Example usage for javax.naming.directory Attributes get

List of usage examples for javax.naming.directory Attributes get

Introduction

In this page you can find the example usage for javax.naming.directory Attributes get.

Prototype

Attribute get(String attrID);

Source Link

Document

Retrieves the attribute with the given attribute id from the attribute set.

Usage

From source file:dk.magenta.ldap.LDAPMultiBaseUserRegistry.java

public Collection<NodeDescription> getGroups(Date modifiedSince) {
    // Work out whether the user and group trees are disjoint. This may allow us to optimize reverse DN
    // resolution.
    final Set<LdapName> groupDistinguishedNamePrefixes = new LinkedHashSet<>();
    for (String groupSearchBase : this.groupSearchBases) {
        try {//from  w  ww .jav  a  2 s .co  m
            final LdapName groupDistinguishedNamePrefix = fixedLdapName(groupSearchBase.toLowerCase());
            groupDistinguishedNamePrefixes.add(groupDistinguishedNamePrefix);
        } catch (InvalidNameException e) {
            Object[] params = { groupSearchBase.toLowerCase(), e.getLocalizedMessage() };
            throw new AlfrescoRuntimeException("synchronization.err.ldap.search.base.invalid", params, e);
        }
    }
    final Set<LdapName> userDistinguishedNamePrefixes = new LinkedHashSet<>();
    for (String userSearchBase : this.userSearchBases) {
        try {
            final LdapName userDistinguishedNamePrefix = fixedLdapName(userSearchBase.toLowerCase());
            userDistinguishedNamePrefixes.add(userDistinguishedNamePrefix);
        } catch (InvalidNameException e) {
            Object[] params = { userSearchBase.toLowerCase(), e.getLocalizedMessage() };
            throw new AlfrescoRuntimeException("synchronization.err.ldap.search.base.invalid", params, e);
        }
    }

    final Set<LdapName> distinctGroupDNPrefixes = new LinkedHashSet<>(groupDistinguishedNamePrefixes);
    final Set<LdapName> distinctUserDNPrefixes = new LinkedHashSet<>(userDistinguishedNamePrefixes);
    removeCommonPrefixedNamesFromSets(distinctGroupDNPrefixes, distinctUserDNPrefixes);

    // If there exist either distinct user DNs or group DNs, then the
    // sets are disjoint, and we may be able to recognize user or group
    // DNs without secondary lookup
    final boolean disjoint = !distinctUserDNPrefixes.isEmpty() || !distinctGroupDNPrefixes.isEmpty();

    if (LDAPMultiBaseUserRegistry.logger.isDebugEnabled()) {
        if (disjoint) {
            LDAPMultiBaseUserRegistry.logger.debug("Distinct user " + "DN prefixes: " + distinctUserDNPrefixes);
            LDAPMultiBaseUserRegistry.logger
                    .debug("Distinct group " + "DN prefixes: " + distinctGroupDNPrefixes);
        }
    }

    // Choose / generate the query
    String query;
    if (modifiedSince == null) {
        query = this.groupQuery;
    } else {
        query = MessageFormat.format(this.groupDifferentialQuery, this.timestampFormat.format(modifiedSince));
    }

    // Run the query and process the results
    final Map<String, NodeDescription> lookup = new TreeMap<String, NodeDescription>();
    processQuery(new SearchCallback() {
        // We get a whole new context to avoid interference with cookies from paged results
        private DirContext ctx = LDAPMultiBaseUserRegistry.this.ldapInitialContextFactory
                .getDefaultIntialDirContext();

        public void process(SearchResult result) throws NamingException, ParseException {
            Attributes attributes = result.getAttributes();
            Attribute gidAttribute = attributes.get(LDAPMultiBaseUserRegistry.this.groupIdAttributeName);
            if (gidAttribute == null) {
                if (LDAPMultiBaseUserRegistry.this.errorOnMissingGID) {
                    Object[] params = { result.getNameInNamespace(),
                            LDAPMultiBaseUserRegistry.this.groupIdAttributeName };
                    throw new AlfrescoRuntimeException("synchronization.err.ldap.get.group.id.missing", params);
                } else {
                    LDAPMultiBaseUserRegistry.logger.warn("Missing GID on " + attributes);
                    return;
                }
            }
            String groupShortName = gidAttribute.get(0).toString();
            String gid = "GROUP_" + groupShortName;

            NodeDescription group = lookup.get(gid);
            if (group == null) {
                // Apply the mapped properties to the node description
                group = mapToNode(LDAPMultiBaseUserRegistry.this.groupAttributeMapping,
                        LDAPMultiBaseUserRegistry.this.groupAttributeDefaults, result);

                // Make sure the "GROUP_" prefix is applied
                group.getProperties().put(ContentModel.PROP_AUTHORITY_NAME, gid);
                lookup.put(gid, group);
            } else if (LDAPMultiBaseUserRegistry.this.errorOnDuplicateGID) {
                throw new AlfrescoRuntimeException("Duplicate group id found for " + gid);
            } else {
                LDAPMultiBaseUserRegistry.logger
                        .warn("Duplicate gid found for " + gid + " -> merging definitions");
            }

            Set<String> childAssocs = group.getChildAssociations();

            // Get the repeating (and possibly range restricted) member attribute
            Attribute memAttribute = getRangeRestrictedAttribute(attributes,
                    LDAPMultiBaseUserRegistry.this.memberAttributeName);
            int nextStart = LDAPMultiBaseUserRegistry.this.attributeBatchSize;
            if (LDAPMultiBaseUserRegistry.logger.isDebugEnabled()) {
                LDAPMultiBaseUserRegistry.logger
                        .debug("Processing group: " + gid + ", from source: " + group.getSourceId());
            }
            // Loop until we get to the end of the range
            while (memAttribute != null) {
                for (int i = 0; i < memAttribute.size(); i++) {
                    String attribute = (String) memAttribute.get(i);
                    if (attribute != null && attribute.length() > 0) {
                        try {
                            // Attempt to parse the member attribute as a DN. If this fails we have a fallback
                            // in the catch block
                            LdapName distinguishedNameForComparison = fixedLdapName(attribute.toLowerCase());
                            Attribute nameAttribute;

                            // If the user and group search bases are different we may be able to recognize user
                            // and group DNs without a secondary lookup
                            if (disjoint) {
                                LdapName distinguishedName = fixedLdapName(attribute);
                                Attributes nameAttributes = distinguishedName
                                        .getRdn(distinguishedName.size() - 1).toAttributes();

                                // Recognize user DNs
                                if (nameStartsWithNameInSet(distinguishedNameForComparison,
                                        distinctUserDNPrefixes)
                                        && (nameAttribute = nameAttributes.get(
                                                LDAPMultiBaseUserRegistry.this.userIdAttributeName)) != null) {
                                    if (LDAPMultiBaseUserRegistry.logger.isDebugEnabled()) {
                                        LDAPMultiBaseUserRegistry.logger
                                                .debug("User DN recognized: " + nameAttribute.get());
                                    }
                                    childAssocs.add((String) nameAttribute.get());
                                    continue;
                                }

                                // Recognize group DNs
                                if (nameStartsWithNameInSet(distinguishedNameForComparison,
                                        distinctGroupDNPrefixes)
                                        && (nameAttribute = nameAttributes.get(
                                                LDAPMultiBaseUserRegistry.this.groupIdAttributeName)) != null) {
                                    if (LDAPMultiBaseUserRegistry.logger.isDebugEnabled()) {
                                        LDAPMultiBaseUserRegistry.logger.debug(
                                                "Group DN recognized: " + "GROUP_" + nameAttribute.get());
                                    }
                                    childAssocs.add("GROUP_" + nameAttribute.get());
                                    continue;
                                }
                            }

                            // If we can't determine the name and type from the DN alone, try a directory lookup
                            if (nameStartsWithNameInSet(distinguishedNameForComparison,
                                    userDistinguishedNamePrefixes)
                                    || nameStartsWithNameInSet(distinguishedNameForComparison,
                                            groupDistinguishedNamePrefixes)) {
                                try {
                                    Attributes childAttributes = this.ctx.getAttributes(jndiName(attribute),
                                            new String[] { "objectclass",
                                                    LDAPMultiBaseUserRegistry.this.groupIdAttributeName,
                                                    LDAPMultiBaseUserRegistry.this.userIdAttributeName });
                                    Attribute objectClass = childAttributes.get("objectclass");
                                    if (hasAttributeValue(objectClass,
                                            LDAPMultiBaseUserRegistry.this.personType)) {
                                        nameAttribute = childAttributes
                                                .get(LDAPMultiBaseUserRegistry.this.userIdAttributeName);
                                        if (nameAttribute == null) {
                                            if (LDAPMultiBaseUserRegistry.this.errorOnMissingUID) {
                                                throw new AlfrescoRuntimeException(
                                                        "User missing user id attribute DN =" + attribute
                                                                + "  att = "
                                                                + LDAPMultiBaseUserRegistry.this.userIdAttributeName);
                                            } else {
                                                LDAPMultiBaseUserRegistry.logger
                                                        .warn("User missing user id attribute DN =" + attribute
                                                                + "  att = "
                                                                + LDAPMultiBaseUserRegistry.this.userIdAttributeName);
                                                continue;
                                            }
                                        }
                                        if (LDAPMultiBaseUserRegistry.logger.isDebugEnabled()) {
                                            LDAPMultiBaseUserRegistry.logger
                                                    .debug("User DN recognized by directory lookup: "
                                                            + nameAttribute.get());
                                        }
                                        childAssocs.add((String) nameAttribute.get());
                                        continue;
                                    } else if (hasAttributeValue(objectClass,
                                            LDAPMultiBaseUserRegistry.this.groupType)) {
                                        nameAttribute = childAttributes
                                                .get(LDAPMultiBaseUserRegistry.this.groupIdAttributeName);
                                        if (nameAttribute == null) {
                                            if (LDAPMultiBaseUserRegistry.this.errorOnMissingGID) {
                                                Object[] params = { result.getNameInNamespace(),
                                                        LDAPMultiBaseUserRegistry.this.groupIdAttributeName };
                                                throw new AlfrescoRuntimeException(
                                                        "synchronization.err.ldap.get.group.id.missing",
                                                        params);
                                            } else {
                                                LDAPMultiBaseUserRegistry.logger
                                                        .warn("Missing GID on " + childAttributes);
                                                continue;
                                            }
                                        }
                                        if (LDAPMultiBaseUserRegistry.logger.isDebugEnabled()) {
                                            LDAPMultiBaseUserRegistry.logger
                                                    .debug("Group DN recognized by directory lookup: "
                                                            + "GROUP_" + nameAttribute.get());
                                        }
                                        childAssocs.add("GROUP_" + nameAttribute.get());
                                        continue;
                                    }
                                } catch (NamingException e) {
                                    // Unresolvable name
                                    if (LDAPMultiBaseUserRegistry.this.errorOnMissingMembers) {
                                        Object[] params = { groupShortName, attribute,
                                                e.getLocalizedMessage() };
                                        throw new AlfrescoRuntimeException(
                                                "synchronization.err.ldap.group.member.missing.exception",
                                                params, e);
                                    }
                                    LDAPMultiBaseUserRegistry.logger.warn("Failed to resolve member of group '"
                                            + groupShortName + "' with distinguished name: " + attribute, e);
                                    continue;
                                }
                            }
                            if (LDAPMultiBaseUserRegistry.this.errorOnMissingMembers) {
                                Object[] params = { groupShortName, attribute };
                                throw new AlfrescoRuntimeException(
                                        "synchronization.err.ldap.group.member.missing", params);
                            }
                            LDAPMultiBaseUserRegistry.logger.warn("Failed to resolve member of group '"
                                    + groupShortName + "' with distinguished name: " + attribute);
                        } catch (InvalidNameException e) {
                            // The member attribute didn't parse as a DN. So assume we have a group class like
                            // posixGroup (FDS) that directly lists user names
                            if (LDAPMultiBaseUserRegistry.logger.isDebugEnabled()) {
                                LDAPMultiBaseUserRegistry.logger
                                        .debug("Member DN recognized as posixGroup: " + attribute);
                            }
                            childAssocs.add(attribute);
                        }
                    }
                }

                // If we are using attribute matching and we haven't got to the end (indicated by an asterisk),
                // fetch the next batch
                if (nextStart > 0 && !LDAPMultiBaseUserRegistry.PATTERN_RANGE_END
                        .matcher(memAttribute.getID().toLowerCase()).find()) {
                    Attributes childAttributes = this.ctx.getAttributes(jndiName(result.getNameInNamespace()),
                            new String[] { LDAPMultiBaseUserRegistry.this.memberAttributeName + ";range="
                                    + nextStart + '-'
                                    + (nextStart + LDAPMultiBaseUserRegistry.this.attributeBatchSize - 1) });
                    memAttribute = getRangeRestrictedAttribute(childAttributes,
                            LDAPMultiBaseUserRegistry.this.memberAttributeName);
                    nextStart += LDAPMultiBaseUserRegistry.this.attributeBatchSize;
                } else {
                    memAttribute = null;
                }
            }
        }

        public void close() throws NamingException {
            this.ctx.close();
        }
    }, this.groupSearchBases, query, this.groupKeys.getFirst());

    if (LDAPMultiBaseUserRegistry.logger.isDebugEnabled()) {
        LDAPMultiBaseUserRegistry.logger.debug("Found " + lookup.size());
    }

    return lookup.values();
}

