Skip to content
LdapUserDAO.java 50.2 KiB
Newer Older
Jeff Burke's avatar
Jeff Burke committed
            logger.debug("setPassword Exception: " + e);
            LdapDAO.checkLdapResult(e.getResultCode());
        }
    
    /**
     * Update a user's password. The given user and authenticating user must match.
     *
     * @param userID
     * @param oldPassword   current password.
     * @param newPassword   new password.
     * @throws UserNotFoundException If the given user does not exist.
     * @throws TransientException   If an temporary, unexpected problem occurred.
     * @throws AccessControlException If the operation is not permitted.
     */
    public void setPassword(HttpPrincipal userID, String oldPassword, String newPassword)
        throws UserNotFoundException, TransientException, AccessControlException
    {
        updatePassword(userID, oldPassword, newPassword);
    }

    /**
     * Reset a user's password. The given user and authenticating user must match.
     *
     * @param userID
     * @param newPassword   new password.
     * @throws UserNotFoundException If the given user does not exist.
     * @throws TransientException   If an temporary, unexpected problem occurred.
     * @throws AccessControlException If the operation is not permitted.
     */
    public void resetPassword(HttpPrincipal userID, String newPassword)
        throws UserNotFoundException, TransientException, AccessControlException
    {
     * Delete the user specified by userID from the active user tree.
     *
     * @param userID The userID.
     * @throws UserNotFoundException  when the user is not found.
     * @throws TransientException     If an temporary, unexpected problem occurred.
     * @throws AccessControlException If the operation is not permitted.
     */
    public void deleteUser(final T userID)
            throws UserNotFoundException, TransientException,
                   AccessControlException
        deleteUser(userID, config.getUsersDN(), true);
    }

    /**
     * Delete the user specified by userID from the pending user tree.
     *
     * @param userID The userID.
     * @throws UserNotFoundException  when the user is not found.
     * @throws TransientException     If an temporary, unexpected problem occurred.
     * @throws AccessControlException If the operation is not permitted.
     */
    public void deletePendingUser(final T userID)
        throws UserNotFoundException, TransientException,
        AccessControlException
    {
        deleteUser(userID, config.getUserRequestsDN(), false);
    private void deleteUser(final T userID, final String usersDN, boolean markDelete)
        throws UserNotFoundException, AccessControlException, TransientException
    {
        getUser(userID, usersDN);
        try
        {
            DN userDN = getUserDN(userID.getName(), usersDN);
            if (markDelete)
            {
                List<Modification> modifs = new ArrayList<Modification>();
                modifs.add(new Modification(ModificationType.ADD, LDAP_NSACCOUNTLOCK, "true"));
                ModifyRequest modifyRequest = new ModifyRequest(userDN, modifs);
Patrick Dowler's avatar
Patrick Dowler committed
                //modifyRequest.addControl(
                //    new ProxiedAuthorizationV2RequestControl(
                //        "dn:" + getSubjectDN().toNormalizedString()));
Brian Major's avatar
Brian Major committed
                LDAPResult result = getReadWriteConnection().modify(modifyRequest);
                LdapDAO.checkLdapResult(result.getResultCode());
            }
            else // real delete
            {
                DeleteRequest delRequest = new DeleteRequest(userDN);
Patrick Dowler's avatar
Patrick Dowler committed
                //delRequest.addControl(
                //    new ProxiedAuthorizationV2RequestControl(
                //        "dn:" + getSubjectDN().toNormalizedString()));
Brian Major's avatar
Brian Major committed
                LDAPResult result = getReadWriteConnection().delete(delRequest);
                LdapDAO.checkLdapResult(result.getResultCode());
            }
        }
        catch (LDAPException e1)
        {
            logger.debug("Delete Exception: " + e1, e1);
            LdapDAO.checkLdapResult(e1.getResultCode());
        }

        // getUser does not yet support nsaccountlock
        if (!markDelete)
            try
            {
                getUser(userID, usersDN);
                throw new RuntimeException(
                    "BUG: " + userID.getName() + " not deleted in " + usersDN);
            }
            catch (UserNotFoundException ignore) {}
Jeff Burke's avatar
Jeff Burke committed
    /**
     * Returns a member user identified by the X500Principal only. The
     * returned object has the fields required by the LdapGroupDAO.
Dustin Jenkins's avatar
Dustin Jenkins committed
     * Note that this method binds as a proxy user and not as the
Jeff Burke's avatar
Jeff Burke committed
     * @param userDN
     * @return
     * @throws UserNotFoundException
     * @throws LDAPException
     */
    User<X500Principal> getX500User(DN userDN)
            throws UserNotFoundException, LDAPException, TransientException
Dustin Jenkins's avatar
Dustin Jenkins committed
        Filter filter =
                Filter.createEqualityFilter(LDAP_ENTRYDN,
Dustin Jenkins's avatar
Dustin Jenkins committed

        SearchRequest searchRequest =
                new SearchRequest(config.getUsersDN(), SearchScope.ONE,
Dustin Jenkins's avatar
Dustin Jenkins committed

        SearchResultEntry searchResult =
Brian Major's avatar
Brian Major committed
                getReadOnlyConnection().searchForEntry(searchRequest);

        if (searchResult == null)
        {
            logger.debug(msg);
            throw new UserNotFoundException(msg);
        }
Jeff Burke's avatar
Jeff Burke committed
        User<X500Principal> user = new User<X500Principal>(
                new X500Principal(searchResult.getAttributeValue(
Dustin Jenkins's avatar
Dustin Jenkins committed
                        userLdapAttrib.get(X500Principal.class))));
        String princ = searchResult.getAttributeValue(
Dustin Jenkins's avatar
Dustin Jenkins committed
                userLdapAttrib.get(HttpPrincipal.class));
        if (princ != null)
        {
            user.getIdentities().add(new HttpPrincipal(princ));
        }
        String fname = searchResult.getAttributeValue(LDAP_FIRST_NAME);
        String lname = searchResult.getAttributeValue(LDAP_LAST_NAME);
        user.details.add(new PersonalDetails(fname, lname));
        return user;
    }

    DN getUserDN(User<? extends Principal> user)
Dustin Jenkins's avatar
Dustin Jenkins committed
            throws UserNotFoundException, TransientException
        String searchField = userLdapAttrib.get(user.getUserID().getClass());
        if (searchField == null)
        {
Jeff Burke's avatar
Jeff Burke committed
            throw new IllegalArgumentException(
                    "Unsupported principal type " + user.getUserID().getClass());
        // change the DN to be in the 'java' format
        if (user.getUserID() instanceof X500Principal)
        {
            X500Principal orderedPrincipal = AuthenticationUtil.getOrderedForm(
                (X500Principal) user.getUserID());
            filter = Filter.createEqualityFilter(searchField, orderedPrincipal.toString());
            filter = Filter.createEqualityFilter(searchField, user.getUserID().getName());
        SearchResultEntry searchResult = null;
        try
        {
            SearchRequest searchRequest = new SearchRequest(
                config.getUsersDN(), SearchScope.ONE, filter, LDAP_ENTRYDN);
Brian Major's avatar
Brian Major committed
            searchResult = getReadOnlyConnection().searchForEntry(searchRequest);
Dustin Jenkins's avatar
Dustin Jenkins committed
        }
        catch (LDAPException e)
            LdapDAO.checkLdapResult(e.getResultCode());
        if (searchResult == null)
        {
            String msg = "User not found " + user.getUserID().getName();
            logger.debug(msg);
            throw new UserNotFoundException(msg);
        }
        return searchResult.getAttributeValueAsDN(LDAP_ENTRYDN);
    }
    protected DN getUserDN(final String userID, final String usersDN)
            throws LDAPException, TransientException
            return new DN(LDAP_UID + "=" + userID + "," + usersDN);
        }
        catch (LDAPException e)
        {
            logger.debug("getUserDN Exception: " + e, e);
            LdapDAO.checkLdapResult(e.getResultCode());
        }
        throw new IllegalArgumentException(userID + " not a valid user ID");
    }
    private void addAttribute(List<Attribute> attributes, final String name, final String value)
    {
        if (value != null && !value.isEmpty())
        {
            attributes.add(new Attribute(name, value));
        }
    private void addModification(List<Modification> mods, final String name, final String value)
    {
        if (value != null && !value.isEmpty())
        {
            mods.add(new Modification(ModificationType.REPLACE, name, value));
        }
        else
        {
            mods.add(new Modification(ModificationType.REPLACE, name));
        }
    }

    /**
     * Checks the Ldap result code, and if the result is not SUCCESS,
     * throws an appropriate exception. This is the place to decide on
     * mapping between ldap errors and exception types
     *
     * @param code The code returned from an LDAP request.
     * @throws TransientException
     * @throws UserAlreadyExistsException
     */
    protected static void checkUserLDAPResult(final ResultCode code)
            throws TransientException, UserAlreadyExistsException
    {
        if (code == ResultCode.ENTRY_ALREADY_EXISTS)
        {
            throw new UserAlreadyExistsException("User already exists.");
        }
        else
        {
            LdapDAO.checkLdapResult(code);
        }
    }
     * Method to return a randomly generated user numeric ID. The default
     * implementation returns a value between 10000 and Integer.MAX_VALUE.
     * Services that support a different mechanism for generating numeric
     * @return
     */
    protected int genNextNumericId()
    {
        Random rand = new Random();
        return rand.nextInt(Integer.MAX_VALUE - 10000) + 10000;
    }