@Override
    public String map(String authcid) {
        String authzid = authcid;
        DirContext ctx = null;
        try {
            Log.debug("LdapAuthorizationMapping: Starting LDAP search...");
            String usernameField = manager.getUsernameField();
            //String baseDN = manager.getBaseDN();
            boolean subTreeSearch = manager.isSubTreeSearch();
            ctx = manager.getContext();
            SearchControls constraints = new SearchControls();
            if (subTreeSearch) {
                constraints.setSearchScope
            (SearchControls.SUBTREE_SCOPE);
            }
            // Otherwise, only search a single level.
            else {
                constraints.setSearchScope(SearchControls.ONELEVEL_SCOPE);
            }
            constraints.setReturningAttributes(new String[] { usernameField });

            NamingEnumeration<SearchResult> answer = ctx.search("", princSearchFilter,
                    new String[] {LdapManager.sanitizeSearchFilter(authcid)},
                    constraints);
            Log.debug("LdapAuthorizationMapping: ... search finished");
            if (answer == null || !answer.hasMoreElements()) {
                Log.debug("LdapAuthorizationMapping: Username based on principal '" + authcid + "' not found.");
                return authcid;
            }
            Attributes atrs = answer.next().getAttributes();
            Attribute usernameAttribute = atrs.get(usernameField);
            authzid = (String) usernameAttribute.get();
        }
        catch (Exception e) {
            // Ignore.
        }
        finally {
            try {
                if (ctx != null) {
                    ctx.close();
                }
            }
            catch (Exception ex) {
                Log.debug("An exception occurred while trying to close a LDAP context after trying to map authorization for principal {}.", authcid, ex);
            }
        }
        return authzid;
    }
Provider for authorization mapping using LDAP. If the authenticated identity ('principal', whose password is used)
did not request an authorization identity ('username', to act as), provide one via LDAP. Specify the lookup field in
the system properties. An entry in that file would look like the following:

<ul>
<li>{@code ldap.princField = k5login}</li>
<li>{@code ldap.princSearchFilter = princField={0}}</li>
</ul>
<p>
Each ldap object that represents a user is expected to have exactly one of ldap.usernameField and ldap.princField,
and they are both expected to be unique over the search base.

A search will be performed over all objects where princField = principal, and the usernameField will be returned.

Note that it is expected this search return exactly one object. (There can only be one default) If more than one is
returned, the first entry encountered will be used, and no sorting is performed or requested.

If more control over the search is needed, you can specify the mapSearchFilter used to perform the LDAP query.
This implementation requires that LDAP be configured, obviously.

@author Jay Kline
xmppserver/src/main/java/org/jivesoftware/openfire/ldap/LdapAuthorizationMapping.java