From source file:org.josso.gateway.identity.service.store.ldap.LDAPIdentityStore.java

/**
 * Fetch the Ldap user attributes to be used as credentials.
 *
 * @param uid the user id (or lookup value) for whom credentials are required
 * @return the hash map containing user credentials as name/value pairs
 * @throws NamingException LDAP error obtaining user credentials.
 * @throws IOException /*from  w  ww .j a v  a  2 s.  com*/
 */
protected HashMap selectCredentials(String uid, CredentialProvider cp) throws NamingException, IOException {
    HashMap credentialResultSet = new HashMap();

    InitialLdapContext ctx = createLdapInitialContext(false);

    StartTlsResponse tls = null;
    if (getEnableStartTls()) {
        tls = startTls(ctx);
    }

    String schemeName = null;
    if (cp instanceof AuthenticationScheme) {
        schemeName = ((AuthenticationScheme) cp).getName();
    }

    String principalLookupAttrName = this.getPrincipalLookupAttributeID();
    if (principalLookupAttrName == null || principalLookupAttrName.trim().equals("")
            || !"strong-authentication".equals(schemeName)) {
        principalLookupAttrName = this.getPrincipalUidAttributeID();
    }

    String usersCtxDN = this.getUsersCtxDN();

    // BasicAttributes matchAttrs = new BasicAttributes(true);
    // matchAttrs.put(principalUidAttrName, uid);

    String credentialQueryString = getCredentialQueryString();
    HashMap credentialQueryMap = parseQueryString(credentialQueryString);

    Iterator i = credentialQueryMap.keySet().iterator();
    List credentialAttrList = new ArrayList();
    while (i.hasNext()) {
        String o = (String) i.next();
        credentialAttrList.add(o);
    }

    String[] credentialAttr = (String[]) credentialAttrList.toArray(new String[credentialAttrList.size()]);

    try {

        // NamingEnumeration answer = ctx.search(usersCtxDN, matchAttrs, credentialAttr);

        // This gives more control over search behavior :
        NamingEnumeration answer = ctx.search(usersCtxDN, "(&(" + principalLookupAttrName + "=" + uid + "))",
                getSearchControls());

        while (answer.hasMore()) {
            SearchResult sr = (SearchResult) answer.next();
            Attributes attrs = sr.getAttributes();

            String userDN = sr.getNameInNamespace();
            if (logger.isDebugEnabled())
                logger.debug("Processing results for entry '" + userDN + "'");

            for (int j = 0; j < credentialAttr.length; j++) {
                if (attrs.get(credentialAttr[j]) == null)
                    continue;

                //Object credentialObject = attrs.get(credentialAttr[j]).get();
                String credentialName = (String) credentialQueryMap.get(credentialAttr[j]);
                String credentialValue = null;

                Attribute attr = attrs.get(credentialAttr[j]);
                NamingEnumeration attrEnum = attr.getAll();
                while (attrEnum.hasMore()) {
                    Object credentialObject = attrEnum.next();
                    if (credentialObject == null)
                        continue;

                    if (logger.isDebugEnabled())
                        logger.debug("Found user credential '" + credentialName + "' of type '"
                                + credentialObject.getClass().getName() + ""
                                + (credentialObject.getClass().isArray()
                                        ? "[" + Array.getLength(credentialObject) + "]"
                                        : "")
                                + "'");

                    // if the attribute value is an array, cast it to byte[] and then convert to
                    // String using proper encoding
                    if (credentialObject.getClass().isArray()) {

                        try {
                            // Try to create a UTF-8 String, we use java.nio to handle errors in a better way.
                            // If the byte[] cannot be converted to UTF-8, we're using the credentialObject as is.
                            byte[] credentialData = (byte[]) credentialObject;
                            ByteBuffer in = ByteBuffer.allocate(credentialData.length);
                            in.put(credentialData);
                            in.flip();

                            Charset charset = Charset.forName("UTF-8");
                            CharsetDecoder decoder = charset.newDecoder();
                            CharBuffer charBuffer = decoder.decode(in);

                            credentialValue = charBuffer.toString();

                        } catch (CharacterCodingException e) {
                            if (logger.isDebugEnabled())
                                logger.debug("Can't convert credential value to String using UTF-8");
                        }

                    } else if (credentialObject instanceof String) {
                        // The credential value must be a String ...
                        credentialValue = (String) credentialObject;

                    }

                    // Check what do we have ...
                    List credentials = (List) credentialResultSet.get(credentialName);
                    if (credentials == null) {
                        credentials = new ArrayList();
                    }
                    if (credentialValue != null) {
                        // Remove any schema information from the credential value, like the {md5} prefix for passwords.
                        credentialValue = getSchemeFreeValue(credentialValue);
                        credentials.add(credentialValue);
                    } else {
                        // We have a binary credential, leave it as it is ... probably binary value.
                        credentials.add(credentialObject);
                    }
                    credentialResultSet.put(credentialName, credentials);

                    if (logger.isDebugEnabled())
                        logger.debug("Found user credential '" + credentialName + "' with value '"
                                + (credentialValue != null ? credentialValue : credentialObject) + "'");
                }
            }

        }
    } catch (NamingException e) {
        if (logger.isDebugEnabled())
            logger.debug("Failed to locate user", e);
    } finally {
        // Close the context to release the connection
        if (tls != null) {
            tls.close();
        }
        ctx.close();
    }

    return credentialResultSet;
}

