Search in sources :

Example 1 with SearchResult

use of javax.naming.directory.SearchResult in project jetty.project by eclipse.

the class LdapLoginModule method getUserRolesByDn.

private List<String> getUserRolesByDn(DirContext dirContext, String userDn) throws LoginException, NamingException {
    List<String> roleList = new ArrayList<String>();
    if (dirContext == null || _roleBaseDn == null || _roleMemberAttribute == null || _roleObjectClass == null) {
        return roleList;
    }
    SearchControls ctls = new SearchControls();
    ctls.setDerefLinkFlag(true);
    ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
    ctls.setReturningAttributes(new String[] { _roleNameAttribute });
    String filter = "(&(objectClass={0})({1}={2}))";
    Object[] filterArguments = { _roleObjectClass, _roleMemberAttribute, userDn };
    NamingEnumeration<SearchResult> results = dirContext.search(_roleBaseDn, filter, filterArguments, ctls);
    LOG.debug("Found user roles?: " + results.hasMoreElements());
    while (results.hasMoreElements()) {
        SearchResult result = (SearchResult) results.nextElement();
        Attributes attributes = result.getAttributes();
        if (attributes == null) {
            continue;
        }
        Attribute roleAttribute = attributes.get(_roleNameAttribute);
        if (roleAttribute == null) {
            continue;
        }
        NamingEnumeration<?> roles = roleAttribute.getAll();
        while (roles.hasMore()) {
            roleList.add(roles.next().toString());
        }
    }
    return roleList;
}
Also used : Attribute(javax.naming.directory.Attribute) ArrayList(java.util.ArrayList) Attributes(javax.naming.directory.Attributes) SearchControls(javax.naming.directory.SearchControls) SearchResult(javax.naming.directory.SearchResult)

Example 2 with SearchResult

use of javax.naming.directory.SearchResult in project tomcat by apache.

the class JNDIRealm method getRoles.

/**
     * Return a List of roles associated with the given User.  Any
     * roles present in the user's directory entry are supplemented by
     * a directory search. If no roles are associated with this user,
     * a zero-length List is returned.
     *
     * @param context The directory context we are searching
     * @param user The User to be checked
     * @return the list of role names
     * @exception NamingException if a directory server error occurs
     */