From source file:org.cggh.repo.security.sync.ldap.LDAPUserRegistry.java

public Collection<NodeDescription> getGroups(Date modifiedSince) {
    // Work out whether the user and group trees are disjoint. This may allow us to optimize reverse DN
    // resolution.
    final LdapName groupDistinguishedNamePrefix;
    try {//from  w w  w  .j  a  v a  2 s .  c o  m
        groupDistinguishedNamePrefix = fixedLdapName(this.groupSearchBase.toLowerCase());
    } catch (InvalidNameException e) {
        Object[] params = { this.groupSearchBase.toLowerCase(), e.getLocalizedMessage() };
        throw new AlfrescoRuntimeException("synchronization.err.ldap.search.base.invalid", params, e);
    }
    final LdapName userDistinguishedNamePrefix;
    try {
        userDistinguishedNamePrefix = fixedLdapName(this.userSearchBase.toLowerCase());
    } catch (InvalidNameException e) {
        Object[] params = { this.userSearchBase.toLowerCase(), e.getLocalizedMessage() };
        throw new AlfrescoRuntimeException("synchronization.err.ldap.search.base.invalid", params, e);
    }

    final boolean disjoint = !groupDistinguishedNamePrefix.startsWith(userDistinguishedNamePrefix)
            && !userDistinguishedNamePrefix.startsWith(groupDistinguishedNamePrefix);

    // Choose / generate the query
    String query;
    if (modifiedSince == null) {
        query = this.groupQuery;
    } else {
        query = MessageFormat.format(this.groupDifferentialQuery, this.timestampFormat.format(modifiedSince));
    }

    // Run the query and process the results
    final Map<String, NodeDescription> lookup = new TreeMap<String, NodeDescription>();
    processQuery(new AbstractSearchCallback() {
        // We get a whole new context to avoid interference with cookies from paged results
        private DirContext ctx = LDAPUserRegistry.this.ldapInitialContextFactory.getDefaultIntialDirContext();

        protected void doProcess(SearchResult result) throws NamingException, ParseException {
            Attributes attributes = result.getAttributes();
            Attribute gidAttribute = attributes.get(LDAPUserRegistry.this.groupIdAttributeName);
            if (gidAttribute == null) {
                if (LDAPUserRegistry.this.errorOnMissingGID) {
                    Object[] params = { result.getNameInNamespace(),
                            LDAPUserRegistry.this.groupIdAttributeName };
                    throw new AlfrescoRuntimeException("synchronization.err.ldap.get.group.id.missing", params);
                } else {
                    LDAPUserRegistry.logger.warn(
                            "Missing GID2 on " + result.getNameInNamespace() + " attributes:" + attributes);
                    return;
                }
            }
            String groupShortName = gidAttribute.get(0).toString();
            String gid = "GROUP_" + groupShortName;

            NodeDescription group = lookup.get(gid);
            if (group == null) {
                // Apply the mapped properties to the node description
                group = mapToNode(LDAPUserRegistry.this.groupAttributeMapping,
                        LDAPUserRegistry.this.groupAttributeDefaults, result);

                // Make sure the "GROUP_" prefix is applied
                group.getProperties().put(ContentModel.PROP_AUTHORITY_NAME, gid);
                lookup.put(gid, group);
            } else if (LDAPUserRegistry.this.errorOnDuplicateGID) {
                throw new AlfrescoRuntimeException("Duplicate group id found for " + gid);
            } else {
                LDAPUserRegistry.logger.warn("Duplicate gid found for " + gid + " -> merging definitions");
            }

            Set<String> childAssocs = group.getChildAssociations();

            // Get the repeating (and possibly range restricted) member attribute
            Attribute memAttribute = getRangeRestrictedAttribute(attributes,
                    LDAPUserRegistry.this.memberAttributeName);
            int nextStart = LDAPUserRegistry.this.attributeBatchSize;
            if (LDAPUserRegistry.logger.isDebugEnabled()) {
                LDAPUserRegistry.logger
                        .debug("Processing group: " + gid + ", from source: " + group.getSourceId());
            }
            // Loop until we get to the end of the range
            while (memAttribute != null) {
                for (int i = 0; i < memAttribute.size(); i++) {
                    String attribute = (String) memAttribute.get(i);
                    if (attribute != null && attribute.length() > 0) {
                        try {
                            // Attempt to parse the member attribute as a DN. If this fails we have a fallback
                            // in the catch block
                            LdapName distinguishedNameForComparison = fixedLdapName(attribute.toLowerCase());
                            Attribute nameAttribute;

                            // If the user and group search bases are different we may be able to recognize user
                            // and group DNs without a secondary lookup
                            if (disjoint) {
                                LdapName distinguishedName = fixedLdapName(attribute);
                                Attributes nameAttributes = distinguishedName
                                        .getRdn(distinguishedName.size() - 1).toAttributes();

                                // Recognize user DNs
                                if (distinguishedNameForComparison.startsWith(userDistinguishedNamePrefix)
                                        && (nameAttribute = nameAttributes
                                                .get(LDAPUserRegistry.this.userIdAttributeName)) != null) {
                                    if (LDAPUserRegistry.logger.isDebugEnabled()) {
                                        LDAPUserRegistry.logger
                                                .debug("User DN recognized: " + nameAttribute.get());
                                    }
                                    childAssocs.add((String) nameAttribute.get());
                                    continue;
                                }

                                // Recognize group DNs
                                if (distinguishedNameForComparison.startsWith(groupDistinguishedNamePrefix)
                                        && (nameAttribute = nameAttributes
                                                .get(LDAPUserRegistry.this.groupIdAttributeName)) != null) {
                                    if (LDAPUserRegistry.logger.isDebugEnabled()) {
                                        LDAPUserRegistry.logger.debug(
                                                "Group DN recognized: " + "GROUP_" + nameAttribute.get());
                                    }
                                    childAssocs.add("GROUP_" + nameAttribute.get());
                                    continue;
                                }
                            }

                            // If we can't determine the name and type from the DN alone, try a directory lookup
                            if (distinguishedNameForComparison.startsWith(userDistinguishedNamePrefix)
                                    || distinguishedNameForComparison
                                            .startsWith(groupDistinguishedNamePrefix)) {
                                try {
                                    Attributes childAttributes = this.ctx.getAttributes(jndiName(attribute),
                                            new String[] { "objectclass",
                                                    LDAPUserRegistry.this.groupIdAttributeName,
                                                    LDAPUserRegistry.this.userIdAttributeName });
                                    Attribute objectClass = childAttributes.get("objectclass");
                                    if (hasAttributeValue(objectClass, LDAPUserRegistry.this.personType)) {
                                        nameAttribute = childAttributes
                                                .get(LDAPUserRegistry.this.userIdAttributeName);
                                        if (nameAttribute == null) {
                                            if (LDAPUserRegistry.this.errorOnMissingUID) {
                                                throw new AlfrescoRuntimeException(
                                                        "User missing user id attribute DN =" + attribute
                                                                + "  att = "
                                                                + LDAPUserRegistry.this.userIdAttributeName);
                                            } else {
                                                LDAPUserRegistry.logger
                                                        .warn("User missing user id attribute DN =" + attribute
                                                                + "  att = "
                                                                + LDAPUserRegistry.this.userIdAttributeName);
                                                continue;
                                            }
                                        }
                                        if (LDAPUserRegistry.logger.isDebugEnabled()) {
                                            LDAPUserRegistry.logger
                                                    .debug("User DN recognized by directory lookup: "
                                                            + nameAttribute.get());
                                        }
                                        childAssocs.add((String) nameAttribute.get());
                                        continue;
                                    } else if (hasAttributeValue(objectClass,
                                            LDAPUserRegistry.this.groupType)) {
                                        nameAttribute = childAttributes
                                                .get(LDAPUserRegistry.this.groupIdAttributeName);
                                        if (nameAttribute == null) {
                                            if (LDAPUserRegistry.this.errorOnMissingGID) {
                                                Object[] params = { result.getNameInNamespace(),
                                                        LDAPUserRegistry.this.groupIdAttributeName };
                                                throw new AlfrescoRuntimeException(
                                                        "synchronization.err.ldap.get.group.id.missing",
                                                        params);
                                            } else {
                                                LDAPUserRegistry.logger.warn(
                                                        "Missing GID3 on " + distinguishedNameForComparison
                                                                + " attributes:" + childAttributes);
                                                continue;
                                            }
                                        }
                                        if (LDAPUserRegistry.logger.isDebugEnabled()) {
                                            LDAPUserRegistry.logger
                                                    .debug("Group DN recognized by directory lookup: "
                                                            + "GROUP_" + nameAttribute.get());
                                        }
                                        childAssocs.add("GROUP_" + nameAttribute.get());
                                        continue;
                                    }
                                } catch (NamingException e) {
                                    // Unresolvable name
                                    if (LDAPUserRegistry.this.errorOnMissingMembers) {
                                        Object[] params = { groupShortName, attribute,
                                                e.getLocalizedMessage() };
                                        throw new AlfrescoRuntimeException(
                                                "synchronization.err.ldap.group.member.missing.exception",
                                                params, e);
                                    }
                                    LDAPUserRegistry.logger.warn("Failed to resolve member of group '"
                                            + groupShortName + "' with distinguished name: " + attribute, e);
                                    continue;
                                }
                            }
                            if (LDAPUserRegistry.this.errorOnMissingMembers) {
                                Object[] params = { groupShortName, attribute };
                                throw new AlfrescoRuntimeException(
                                        "synchronization.err.ldap.group.member.missing", params);
                            }
                            LDAPUserRegistry.logger.warn("Failed to resolve member of group '" + groupShortName
                                    + "' with distinguished name: " + attribute);
                        } catch (InvalidNameException e) {
                            // The member attribute didn't parse as a DN. So assume we have a group class like
                            // posixGroup (FDS) that directly lists user names
                            if (LDAPUserRegistry.logger.isDebugEnabled()) {
                                LDAPUserRegistry.logger
                                        .debug("Member DN recognized as posixGroup: " + attribute);
                            }
                            childAssocs.add(attribute);
                        }
                    }
                }

                // If we are using attribute matching and we haven't got to the end (indicated by an asterisk),
                // fetch the next batch
                if (nextStart > 0 && !LDAPUserRegistry.PATTERN_RANGE_END
                        .matcher(memAttribute.getID().toLowerCase()).find()) {
                    Attributes childAttributes = this.ctx.getAttributes(jndiName(result.getNameInNamespace()),
                            new String[] { LDAPUserRegistry.this.memberAttributeName + ";range=" + nextStart
                                    + '-' + (nextStart + LDAPUserRegistry.this.attributeBatchSize - 1) });
                    memAttribute = getRangeRestrictedAttribute(childAttributes,
                            LDAPUserRegistry.this.memberAttributeName);
                    nextStart += LDAPUserRegistry.this.attributeBatchSize;
                } else {
                    memAttribute = null;
                }
            }
        }

        public void close() throws NamingException {
            this.ctx.close();
        }
    }, this.groupSearchBase, query, this.groupKeys.getFirst());

    if (LDAPUserRegistry.logger.isDebugEnabled()) {
        LDAPUserRegistry.logger.debug("Found " + lookup.size());
    }

    return lookup.values();
}

From source file:org.alfresco.repo.security.sync.ldap.LDAPUserRegistry.java

public Collection<NodeDescription> getGroups(Date modifiedSince) {
    // Work out whether the user and group trees are disjoint. This may allow us to optimize reverse DN
    // resolution.
    final LdapName groupDistinguishedNamePrefix;
    try {//from  www .  j a v a  2s. c  o m
        groupDistinguishedNamePrefix = fixedLdapName(this.groupSearchBase.toLowerCase());
    } catch (InvalidNameException e) {
        Object[] params = { this.groupSearchBase.toLowerCase(), e.getLocalizedMessage() };
        throw new AlfrescoRuntimeException("synchronization.err.ldap.search.base.invalid", params, e);
    }
    final LdapName userDistinguishedNamePrefix;
    try {
        userDistinguishedNamePrefix = fixedLdapName(this.userSearchBase.toLowerCase());
    } catch (InvalidNameException e) {
        Object[] params = { this.userSearchBase.toLowerCase(), e.getLocalizedMessage() };
        throw new AlfrescoRuntimeException("synchronization.err.ldap.search.base.invalid", params, e);
    }

    final boolean disjoint = !groupDistinguishedNamePrefix.startsWith(userDistinguishedNamePrefix)
            && !userDistinguishedNamePrefix.startsWith(groupDistinguishedNamePrefix);

    // Choose / generate the query
    String query;
    if (modifiedSince == null) {
        query = this.groupQuery;
    } else {
        query = MessageFormat.format(this.groupDifferentialQuery, this.timestampFormat.format(modifiedSince));
    }

    // Run the query and process the results
    final Map<String, NodeDescription> lookup = new TreeMap<String, NodeDescription>();
    processQuery(new AbstractSearchCallback() {
        // We get a whole new context to avoid interference with cookies from paged results
        private DirContext ctx = LDAPUserRegistry.this.ldapInitialContextFactory.getDefaultIntialDirContext();

        protected void doProcess(SearchResult result) throws NamingException, ParseException {
            Attributes attributes = result.getAttributes();
            Attribute gidAttribute = attributes.get(LDAPUserRegistry.this.groupIdAttributeName);
            if (gidAttribute == null) {
                if (LDAPUserRegistry.this.errorOnMissingGID) {
                    Object[] params = { result.getNameInNamespace(),
                            LDAPUserRegistry.this.groupIdAttributeName };
                    throw new AlfrescoRuntimeException("synchronization.err.ldap.get.group.id.missing", params);
                } else {
                    LDAPUserRegistry.logger.warn("Missing GID on " + attributes);
                    return;
                }
            }
            String groupShortName = gidAttribute.get(0).toString();
            String gid = "GROUP_" + groupShortName;

            NodeDescription group = lookup.get(gid);
            if (group == null) {
                // Apply the mapped properties to the node description
                group = mapToNode(LDAPUserRegistry.this.groupAttributeMapping,
                        LDAPUserRegistry.this.groupAttributeDefaults, result);

                // Make sure the "GROUP_" prefix is applied
                group.getProperties().put(ContentModel.PROP_AUTHORITY_NAME, gid);
                lookup.put(gid, group);
            } else if (LDAPUserRegistry.this.errorOnDuplicateGID) {
                throw new AlfrescoRuntimeException("Duplicate group id found for " + gid);
            } else {
                LDAPUserRegistry.logger.warn("Duplicate gid found for " + gid + " -> merging definitions");
            }

            Set<String> childAssocs = group.getChildAssociations();

            // Get the repeating (and possibly range restricted) member attribute
            Attribute memAttribute = getRangeRestrictedAttribute(attributes,
                    LDAPUserRegistry.this.memberAttributeName);
            int nextStart = LDAPUserRegistry.this.attributeBatchSize;
            if (LDAPUserRegistry.logger.isDebugEnabled()) {
                LDAPUserRegistry.logger
                        .debug("Processing group: " + gid + ", from source: " + group.getSourceId());
            }
            // Loop until we get to the end of the range
            while (memAttribute != null) {
                for (int i = 0; i < memAttribute.size(); i++) {
                    String attribute = (String) memAttribute.get(i);
                    if (attribute != null && attribute.length() > 0) {
                        try {
                            // Attempt to parse the member attribute as a DN. If this fails we have a fallback
                            // in the catch block
                            LdapName distinguishedNameForComparison = fixedLdapName(attribute.toLowerCase());
                            Attribute nameAttribute;

                            // If the user and group search bases are different we may be able to recognize user
                            // and group DNs without a secondary lookup
                            if (disjoint) {
                                LdapName distinguishedName = fixedLdapName(attribute);
                                Attributes nameAttributes = distinguishedName
                                        .getRdn(distinguishedName.size() - 1).toAttributes();

                                // Recognize user DNs
                                if (distinguishedNameForComparison.startsWith(userDistinguishedNamePrefix)
                                        && (nameAttribute = nameAttributes
                                                .get(LDAPUserRegistry.this.userIdAttributeName)) != null) {
                                    if (LDAPUserRegistry.logger.isDebugEnabled()) {
                                        LDAPUserRegistry.logger
                                                .debug("User DN recognized: " + nameAttribute.get());
                                    }
                                    childAssocs.add((String) nameAttribute.get());
                                    continue;
                                }

                                // Recognize group DNs
                                if (distinguishedNameForComparison.startsWith(groupDistinguishedNamePrefix)
                                        && (nameAttribute = nameAttributes
                                                .get(LDAPUserRegistry.this.groupIdAttributeName)) != null) {
                                    if (LDAPUserRegistry.logger.isDebugEnabled()) {
                                        LDAPUserRegistry.logger.debug(
                                                "Group DN recognized: " + "GROUP_" + nameAttribute.get());
                                    }
                                    childAssocs.add("GROUP_" + nameAttribute.get());
                                    continue;
                                }
                            }

                            // If we can't determine the name and type from the DN alone, try a directory lookup
                            if (distinguishedNameForComparison.startsWith(userDistinguishedNamePrefix)
                                    || distinguishedNameForComparison
                                            .startsWith(groupDistinguishedNamePrefix)) {
                                try {
                                    Attributes childAttributes = this.ctx.getAttributes(jndiName(attribute),
                                            new String[] { "objectclass",
                                                    LDAPUserRegistry.this.groupIdAttributeName,
                                                    LDAPUserRegistry.this.userIdAttributeName });
                                    Attribute objectClass = childAttributes.get("objectclass");
                                    if (hasAttributeValue(objectClass, LDAPUserRegistry.this.personType)) {
                                        nameAttribute = childAttributes
                                                .get(LDAPUserRegistry.this.userIdAttributeName);
                                        if (nameAttribute == null) {
                                            if (LDAPUserRegistry.this.errorOnMissingUID) {
                                                throw new AlfrescoRuntimeException(
                                                        "User missing user id attribute DN =" + attribute
                                                                + "  att = "
                                                                + LDAPUserRegistry.this.userIdAttributeName);
                                            } else {
                                                LDAPUserRegistry.logger
                                                        .warn("User missing user id attribute DN =" + attribute
                                                                + "  att = "
                                                                + LDAPUserRegistry.this.userIdAttributeName);
                                                continue;
                                            }
                                        }
                                        if (LDAPUserRegistry.logger.isDebugEnabled()) {
                                            LDAPUserRegistry.logger
                                                    .debug("User DN recognized by directory lookup: "
                                                            + nameAttribute.get());
                                        }
                                        childAssocs.add((String) nameAttribute.get());
                                        continue;
                                    } else if (hasAttributeValue(objectClass,
                                            LDAPUserRegistry.this.groupType)) {
                                        nameAttribute = childAttributes
                                                .get(LDAPUserRegistry.this.groupIdAttributeName);
                                        if (nameAttribute == null) {
                                            if (LDAPUserRegistry.this.errorOnMissingGID) {
                                                Object[] params = { result.getNameInNamespace(),
                                                        LDAPUserRegistry.this.groupIdAttributeName };
                                                throw new AlfrescoRuntimeException(
                                                        "synchronization.err.ldap.get.group.id.missing",
                                                        params);
                                            } else {
                                                LDAPUserRegistry.logger
                                                        .warn("Missing GID on " + childAttributes);
                                                continue;
                                            }
                                        }
                                        if (LDAPUserRegistry.logger.isDebugEnabled()) {
                                            LDAPUserRegistry.logger
                                                    .debug("Group DN recognized by directory lookup: "
                                                            + "GROUP_" + nameAttribute.get());
                                        }
                                        childAssocs.add("GROUP_" + nameAttribute.get());
                                        continue;
                                    }
                                } catch (NamingException e) {
                                    // Unresolvable name
                                    if (LDAPUserRegistry.this.errorOnMissingMembers) {
                                        Object[] params = { groupShortName, attribute,
                                                e.getLocalizedMessage() };
                                        throw new AlfrescoRuntimeException(
                                                "synchronization.err.ldap.group.member.missing.exception",
                                                params, e);
                                    }
                                    LDAPUserRegistry.logger.warn("Failed to resolve member of group '"
                                            + groupShortName + "' with distinguished name: " + attribute, e);
                                    continue;
                                }
                            }
                            if (LDAPUserRegistry.this.errorOnMissingMembers) {
                                Object[] params = { groupShortName, attribute };
                                throw new AlfrescoRuntimeException(
                                        "synchronization.err.ldap.group.member.missing", params);
                            }
                            LDAPUserRegistry.logger.warn("Failed to resolve member of group '" + groupShortName
                                    + "' with distinguished name: " + attribute);
                        } catch (InvalidNameException e) {
                            // The member attribute didn't parse as a DN. So assume we have a group class like
                            // posixGroup (FDS) that directly lists user names
                            if (LDAPUserRegistry.logger.isDebugEnabled()) {
                                LDAPUserRegistry.logger
                                        .debug("Member DN recognized as posixGroup: " + attribute);
                            }
                            childAssocs.add(attribute);
                        }
                    }
                }

                // If we are using attribute matching and we haven't got to the end (indicated by an asterisk),
                // fetch the next batch
                if (nextStart > 0 && !LDAPUserRegistry.PATTERN_RANGE_END
                        .matcher(memAttribute.getID().toLowerCase()).find()) {
                    Attributes childAttributes = this.ctx.getAttributes(jndiName(result.getNameInNamespace()),
                            new String[] { LDAPUserRegistry.this.memberAttributeName + ";range=" + nextStart
                                    + '-' + (nextStart + LDAPUserRegistry.this.attributeBatchSize - 1) });
                    memAttribute = getRangeRestrictedAttribute(childAttributes,
                            LDAPUserRegistry.this.memberAttributeName);
                    nextStart += LDAPUserRegistry.this.attributeBatchSize;
                } else {
                    memAttribute = null;
                }
            }
        }

        public void close() throws NamingException {
            this.ctx.close();
        }
    }, this.groupSearchBase, query, this.groupKeys.getFirst());

    if (LDAPUserRegistry.logger.isDebugEnabled()) {
        LDAPUserRegistry.logger.debug("Found " + lookup.size());
    }

    return lookup.values();
}