protected List<String> getRoles(DirContext context, User user) throws NamingException {
    if (user == null)
        return null;
    String dn = user.getDN();
    String username = user.getUserName();
    String userRoleId = user.getUserRoleId();
    if (dn == null || username == null)
        return null;
    if (containerLog.isTraceEnabled())
        containerLog.trace("  getRoles(" + dn + ")");
    // Start with roles retrieved from the user entry
    List<String> list = new ArrayList<>();
    List<String> userRoles = user.getRoles();
    if (userRoles != null) {
        list.addAll(userRoles);
    }
    if (commonRole != null)
        list.add(commonRole);
    if (containerLog.isTraceEnabled()) {
        containerLog.trace("  Found " + list.size() + " user internal roles");
        containerLog.trace("  Found user internal roles " + list.toString());
    }
    // Are we configured to do role searches?
    if ((roleFormat == null) || (roleName == null))
        return list;
    // Set up parameters for an appropriate search
    String filter = roleFormat.format(new String[] { doRFC2254Encoding(dn), username, userRoleId });
    SearchControls controls = new SearchControls();
    if (roleSubtree)
        controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
    else
        controls.setSearchScope(SearchControls.ONELEVEL_SCOPE);
    controls.setReturningAttributes(new String[] { roleName });
    String base = null;
    if (roleBaseFormat != null) {
        NameParser np = context.getNameParser("");
        Name name = np.parse(dn);
        String[] nameParts = new String[name.size()];
        for (int i = 0; i < name.size(); i++) {
            nameParts[i] = name.get(i);
        }
        base = roleBaseFormat.format(nameParts);
    } else {
        base = "";
    }
    // Perform the configured search and process the results
    NamingEnumeration<SearchResult> results = searchAsUser(context, user, base, filter, controls, isRoleSearchAsUser());
    if (results == null)
        // Should never happen, but just in case ...
        return list;
    HashMap<String, String> groupMap = new HashMap<>();
    try {
        while (results.hasMore()) {
            SearchResult result = results.next();
            Attributes attrs = result.getAttributes();
            if (attrs == null)
                continue;
            String dname = getDistinguishedName(context, roleBase, result);
            String name = getAttributeValue(roleName, attrs);
            if (name != null && dname != null) {
                groupMap.put(dname, name);
            }
        }
    } catch (PartialResultException ex) {
        if (!adCompat)
            throw ex;
    } finally {
        results.close();
    }
    if (containerLog.isTraceEnabled()) {
        Set<Entry<String, String>> entries = groupMap.entrySet();
        containerLog.trace("  Found " + entries.size() + " direct roles");
        for (Entry<String, String> entry : entries) {
            containerLog.trace("  Found direct role " + entry.getKey() + " -> " + entry.getValue());
        }
    }
    // if nested group search is enabled, perform searches for nested groups until no new group is found
    if (getRoleNested()) {
        // The following efficient algorithm is known as memberOf Algorithm, as described in "Practices in
        // Directory Groups". It avoids group slurping and handles cyclic group memberships as well.
        // See http://middleware.internet2.edu/dir/ for details
        Map<String, String> newGroups = new HashMap<>(groupMap);
        while (!newGroups.isEmpty()) {
            // Stores the groups we find in this iteration
            Map<String, String> newThisRound = new HashMap<>();
            for (Entry<String, String> group : newGroups.entrySet()) {
                filter = roleFormat.format(new String[] { group.getKey(), group.getValue(), group.getValue() });
                if (containerLog.isTraceEnabled()) {
                    containerLog.trace("Perform a nested group search with base " + roleBase + " and filter " + filter);
                }
                results = searchAsUser(context, user, roleBase, filter, controls, isRoleSearchAsUser());
                try {
                    while (results.hasMore()) {
                        SearchResult result = results.next();
                        Attributes attrs = result.getAttributes();
                        if (attrs == null)
                            continue;
                        String dname = getDistinguishedName(context, roleBase, result);
                        String name = getAttributeValue(roleName, attrs);
                        if (name != null && dname != null && !groupMap.keySet().contains(dname)) {
                            groupMap.put(dname, name);
                            newThisRound.put(dname, name);
                            if (containerLog.isTraceEnabled()) {
                                containerLog.trace("  Found nested role " + dname + " -> " + name);
                            }
                        }
                    }
                } catch (PartialResultException ex) {
                    if (!adCompat)
                        throw ex;
                } finally {
                    results.close();
                }
            }
            newGroups = newThisRound;
        }
    }
    list.addAll(groupMap.values());
    return list;
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Attributes(javax.naming.directory.Attributes) SearchResult(javax.naming.directory.SearchResult) PartialResultException(javax.naming.PartialResultException) CompositeName(javax.naming.CompositeName) Name(javax.naming.Name) Entry(java.util.Map.Entry) SearchControls(javax.naming.directory.SearchControls) NameParser(javax.naming.NameParser)

Example 3 with SearchResult

use of javax.naming.directory.SearchResult in project zeppelin by apache.

the class LdapRealm method rolesFor.

private Set<String> rolesFor(PrincipalCollection principals, String userNameIn, final LdapContext ldapCtx, final LdapContextFactory ldapContextFactory) throws NamingException {
    final Set<String> roleNames = new HashSet<>();
    final Set<String> groupNames = new HashSet<>();
    final String userName;
    if (getUserLowerCase()) {
        log.debug("userLowerCase true");
        userName = userNameIn.toLowerCase();
    } else {
        userName = userNameIn;
    }
    String userDn;
    if (userSearchAttributeName == null || userSearchAttributeName.isEmpty()) {
        // memberAttributeValuePrefix and memberAttributeValueSuffix 
        // were computed from memberAttributeValueTemplate
        userDn = memberAttributeValuePrefix + userName + memberAttributeValueSuffix;
    } else {
        userDn = getUserDn(userName);
    }
    // Activate paged results
    int pageSize = getPagingSize();
    if (log.isDebugEnabled()) {
        log.debug("Ldap PagingSize: " + pageSize);
    }
    int numResults = 0;
    byte[] cookie = null;
    try {
        ldapCtx.addToEnvironment(Context.REFERRAL, "ignore");
        ldapCtx.setRequestControls(new Control[] { new PagedResultsControl(pageSize, Control.NONCRITICAL) });
        do {
            // ldapsearch -h localhost -p 33389 -D
            // uid=guest,ou=people,dc=hadoop,dc=apache,dc=org -w guest-password
            // -b dc=hadoop,dc=apache,dc=org -s sub '(objectclass=*)'
            NamingEnumeration<SearchResult> searchResultEnum = null;
            SearchControls searchControls = getGroupSearchControls();
            try {
                if (groupSearchEnableMatchingRuleInChain) {
                    searchResultEnum = ldapCtx.search(getGroupSearchBase(), String.format(MATCHING_RULE_IN_CHAIN_FORMAT, groupObjectClass, memberAttribute, userDn), searchControls);
                    while (searchResultEnum != null && searchResultEnum.hasMore()) {
                        // searchResults contains all the groups in search scope
                        numResults++;
                        final SearchResult group = searchResultEnum.next();
                        Attribute attribute = group.getAttributes().get(getGroupIdAttribute());
                        String groupName = attribute.get().toString();
                        String roleName = roleNameFor(groupName);
                        if (roleName != null) {
                            roleNames.add(roleName);
                        } else {
                            roleNames.add(groupName);
                        }
                    }
                } else {
                    searchResultEnum = ldapCtx.search(getGroupSearchBase(), "objectClass=" + groupObjectClass, searchControls);
                    while (searchResultEnum != null && searchResultEnum.hasMore()) {
                        // searchResults contains all the groups in search scope
                        numResults++;
                        final SearchResult group = searchResultEnum.next();
                        addRoleIfMember(userDn, group, roleNames, groupNames, ldapContextFactory);
                    }
                }
            } catch (PartialResultException e) {
                log.debug("Ignoring PartitalResultException");
            } finally {
                if (searchResultEnum != null) {
                    searchResultEnum.close();
                }
            }
            // Re-activate paged results
            ldapCtx.setRequestControls(new Control[] { new PagedResultsControl(pageSize, cookie, Control.CRITICAL) });
        } while (cookie != null);
    } catch (SizeLimitExceededException e) {
        log.info("Only retrieved first " + numResults + " groups due to SizeLimitExceededException.");
    } catch (IOException e) {
        log.error("Unabled to setup paged results");
    }
    // save role names and group names in session so that they can be
    // easily looked up outside of this object
    SecurityUtils.getSubject().getSession().setAttribute(SUBJECT_USER_ROLES, roleNames);
    SecurityUtils.getSubject().getSession().setAttribute(SUBJECT_USER_GROUPS, groupNames);
    if (!groupNames.isEmpty() && (principals instanceof MutablePrincipalCollection)) {
        ((MutablePrincipalCollection) principals).addAll(groupNames, getName());
    }
    if (log.isDebugEnabled()) {
        log.debug("User RoleNames: " + userName + "::" + roleNames);
    }
    return roleNames;
}
Also used : Attribute(javax.naming.directory.Attribute) SearchResult(javax.naming.directory.SearchResult) PartialResultException(javax.naming.PartialResultException) IOException(java.io.IOException) MutablePrincipalCollection(org.apache.shiro.subject.MutablePrincipalCollection) SizeLimitExceededException(javax.naming.SizeLimitExceededException) SearchControls(javax.naming.directory.SearchControls) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) PagedResultsControl(javax.naming.ldap.PagedResultsControl)