From source file:org.nuxeo.ecm.directory.ldap.LDAPReference.java

protected String getIdForDn(LDAPSession session, String dn) {
    // the entry id is not based on the rdn, we thus need to
    // fetch the LDAP entry to grab it
    String[] attributeIdsToCollect = { session.idAttribute };
    Attributes entry;
    try {//  w  ww. j a  va  2  s  .  c  om

        if (log.isDebugEnabled()) {
            log.debug(String.format(
                    "LDAPReference.getIdForDn(session, %s): LDAP get dn='%s'"
                            + " attribute ids to collect='%s' [%s]",
                    dn, dn, StringUtils.join(attributeIdsToCollect, ", "), this));
        }

        Name name = new CompositeName().add(dn);
        entry = session.dirContext.getAttributes(name, attributeIdsToCollect);
    } catch (NamingException e) {
        return null;
    }
    // NXP-2461: check that id field is filled
    Attribute attr = entry.get(session.idAttribute);
    if (attr != null) {
        try {
            return attr.get().toString();
        } catch (NamingException e) {
        }
    }
    return null;
}

From source file:org.nuxeo.ecm.directory.ldap.LDAPSession.java

@Override
@SuppressWarnings("unchecked")
public void updateEntry(DocumentModel docModel) {
    checkPermission(SecurityConstants.WRITE);
    List<String> updateList = new ArrayList<String>();
    List<String> referenceFieldList = new LinkedList<String>();

    try {//from  w w w. j  a  va 2s  .  co m
        for (String fieldName : schemaFieldMap.keySet()) {
            if (!docModel.getPropertyObject(schemaName, fieldName).isDirty()) {
                continue;
            }
            if (getDirectory().isReference(fieldName)) {
                referenceFieldList.add(fieldName);
            } else {
                updateList.add(fieldName);
            }
        }

        if (!isReadOnlyEntry(docModel) && !updateList.isEmpty()) {
            Attributes attrs = new BasicAttributes();
            SearchResult ldapEntry = getLdapEntry(docModel.getId());
            if (ldapEntry == null) {
                throw new DirectoryException(docModel.getId() + " not found");
            }
            Attributes oldattrs = ldapEntry.getAttributes();
            String dn = ldapEntry.getNameInNamespace();
            Attributes attrsToDel = new BasicAttributes();
            for (String f : updateList) {
                Object value = docModel.getProperty(schemaName, f);
                String backendField = getDirectory().getFieldMapper().getBackendField(f);
                if (LDAPDirectory.DN_SPECIAL_ATTRIBUTE_KEY.equals(backendField)) {
                    // skip special LDAP DN field that is readonly
                    log.warn(String.format("field %s is mapped to read only DN field: ignored", f));
                    continue;
                }
                if (value == null || value.equals("")) {
                    Attribute objectClasses = oldattrs.get("objectClass");
                    Attribute attr;
                    if (getMandatoryAttributes(objectClasses).contains(backendField)) {
                        attr = new BasicAttribute(backendField);
                        // XXX: this might fail if the mandatory attribute
                        // is typed integer for instance
                        attr.add(" ");
                        attrs.put(attr);
                    } else if (oldattrs.get(backendField) != null) {
                        attr = new BasicAttribute(backendField);
                        attr.add(oldattrs.get(backendField).get());
                        attrsToDel.put(attr);
                    }
                } else if (f.equals(getPasswordField())) {
                    // The password has been updated, it has to be encrypted
                    Attribute attr = new BasicAttribute(backendField);
                    attr.add(PasswordHelper.hashPassword((String) value, passwordHashAlgorithm));
                    attrs.put(attr);
                } else {
                    attrs.put(getAttributeValue(f, value));
                }
            }

            if (log.isDebugEnabled()) {
                log.debug(String.format("LDAPSession.updateEntry(%s): LDAP modifyAttributes dn='%s' "
                        + "mod_op='REMOVE_ATTRIBUTE' attr='%s' [%s]", docModel, dn, attrsToDel, this));
            }
            dirContext.modifyAttributes(dn, DirContext.REMOVE_ATTRIBUTE, attrsToDel);

            if (log.isDebugEnabled()) {
                log.debug(String.format("LDAPSession.updateEntry(%s): LDAP modifyAttributes dn='%s' "
                        + "mod_op='REPLACE_ATTRIBUTE' attr='%s' [%s]", docModel, dn, attrs, this));
            }
            dirContext.modifyAttributes(dn, DirContext.REPLACE_ATTRIBUTE, attrs);
        }

        // update reference fields
        for (String referenceFieldName : referenceFieldList) {
            List<Reference> references = directory.getReferences(referenceFieldName);
            if (references.size() > 1) {
                // not supported
            } else {
                Reference reference = references.get(0);
                List<String> targetIds = (List<String>) docModel.getProperty(schemaName, referenceFieldName);
                reference.setTargetIdsForSource(docModel.getId(), targetIds);
            }
        }
    } catch (NamingException e) {
        handleException(e, "updateEntry failed:");
    }
    getDirectory().invalidateCaches();
}

From source file:org.nuxeo.ecm.directory.ldap.LDAPReference.java

/**
 * Optimized method to spare a LDAP request when the caller is a LDAPSession object that has already fetched the
 * LDAP Attribute instances./* w  w w.  j a v a 2s.  co m*/
 * <p>
 * This method should return the same results as the sister method: org.nuxeo
 * .ecm.directory.Reference#getTargetIdsForSource(java.lang.String)
 *
 * @return target reference ids
 * @throws DirectoryException
 */
public List<String> getLdapTargetIds(Attributes attributes) throws DirectoryException {

    Set<String> targetIds = new TreeSet<>();

    LDAPDirectory ldapTargetDirectory = (LDAPDirectory) getTargetDirectory();
    LDAPDirectoryDescriptor targetDirconfig = getTargetDirectoryDescriptor();
    String emptyRefMarker = ldapTargetDirectory.getDescriptor().getEmptyRefMarker();
    try (LDAPSession targetSession = (LDAPSession) ldapTargetDirectory.getSession()) {
        String baseDn = pseudoNormalizeDn(targetDirconfig.getSearchBaseDn());

        // step #1: fetch ids referenced by static attributes
        String staticAttributeId = getStaticAttributeId();
        Attribute staticAttribute = null;
        if (staticAttributeId != null) {
            staticAttribute = attributes.get(staticAttributeId);
        }

        if (staticAttribute != null && !staticAttributeIdIsDn) {
            NamingEnumeration<?> staticContent = staticAttribute.getAll();
            try {
                while (staticContent.hasMore()) {
                    String value = staticContent.next().toString();
                    if (!emptyRefMarker.equals(value)) {
                        targetIds.add(value);
                    }
                }
            } finally {
                staticContent.close();
            }
        }

        if (staticAttribute != null && staticAttributeIdIsDn) {
            NamingEnumeration<?> targetDns = staticAttribute.getAll();
            try {
                while (targetDns.hasMore()) {
                    String targetDn = targetDns.next().toString();

                    if (!pseudoNormalizeDn(targetDn).endsWith(baseDn)) {
                        // optim: avoid network connections when obvious
                        if (log.isTraceEnabled()) {
                            log.trace(String.format("ignoring: dn='%s' (does not match '%s') for '%s'",
                                    targetDn, baseDn, this));
                        }
                        continue;
                    }
                    // find the id of the referenced entry
                    String id = null;

                    if (targetSession.rdnMatchesIdField()) {
                        // optim: do not fetch the entry to get its true id
                        // but
                        // guess it by reading the targetDn
                        LdapName name = new LdapName(targetDn);
                        String rdn = name.get(name.size() - 1);
                        int pos = rdn.indexOf("=");
                        id = rdn.substring(pos + 1);
                    } else {
                        id = getIdForDn(targetSession, targetDn);
                        if (id == null) {
                            log.warn(String.format(
                                    "ignoring target '%s' (missing attribute '%s') while resolving reference '%s'",
                                    targetDn, targetSession.idAttribute, this));
                            continue;
                        }
                    }
                    if (forceDnConsistencyCheck) {
                        // check that the referenced entry is actually part
                        // of
                        // the target directory (takes care of the filters
                        // and
                        // the scope)
                        // this check can be very expensive on large groups
                        // and thus not enabled by default
                        if (!targetSession.hasEntry(id)) {
                            if (log.isTraceEnabled()) {
                                log.trace(String.format(
                                        "ignoring target '%s' when resolving '%s' (not part of target"
                                                + " directory by forced DN consistency check)",
                                        targetDn, this));
                            }
                            continue;
                        }
                    }
                    // NXP-2461: check that id field is filled
                    if (id != null) {
                        targetIds.add(id);
                    }
                }
            } finally {
                targetDns.close();
            }
        }
        // step #2: fetched dynamically referenced ids
        String dynamicAttributeId = this.dynamicAttributeId;
        Attribute dynamicAttribute = null;
        if (dynamicAttributeId != null) {
            dynamicAttribute = attributes.get(dynamicAttributeId);
        }
        if (dynamicAttribute != null) {
            NamingEnumeration<?> rawldapUrls = dynamicAttribute.getAll();
            try {
                while (rawldapUrls.hasMore()) {
                    LdapURL ldapUrl = new LdapURL(rawldapUrls.next().toString());
                    String linkDn = pseudoNormalizeDn(ldapUrl.getDN());
                    String directoryDn = pseudoNormalizeDn(targetDirconfig.getSearchBaseDn());
                    int scope = SearchControls.ONELEVEL_SCOPE;
                    String scopePart = ldapUrl.getScope();
                    if (scopePart != null && scopePart.toLowerCase().startsWith("sub")) {
                        scope = SearchControls.SUBTREE_SCOPE;
                    }
                    if (!linkDn.endsWith(directoryDn) && !directoryDn.endsWith(linkDn)) {
                        // optim #1: if the dns do not match, abort
                        continue;
                    } else if (directoryDn.endsWith(linkDn) && linkDn.length() < directoryDn.length()
                            && scope == SearchControls.ONELEVEL_SCOPE) {
                        // optim #2: the link dn is pointing to elements
                        // that at
                        // upperlevel than directory elements
                        continue;
                    } else {

                        // Search for references elements
                        targetIds.addAll(getReferencedElements(attributes, directoryDn, linkDn,
                                ldapUrl.getFilter(), scope));

                    }
                }
            } finally {
                rawldapUrls.close();
            }
        }

        if (dynamicReferences != null && dynamicReferences.length > 0) {

            // Only the first Dynamic Reference is used
            LDAPDynamicReferenceDescriptor dynAtt = dynamicReferences[0];

            Attribute baseDnsAttribute = attributes.get(dynAtt.baseDN);
            Attribute filterAttribute = attributes.get(dynAtt.filter);

            if (baseDnsAttribute != null && filterAttribute != null) {

                NamingEnumeration<?> baseDns = null;
                NamingEnumeration<?> filters = null;

                try {
                    // Get the BaseDN value from the descriptor
                    baseDns = baseDnsAttribute.getAll();
                    String linkDnValue = baseDns.next().toString();
                    baseDns.close();
                    linkDnValue = pseudoNormalizeDn(linkDnValue);

                    // Get the filter value from the descriptor
                    filters = filterAttribute.getAll();
                    String filterValue = filters.next().toString();
                    filters.close();

                    // Get the scope value from the descriptor
                    int scope = "subtree".equalsIgnoreCase(dynAtt.type) ? SearchControls.SUBTREE_SCOPE
                            : SearchControls.ONELEVEL_SCOPE;

                    String directoryDn = pseudoNormalizeDn(targetDirconfig.getSearchBaseDn());

                    // if the dns match, and if the link dn is pointing to
                    // elements that at upperlevel than directory elements
                    if ((linkDnValue.endsWith(directoryDn) || directoryDn.endsWith(linkDnValue))
                            && !(directoryDn.endsWith(linkDnValue)
                                    && linkDnValue.length() < directoryDn.length()
                                    && scope == SearchControls.ONELEVEL_SCOPE)) {

                        // Correct the filter expression
                        filterValue = FilterExpressionCorrector.correctFilter(filterValue,
                                FilterJobs.CORRECT_NOT);

                        // Search for references elements
                        targetIds.addAll(getReferencedElements(attributes, directoryDn, linkDnValue,
                                filterValue, scope));

                    }
                } finally {
                    if (baseDns != null) {
                        baseDns.close();
                    }

                    if (filters != null) {
                        filters.close();
                    }
                }

            }

        }
        // return merged attributes
        return new ArrayList<String>(targetIds);
    } catch (NamingException e) {
        throw new DirectoryException("error computing LDAP references", e);
    }
}

From source file:org.wso2.carbon.user.core.ldap.ReadWriteLDAPUserStoreManager.java