Example 4 with SearchResult

use of javax.naming.directory.SearchResult in project zeppelin by apache.

the class GetUserList method getUserList.

/**
   * function to extract users from LDAP
   */
public List<String> getUserList(JndiLdapRealm r, String searchText) {
    List<String> userList = new ArrayList<>();
    String userDnTemplate = r.getUserDnTemplate();
    String[] userDn = userDnTemplate.split(",", 2);
    String userDnPrefix = userDn[0].split("=")[0];
    String userDnSuffix = userDn[1];
    JndiLdapContextFactory CF = (JndiLdapContextFactory) r.getContextFactory();
    try {
        LdapContext ctx = CF.getSystemLdapContext();
        SearchControls constraints = new SearchControls();
        constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
        String[] attrIDs = { userDnPrefix };
        constraints.setReturningAttributes(attrIDs);
        NamingEnumeration result = ctx.search(userDnSuffix, "(" + userDnPrefix + "=*" + searchText + "*)", constraints);
        while (result.hasMore()) {
            Attributes attrs = ((SearchResult) result.next()).getAttributes();
            if (attrs.get(userDnPrefix) != null) {
                String currentUser = attrs.get(userDnPrefix).toString();
                userList.add(currentUser.split(":")[1].trim());
            }
        }
    } catch (Exception e) {
        LOG.error("Error retrieving User list from Ldap Realm", e);
    }
    LOG.info("UserList: " + userList);
    return userList;
}
Also used : ArrayList(java.util.ArrayList) Attributes(javax.naming.directory.Attributes) SearchControls(javax.naming.directory.SearchControls) NamingEnumeration(javax.naming.NamingEnumeration) SearchResult(javax.naming.directory.SearchResult) LdapContext(javax.naming.ldap.LdapContext) JndiLdapContextFactory(org.apache.shiro.realm.ldap.JndiLdapContextFactory)