@Override
public void doUpdateCredentialByAdmin(String userName, Object newCredential) throws UserStoreException {

    DirContext dirContext = this.connectionSource.getContext();
    DirContext subDirContext = null;
    // first search the existing user entry.
    String searchBase = realmConfig.getUserStoreProperty(LDAPConstants.USER_SEARCH_BASE);
    String searchFilter = realmConfig.getUserStoreProperty(LDAPConstants.USER_NAME_SEARCH_FILTER);
    searchFilter = searchFilter.replace("?", escapeSpecialCharactersForFilter(userName));

    SearchControls searchControls = new SearchControls();
    searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
    searchControls.setReturningAttributes(new String[] { "userPassword" });

    NamingEnumeration<SearchResult> namingEnumeration = null;
    NamingEnumeration passwords = null;

    try {/*from  w  w  w  . java  2 s  .c  o  m*/
        namingEnumeration = dirContext.search(escapeDNForSearch(searchBase), searchFilter, searchControls);
        // here we assume only one user
        // TODO: what to do if there are more than one user
        // there can be only only on user

        SearchResult searchResult = null;
        while (namingEnumeration.hasMore()) {
            searchResult = namingEnumeration.next();
            String passwordHashMethod = realmConfig.getUserStoreProperty(PASSWORD_HASH_METHOD);
            if (!UserCoreConstants.RealmConfig.PASSWORD_HASH_METHOD_PLAIN_TEXT
                    .equalsIgnoreCase(passwordHashMethod)) {
                Attributes attributes = searchResult.getAttributes();
                Attribute userPassword = attributes.get("userPassword");
                // When admin changes other user passwords he do not have to
                // provide the old password. Here it is only possible to have one password, if there
                // are more every one should match with the given old password
                passwords = userPassword.getAll();
                if (passwords.hasMore()) {
                    byte[] byteArray = (byte[]) passwords.next();
                    String password = new String(byteArray);

                    if (password.startsWith("{")) {
                        passwordHashMethod = password.substring(password.indexOf('{') + 1,
                                password.indexOf('}'));
                    }
                }
            }

            String dnName = searchResult.getName();
            subDirContext = (DirContext) dirContext.lookup(searchBase);

            Attribute passwordAttribute = new BasicAttribute("userPassword");
            passwordAttribute.add(
                    UserCoreUtil.getPasswordToStore((String) newCredential, passwordHashMethod, kdcEnabled));
            BasicAttributes basicAttributes = new BasicAttributes(true);
            basicAttributes.put(passwordAttribute);
            subDirContext.modifyAttributes(dnName, DirContext.REPLACE_ATTRIBUTE, basicAttributes);
        }
        // we check whether both carbon admin entry and ldap connection
        // entry are the same
        if (searchResult.getNameInNamespace()
                .equals(realmConfig.getUserStoreProperty(LDAPConstants.CONNECTION_NAME))) {
            this.connectionSource.updateCredential((String) newCredential);
        }

    } catch (NamingException e) {
        String errorMessage = "Can not access the directory service for user : " + userName;
        if (log.isDebugEnabled()) {
            log.debug(errorMessage, e);
        }
        throw new UserStoreException(errorMessage, e);
    } finally {
        JNDIUtil.closeNamingEnumeration(passwords);
        JNDIUtil.closeNamingEnumeration(namingEnumeration);

        JNDIUtil.closeContext(subDirContext);
        JNDIUtil.closeContext(dirContext);
    }
}

From source file:no.feide.moria.directory.backend.JNDIBackend.java

/**
 * Retrieves a list of attributes from an element.
 * @param ldap/*from w w  w .  ja va2  s.com*/
 *            A prepared LDAP context. Cannot be <code>null</code>.
 * @param rdn
 *            The relative DN (to the DN in the LDAP context
 *            <code>ldap</code>). Cannot be <code>null</code>.
 * @param attributes
 *            The requested attribute's names. Also indirectly referenced
 *            attributes on the form
 *            <code>someReferenceAttribute:someIndirectAttribute</code>,
 *            where the DN in the reference attribute
 *            <code>someReferenceAttribute</code> is followed to look up
 *            <code>someIndirectAttribute</code> from another element.
 * @return The requested attributes (<code>String</code> names and
 *         <code>String[]</code> values), if they did exist in the
 *         external backend. Otherwise returns those attributes that could
 *         actually be read, this may be an empty <code>HashMap</code>.
 *         Returns an empty <code>HashMap</code> if
 *         <code>attributes</code> is <code>null</code> or an empty
 *         array. Note that attribute values are mapped to
 *         <code>String</code> using ISO-8859-1.
 * @throws BackendException
 *             If unable to read the attributes from the backend.
 * @throws NullPointerException
 *             If <code>ldap</code> or <code>rdn</code> is
 *             <code>null</code>.
 * @see javax.naming.directory.InitialDirContext#getAttributes(java.lang.String,
 *      java.lang.String[])
 */
private HashMap<String, String[]> getAttributes(final InitialLdapContext ldap, final String rdn,
        final String[] attributes) throws BackendException {

    // Sanity checks.
    if (ldap == null)
        throw new NullPointerException("LDAP context cannot be NULL");
    if (rdn == null)
        throw new NullPointerException("RDN cannot be NULL");
    if ((attributes == null) || (attributes.length == 0))
        return new HashMap<String, String[]>();

    // Used to remember attributes to be read through references later on.
    Hashtable<String, Vector> attributeReferences = new Hashtable<String, Vector>();

    // Strip down request, resolving references and removing duplicates.
    Vector<String> strippedAttributeRequest = new Vector<String>();
    for (int i = 0; i < attributes.length; i++) {
        int indexOfSplitCharacter = attributes[i]
                .indexOf(DirectoryManagerBackend.ATTRIBUTE_REFERENCE_SEPARATOR);
        if (indexOfSplitCharacter == -1) {

            // A regular attribute request.
            if (!strippedAttributeRequest.contains(attributes[i]))
                strippedAttributeRequest.add(attributes[i]);

        } else {

            // A referenced attribute request.
            final String referencingAttribute = attributes[i].substring(0, indexOfSplitCharacter);
            if (!strippedAttributeRequest.contains(referencingAttribute))
                strippedAttributeRequest.add(referencingAttribute);

            // Add to list of attributes to be read through each reference.
            if (!attributeReferences.containsKey(referencingAttribute)) {

                // Add new reference.
                Vector<String> referencedAttribute = new Vector<String>();
                referencedAttribute.add(attributes[i].substring(indexOfSplitCharacter + 1));
                attributeReferences.put(referencingAttribute, referencedAttribute);

            } else {

                // Update existing reference.
                Vector<String> referencedAttribute = attributeReferences.get(referencingAttribute);
                if (!referencedAttribute.contains(attributes[i].substring(indexOfSplitCharacter + 1)))
                    referencedAttribute.add(attributes[i].substring(indexOfSplitCharacter + 1));

            }

        }

    }

    // The context provider URL and DN, for later logging.
    String url = "unknown backend";
    String dn = "unknown dn";

    // Get the attributes from an already initialized LDAP connection.
    Attributes rawAttributes = null;
    try {

        // Remember the URL and bind DN, for later logging.
        final Hashtable environment = ldap.getEnvironment();
        url = (String) environment.get(Context.PROVIDER_URL);
        dn = (String) environment.get(Context.SECURITY_PRINCIPAL);

        // Get the attributes.
        rawAttributes = ldap.getAttributes(rdn, strippedAttributeRequest.toArray(new String[] {}));

    } catch (NameNotFoundException e) {

        // Successful authentication but missing user element; no attributes
        // returned and the event is logged.
        log.logWarn("No LDAP element found (DN was '" + dn + "')", mySessionTicket);
        rawAttributes = new BasicAttributes();

    } catch (NamingException e) {
        String a = new String();
        for (int i = 0; i < attributes.length; i++)
            a = a + attributes[i] + ", ";
        throw new BackendException("Unable to read attribute(s) '" + a.substring(0, a.length() - 2) + "' from '"
                + rdn + "' on '" + url + "'", e);
    }

    // Translate retrieved attributes from Attributes to HashMap.
    HashMap<String, String[]> convertedAttributes = new HashMap<String, String[]>();
    for (int i = 0; i < attributes.length; i++) {

        // Did we get any attribute back at all?
        final String requestedAttribute = attributes[i];
        Attribute rawAttribute = rawAttributes.get(requestedAttribute);
        if (rawAttribute == null) {

            // Attribute was not returned.
            log.logDebug("Requested attribute '" + requestedAttribute + "' not found on '" + url + "'",
                    mySessionTicket);

        } else {

            // Map the attribute values to String[].
            ArrayList<String> convertedAttributeValues = new ArrayList<String>(rawAttribute.size());
            for (int j = 0; j < rawAttribute.size(); j++) {
                try {

                    // We either have a String or a byte[].
                    String convertedAttributeValue = null;
                    try {

                        // Encode String.
                        convertedAttributeValue = new String(((String) rawAttribute.get(j)).getBytes(),
                                DirectoryManagerBackend.ATTRIBUTE_VALUE_CHARSET);
                    } catch (ClassCastException e) {

                        // Encode byte[] to String.
                        convertedAttributeValue = new String(Base64.encodeBase64((byte[]) rawAttribute.get(j)),
                                DirectoryManagerBackend.ATTRIBUTE_VALUE_CHARSET);

                    }
                    convertedAttributeValues.add(convertedAttributeValue);

                } catch (NamingException e) {
                    throw new BackendException("Unable to read attribute value of '" + rawAttribute.getID()
                            + "' from '" + url + "'", e);
                } catch (UnsupportedEncodingException e) {
                    throw new BackendException(
                            "Unable to use " + DirectoryManagerBackend.ATTRIBUTE_VALUE_CHARSET + " encoding",
                            e);
                }
            }
            convertedAttributes.put(requestedAttribute, convertedAttributeValues.toArray(new String[] {}));

        }

    }

    // Follow references to look up any indirectly referenced attributes.
    Enumeration<String> keys = attributeReferences.keys();
    while (keys.hasMoreElements()) {

        // Do we have a reference? 
        final String referencingAttribute = keys.nextElement();
        final String[] referencingValues = convertedAttributes.get(referencingAttribute);
        if (referencingValues == null) {

            // No reference was found in this attribute.
            log.logDebug("Found no DN references in attribute '" + referencingAttribute + "'", mySessionTicket);

        } else {

            // One (or more) references was found in this attribute.
            if (referencingValues.length > 1)
                log.logDebug("Found " + referencingValues.length + " DN references in attribute '"
                        + referencingAttribute + "'; ignoring all but first", mySessionTicket);
            log.logDebug("Following reference '" + referencingValues[0] + "' found in '" + referencingAttribute
                    + "' to look up attribute(s) '" + attributeReferences.get(referencingAttribute).toString(),
                    mySessionTicket);
            String providerURL = null; // To be used later.
            try {

                // Follow the reference.
                providerURL = (String) ldap.getEnvironment().get(Context.PROVIDER_URL);
                providerURL = providerURL.substring(0, providerURL.lastIndexOf("/") + 1) + referencingValues[0];
                ldap.addToEnvironment(Context.PROVIDER_URL, providerURL);

            } catch (NamingException e) {
                throw new BackendException("Unable to update provider URL in LDAP environment", e);
            }

            // Add any referenced attributes returned.
            HashMap additionalAttributes = getAttributes(ldap, providerURL,
                    (String[]) attributeReferences.get(referencingAttribute).toArray(new String[] {}));
            Iterator i = additionalAttributes.keySet().iterator();
            while (i.hasNext()) {
                String attributeName = (String) i.next();
                convertedAttributes.put(referencingAttribute
                        + DirectoryManagerBackend.ATTRIBUTE_REFERENCE_SEPARATOR + attributeName,
                        (String[]) additionalAttributes.get(attributeName));
            }

        }

    }

    return convertedAttributes;

}

From source file:org.wso2.carbon.identity.agent.onprem.userstore.manager.ldap.LDAPUserStoreManager.java

/**
 * {@inheritDoc}//  www  . j a v  a2  s  .c  o  m
 */
@Override
public String[] doGetUserListOfRole(String roleName, int maxItemLimit) throws UserStoreException {

    boolean debug = log.isDebugEnabled();
    List<String> userList = new ArrayList<String>();
    String[] names = new String[0];
    int givenMax = CommonConstants.MAX_USER_ROLE_LIST;
    int searchTime = CommonConstants.MAX_SEARCH_TIME;

    try {
        givenMax = Integer.parseInt(userStoreProperties.get(CommonConstants.PROPERTY_MAX_USER_LIST));
    } catch (Exception e) {
        givenMax = CommonConstants.MAX_USER_ROLE_LIST;
    }

    try {
        searchTime = Integer.parseInt(userStoreProperties.get(CommonConstants.PROPERTY_MAX_SEARCH_TIME));
    } catch (Exception e) {
        searchTime = CommonConstants.MAX_SEARCH_TIME;
    }

    if (maxItemLimit <= 0 || maxItemLimit > givenMax) {
        maxItemLimit = givenMax;
    }

    DirContext dirContext = null;
    NamingEnumeration<SearchResult> answer = null;
    try {
        SearchControls searchCtls = new SearchControls();
        searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
        searchCtls.setTimeLimit(searchTime);
        searchCtls.setCountLimit(maxItemLimit);

        String searchFilter = userStoreProperties.get(LDAPConstants.GROUP_NAME_LIST_FILTER);
        String roleNameProperty = userStoreProperties.get(LDAPConstants.GROUP_NAME_ATTRIBUTE);
        searchFilter = "(&" + searchFilter + "(" + roleNameProperty + "="
                + escapeSpecialCharactersForFilter(roleName) + "))";

        String membershipProperty = userStoreProperties.get(LDAPConstants.MEMBERSHIP_ATTRIBUTE);
        String returnedAtts[] = { membershipProperty };
        searchCtls.setReturningAttributes(returnedAtts);
        List<String> userDNList = new ArrayList<String>();

        SearchResult sr = null;
        dirContext = connectionSource.getContext();

        // handling multiple search bases
        String searchBases = userStoreProperties.get(LDAPConstants.GROUP_SEARCH_BASE);
        String[] roleSearchBaseArray = searchBases.split("#");
        for (String searchBase : roleSearchBaseArray) {
            if (debug) {
                log.debug("Searching role: " + roleName + " SearchBase: " + searchBase + " SearchFilter: "
                        + searchFilter);
            }
            try {
                // read the DN of users who are members of the group
                answer = dirContext.search(escapeDNForSearch(searchBase), searchFilter, searchCtls);
                int count = 0;
                if (answer.hasMore()) { // to check if there is a result
                    while (answer.hasMore()) { // to check if there are more than one group
                        if (count > 0) {
                            throw new UserStoreException("More than one group exist with name");
                        }
                        sr = answer.next();
                        count++;
                    }
                    break;
                }
            } catch (NamingException e) {
                // ignore
                if (log.isDebugEnabled()) {
                    log.debug(e);
                }
            }
        }

        if (debug) {
            log.debug("Found role: " + sr.getNameInNamespace());
        }

        // read the member attribute and get DNs of the users
        Attributes attributes = sr.getAttributes();
        if (attributes != null) {
            NamingEnumeration attributeEntry = null;
            for (attributeEntry = attributes.getAll(); attributeEntry.hasMore();) {
                Attribute valAttribute = (Attribute) attributeEntry.next();
                if (membershipProperty.equals(valAttribute.getID())) {
                    NamingEnumeration values = null;
                    for (values = valAttribute.getAll(); values.hasMore();) {
                        String value = values.next().toString();
                        if (userDNList.size() >= maxItemLimit) {
                            break;
                        }
                        userDNList.add(value);
                        if (debug) {
                            log.debug("Found attribute: " + membershipProperty + " value: " + value);
                        }
                    }
                }
            }
        }

        if (MEMBER_UID.equals(userStoreProperties.get(LDAPConstants.MEMBERSHIP_ATTRIBUTE))) {
            /* when the GroupEntryObjectClass is posixGroup, membership attribute is memberUid. We have to
               retrieve the DN using the memberUid.
               This procedure has to make an extra call to ldap. alternatively this can be done with a single ldap
               search using the memberUid and retrieving the display name and username. */
            List<String> userDNListNew = new ArrayList<>();

            for (String user : userDNList) {
                String userDN = getNameInSpaceForUserName(user);
                userDNListNew.add(userDN);
            }
            userDNList = userDNListNew;
        }

        // iterate over users' DN list and get userName and display name
        // attribute values
        String userNameProperty = userStoreProperties.get(LDAPConstants.USER_NAME_ATTRIBUTE);
        String displayNameAttribute = userStoreProperties.get(LDAPConstants.DISPLAY_NAME_ATTRIBUTE);
        String[] returnedAttributes = { userNameProperty, displayNameAttribute };

        for (String user : userDNList) {
            if (debug) {
                log.debug("Getting name attributes of: " + user);
            }
            Attributes userAttributes;
            try {
                // '\' and '"' characters need another level of escaping before searching
                userAttributes = dirContext.getAttributes(escapeDNForSearch(user), returnedAttributes);

                String displayName = null;
                String userName = null;
                if (userAttributes != null) {
                    Attribute userNameAttribute = userAttributes.get(userNameProperty);
                    if (userNameAttribute != null) {
                        userName = (String) userNameAttribute.get();
                        if (debug) {
                            log.debug("UserName: " + userName);
                        }
                    }
                    if (org.apache.commons.lang.StringUtils.isNotEmpty(displayNameAttribute)) {
                        Attribute displayAttribute = userAttributes.get(displayNameAttribute);
                        if (displayAttribute != null) {
                            displayName = (String) displayAttribute.get();
                        }
                        if (debug) {
                            log.debug("DisplayName: " + displayName);
                        }
                    }
                }

                // Username will be null in the special case where the
                // username attribute has changed to another
                // and having different userNameProperty than the current
                // user-mgt.xml
                if (userName != null) {
                    user = UserStoreUtils.getCombinedName(userName, displayName);
                    userList.add(user);
                    if (debug) {
                        log.debug(user + " is added to the result list");
                    }
                } else {
                    if (log.isDebugEnabled()) {
                        log.debug(
                                "User " + user + " doesn't have the user name property : " + userNameProperty);
                    }
                }

            } catch (NamingException e) {
                if (log.isDebugEnabled()) {
                    log.debug("Error in reading user information in the user store for the user " + user
                            + e.getMessage(), e);
                }
            }

        }
        names = userList.toArray(new String[userList.size()]);

    } catch (PartialResultException e) {
        // can be due to referrals in AD. so just ignore error
        String errorMessage = "Error in reading user information in the user store";
        if (isIgnorePartialResultException()) {
            if (log.isDebugEnabled()) {
                log.debug(errorMessage, e);
            }
        } else {
            throw new UserStoreException(errorMessage, e);
        }
    } catch (NamingException e) {
        String errorMessage = "Error in reading user information in the user store";
        if (log.isDebugEnabled()) {
            log.debug(errorMessage, e);
        }
        throw new UserStoreException(errorMessage, e);
    } finally {
        JNDIUtil.closeNamingEnumeration(answer);
        JNDIUtil.closeContext(dirContext);
    }
    return names;
}