Example 5 with SearchResult

use of javax.naming.directory.SearchResult in project Openfire by igniterealtime.

the class LdapManager method retrieveList.

/**
     * Generic routine for retrieving a list of results from the LDAP server.  It's meant to be very
     * flexible so that just about any query for a list of results can make use of it without having
     * to reimplement their own calls to LDAP.  This routine also accounts for sorting settings,
     * paging settings, any other global settings, and alternate DNs.
     *
     * The passed in filter string needs to be pre-prepared!  In other words, nothing will be changed
     * in the string before it is used as a string.
     *
     * @param attribute LDAP attribute to be pulled from each result and placed in the return results.
     *     Typically pulled from this manager.
     * @param searchFilter Filter to use to perform the search.  Typically pulled from this manager.
     * @param startIndex Number/index of first result to include in results.  (-1 for no limit)
     * @param numResults Number of results to include.  (-1 for no limit)
     * @param suffixToTrim An arbitrary string to trim from the end of every attribute returned.  null to disable.
     * @param escapeJIDs Use JID-escaping for returned results (e.g. usernames)
     * @return A simple list of strings (that should be sorted) of the results.
     */
public List<String> retrieveList(String attribute, String searchFilter, int startIndex, int numResults, String suffixToTrim, boolean escapeJIDs) {
    List<String> results = new ArrayList<>();
    int pageSize = -1;
    String pageSizeStr = properties.get("ldap.pagedResultsSize");
    if (pageSizeStr != null) {
        try {
            pageSize = Integer.parseInt(pageSizeStr);
        /* radix -1 is invalid */
        } catch (NumberFormatException e) {
        // poorly formatted number, ignoring
        }
    }
    Boolean clientSideSort = false;
    String clientSideSortStr = properties.get("ldap.clientSideSorting");
    if (clientSideSortStr != null) {
        clientSideSort = Boolean.valueOf(clientSideSortStr);
    }
    LdapContext ctx = null;
    LdapContext ctx2 = null;
    try {
        ctx = getContext(baseDN);
        // Set up request controls, if appropriate.
        List<Control> baseTmpRequestControls = new ArrayList<>();
        if (!clientSideSort) {
            // Server side sort on username field.
            baseTmpRequestControls.add(new SortControl(new String[] { attribute }, Control.NONCRITICAL));
        }
        if (pageSize > 0) {
            // Server side paging.
            baseTmpRequestControls.add(new PagedResultsControl(pageSize, Control.NONCRITICAL));
        }
        Control[] baseRequestControls = baseTmpRequestControls.toArray(new Control[baseTmpRequestControls.size()]);
        ctx.setRequestControls(baseRequestControls);
        SearchControls searchControls = new SearchControls();
        // See if recursive searching is enabled. Otherwise, only search one level.
        if (isSubTreeSearch()) {
            searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
        } else {
            searchControls.setSearchScope(SearchControls.ONELEVEL_SCOPE);
        }
        searchControls.setReturningAttributes(new String[] { attribute });
        // If server side sort, we'll skip the initial ones we don't want, and stop when we've hit
        // the amount we do want.
        int skip = -1;
        int lastRes = -1;
        if (!clientSideSort) {
            if (startIndex != -1) {
                skip = startIndex;
            }
            if (numResults != -1) {
                lastRes = startIndex + numResults;
            }
        }
        byte[] cookie;
        int count = 0;
        // Run through all pages of results (one page is also possible  ;)  )
        do {
            cookie = null;
            NamingEnumeration<SearchResult> answer = ctx.search("", searchFilter, searchControls);
            // Examine all of the results on this page
            while (answer.hasMoreElements()) {
                count++;
                if (skip > 0 && count <= skip) {
                    answer.next();
                    continue;
                }
                if (lastRes != -1 && count > lastRes) {
                    answer.next();
                    break;
                }
                // Get the next result.
                String result = (String) answer.next().getAttributes().get(attribute).get();
                // Remove suffixToTrim if set
                if (suffixToTrim != null && suffixToTrim.length() > 0 && result.endsWith(suffixToTrim)) {
                    result = result.substring(0, result.length() - suffixToTrim.length());
                }
                // Add this to the result.
                results.add(escapeJIDs ? JID.escapeNode(result) : result);
            }
            // Examine the paged results control response
            Control[] controls = ctx.getResponseControls();
            if (controls != null) {
                for (Control control : controls) {
                    if (control instanceof PagedResultsResponseControl) {
                        PagedResultsResponseControl prrc = (PagedResultsResponseControl) control;
                        cookie = prrc.getCookie();
                    }
                }
            }
            // Close the enumeration.
            answer.close();
            // Re-activate paged results; affects nothing if no paging support
            List<Control> tmpRequestControls = new ArrayList<>();
            if (!clientSideSort) {
                // Server side sort on username field.
                tmpRequestControls.add(new SortControl(new String[] { attribute }, Control.NONCRITICAL));
            }
            if (pageSize > 0) {
                // Server side paging.
                tmpRequestControls.add(new PagedResultsControl(pageSize, cookie, Control.CRITICAL));
            }
            Control[] requestControls = tmpRequestControls.toArray(new Control[tmpRequestControls.size()]);
            ctx.setRequestControls(requestControls);
        } while (cookie != null && (lastRes == -1 || count <= lastRes));
        // Add groups found in alternate DN
        if (alternateBaseDN != null && (lastRes == -1 || count <= lastRes)) {
            ctx2 = getContext(alternateBaseDN);
            ctx2.setRequestControls(baseRequestControls);
            // Run through all pages of results (one page is also possible  ;)  )
            do {
                cookie = null;
                NamingEnumeration<SearchResult> answer = ctx2.search("", searchFilter, searchControls);
                // Examine all of the results on this page
                while (answer.hasMoreElements()) {
                    count++;
                    if (skip > 0 && count <= skip) {
                        answer.next();
                        continue;
                    }
                    if (lastRes != -1 && count > lastRes) {
                        answer.next();
                        break;
                    }
                    // Get the next result.
                    String result = (String) answer.next().getAttributes().get(attribute).get();
                    // Remove suffixToTrim if set
                    if (suffixToTrim != null && suffixToTrim.length() > 0 && result.endsWith(suffixToTrim)) {
                        result = result.substring(0, result.length() - suffixToTrim.length());
                    }
                    // Add this to the result.
                    results.add(escapeJIDs ? JID.escapeNode(result) : result);
                }
                // Examine the paged results control response
                Control[] controls = ctx2.getResponseControls();
                if (controls != null) {
                    for (Control control : controls) {
                        if (control instanceof PagedResultsResponseControl) {
                            PagedResultsResponseControl prrc = (PagedResultsResponseControl) control;
                            cookie = prrc.getCookie();
                        }
                    }
                }
                // Close the enumeration.
                answer.close();
                // Re-activate paged results; affects nothing if no paging support
                List<Control> tmpRequestControls = new ArrayList<>();
                if (!clientSideSort) {
                    // Server side sort on username field.
                    tmpRequestControls.add(new SortControl(new String[] { attribute }, Control.NONCRITICAL));
                }
                if (pageSize > 0) {
                    // Server side paging.
                    tmpRequestControls.add(new PagedResultsControl(pageSize, cookie, Control.CRITICAL));
                }
                Control[] requestControls = tmpRequestControls.toArray(new Control[tmpRequestControls.size()]);
                ctx2.setRequestControls(requestControls);
            } while (cookie != null && (lastRes == -1 || count <= lastRes));
        }
        // If client-side sorting is enabled, sort and trim.
        if (clientSideSort) {
            Collections.sort(results);
            if (startIndex != -1 || numResults != -1) {
                if (startIndex == -1) {
                    startIndex = 0;
                }
                if (numResults == -1) {
                    numResults = results.size();
                }
                int endIndex = Math.min(startIndex + numResults, results.size() - 1);
                results = results.subList(startIndex, endIndex);
            }
        }
    } catch (Exception e) {
        Log.error(e.getMessage(), e);
    } finally {
        try {
            if (ctx != null) {
                ctx.setRequestControls(null);
                ctx.close();
            }
            if (ctx2 != null) {
                ctx2.setRequestControls(null);
                ctx2.close();
            }
        } catch (Exception ignored) {
        // Ignore.
        }
    }
    return results;
}
Also used : PagedResultsResponseControl(javax.naming.ldap.PagedResultsResponseControl) ArrayList(java.util.ArrayList) SearchResult(javax.naming.directory.SearchResult) NamingException(javax.naming.NamingException) GroupNotFoundException(org.jivesoftware.openfire.group.GroupNotFoundException) UserNotFoundException(org.jivesoftware.openfire.user.UserNotFoundException) SortControl(javax.naming.ldap.SortControl) Control(javax.naming.ldap.Control) SortControl(javax.naming.ldap.SortControl) PagedResultsControl(javax.naming.ldap.PagedResultsControl) PagedResultsResponseControl(javax.naming.ldap.PagedResultsResponseControl) SearchControls(javax.naming.directory.SearchControls) JiveInitialLdapContext(org.jivesoftware.util.JiveInitialLdapContext) LdapContext(javax.naming.ldap.LdapContext) PagedResultsControl(javax.naming.ldap.PagedResultsControl)

Aggregations

SearchResult (javax.naming.directory.SearchResult)253 SearchControls (javax.naming.directory.SearchControls)148 NamingException (javax.naming.NamingException)116 Attributes (javax.naming.directory.Attributes)99 Attribute (javax.naming.directory.Attribute)90 ArrayList (java.util.ArrayList)75 LdapContext (javax.naming.ldap.LdapContext)39 NamingEnumeration (javax.naming.NamingEnumeration)38 DirContext (javax.naming.directory.DirContext)34 Test (org.junit.Test)32 HashSet (java.util.HashSet)30 BasicAttributes (javax.naming.directory.BasicAttributes)30 InitialDirContext (javax.naming.directory.InitialDirContext)27 PagedResultsControl (javax.naming.ldap.PagedResultsControl)25 HashMap (java.util.HashMap)23 InitialLdapContext (javax.naming.ldap.InitialLdapContext)23 IOException (java.io.IOException)19 BasicAttribute (javax.naming.directory.BasicAttribute)19 Control (javax.naming.ldap.Control)19 PagedResultsResponseControl (javax.naming.ldap.PagedResultsResponseControl)18