You are here

Programmatically Change Password

Submitted by wyseguyCO on Mon, 08/31/2009 - 15:18

Has anyone been able to programmatically update a user's password in Luminis?

The reason for my request is that we are in the process of determining the feasibility of using an independent clone of our Luminis LDAP as an authenticating source to set up our same sign-on.  Part of this project will be creating a password self-service site that will allow users to update their passwords for SSB, D2L, and as many other web applications as we can get to authenticate against our cloned LDAP.  We cannot use the internal password mechanisms because we're limited by the fact that we're in the middle of a 13 institution deployment of the portal and not every institution is ready to use the portal.

Luminis Version:

You can do this "quite easily" using the Data Access SDK - provided you have the current password in plain text too.

This should get you started...

import com.sct.pipeline.da.*;

...
...
...


public boolean updatePassword(
    String UserId,
    String currentPassword,
    String newPassword   ){

    // Some defaults
    boolean returnValue = false;
    PasswordModification passwordModification = null;

    if (currentPassword != null && newPassword != null)
    {
        // *** Add your minimum password strength requirements here

        // If the password is to be changed
        if (currentPassword.equals(newPassword))
        {
            // _logger.info("Password change error: New password == Current password");
        }
        else
        {
            // Passwords are different       
            // _logger.debug("Attempting to change password...");
           
            PasswordPair passwordPair = new PasswordPair();
            passwordPair.setCurrentPassword(currentPassword);
            passwordPair.setNewPassword(newPassword);

            passwordModification = new PasswordModification(
                "PASSWORD",
                passwordPair,
                ModOperationTypeEnum.REPLACE
            );

            Modification[] userModifications = new Modification[1] ;
            userModifications[0] =  passwordModification;

            ModifyParams modifyParams =  new ModifyParams();
            modifyParams.setBoId( new BOID( BusinessObjectTypeEnum.USER, userId));
            modifyParams.setModifications(userModifications);

            try
            {
                svc.modify(modifyParams);
                // _logger.info(new StringBuffer().append("User modified: ").append(userId) );

                returnValue = true;
            }
            catch (Exception e)
            {
                /*
                _logger.error(new StringBuffer().append("User modification failed: ")
                    .append(userId)
                    .append(e.getMessage()).toString()
                );
                */
            }
        }
    }
       
    return returnValue;
}

I've adapted it from some code I wrote several years ago that's running on our production box.  Can't guarantee the syntax is exactly right though.

Thanks for the code, its given me a couple ideas for how to proceed.  Unfortunately, I'm developing a password update tool and at the point where I need to encrypt and store the new password, the user has established their identity through a challenge question and providing their Banner ID.  At this point in the process, it is assumed the user is not in possession of their existing password.

I've done some research into using the Java classes that do encryption (specifically the Cipher class).  It is my hope that if I can get the correct algorithm and encryption key for our Luminis install that I'll be able to update the LDAP with the new password.

The solution is to not worry about the encryption of the password.  Instead, just modify the LDAP entry using the Java DirContext and ModificationItem classes to update the password.  Luminis' LDAP will automatically encrypt the password prior to storing it using its own internal mechanisms.

Hi Jonathan,
Did you have to deal with the stored secret?
Per SDK's document the PasswordPair handles the secretstore. However, I am running into a problem: if I connect to the DA webservice as luminis admin user then I can change the user's password but it will not update the stored secret. But if I connect to the DA webservice as the same user (which I should) the code did not work and give me some errors as below:
[INFO] JAXRPCService - -Service class com.sct.pipeline.da.Da_Impl implements service {urn:pipeline.sct.com:webservice:da:200306:soap}da
DAExecption caught: com.sct.pipeline.da.DAException: Server error; [1254935660138] password reset failed; com.pipeline.security.authen.NotYetAuthenticatedException: [BASE, A wrapper exception, Subject Subject: [uid=541778237991171,ou=People,o=usfca.edu,o=usfca.edu hashcode=1801965311 static id=541778237991171] Credentials for [cn=SecretStoreService,ou=SecretStore,ou=Services,o=usfca.edu,o=usfca.edu, cn=UserSessionManager,ou=Services,o=usfca.edu,o=usfca.edu, cn=DirectoryService,ou=Services,o=usfca.edu,o=usfca.edu, cn=HttpAuthenticator,ou=Services,o=Campus, cn=EmailService,ou=Services,o=usfca.edu,o=usfca.edu, cn=CalendarService,ou=Services]Subject:
    Principal: com.sct.security.User@e2d2fe "uid=541778237991171,ou=People,o=usfca.edu,o=usfca.edu"
    Principal: [ com.pipeline.security.authz.uportal.User 541778237991171 ]
    Principal: [ com.pipeline.security.authz.uportal.Group filter.162 ]
    Principal: [ com.pipeline.security.authz.uportal.Group sct.public ]
    Principal: [ com.pipeline.security.authz.uportal.Group sct.faculty ]
    Principal: [ com.pipeline.security.authz.uportal.Group filter.148 ]
    Principal: [ com.pipeline.security.authz.uportal.Group filter.114 ]
    Principal: [ com.pipeline.security.authz.uportal.Group filter.117 ]
    Principal: [ com.pipeline.security.authz.uportal.Group filter.107 ]
    Principal: [ com.pipeline.security.authz.uportal.Group filter.115 ]
    Principal: [ com.pipeline.security.authz.uportal.Group filter.135 ]
    Principal: [ com.pipeline.security.authz.uportal.Group filter.113 ]
    Principal: [ com.pipeline.security.authz.uportal.Group filter.109 ]
    Principal: [ com.pipeline.security.authz.uportal.Group filter.104 ]
    Principal: [ com.pipeline.security.authz.uportal.Group filter.105 ]
    Principal: [ com.pipeline.security.authz.uportal.Group filter.134 ]
    Principal: [ com.pipeline.security.authz.uportal.Group filter.126 ]
    Principal: [ com.pipeline.security.authz.uportal.Group filter.154 ]
    Principal: [ com.pipeline.security.authz.uportal.Group filter.133 ]
    Principal: [ com.pipeline.security.authz.uportal.Group filter.155 ]
    Principal: [ com.pipeline.security.authz.uportal.Group sct.Student ]
    Principal: [ com.pipeline.security.authz.uportal.Group filter.120 ]
    Principal: [ com.pipeline.security.authz.uportal.Group filter.106 ]
    Principal: [ com.pipeline.security.authz.uportal.Group filter.153 ]
    Principal: [ com.pipeline.security.authz.uportal.Group filter.112 ]
    Principal: [ com.pipeline.security.authz.uportal.Group pags.UPD_85 ]
    Principal: [ com.pipeline.security.authz.uportal.Group filter.125 ]
    Principal: [ com.pipeline.security.authz.uportal.Group filter.118 ]
    Principal: [ com.pipeline.security.authz.uportal.Group filter.108 ]
    Principal: [ com.pipeline.security.authz.uportal.Group filter.122 ]
    Principal: [ com.pipeline.security.authz.uportal.Group filter.121 ]
    Principal: [ com.pipeline.security.authz.uportal.Group filter.119 ]
    Principal: [ com.pipeline.security.authz.uportal.Group filter.103 ]
    Principal: [ com.pipeline.security.authz.uportal.Group filter.123 ]
 is not yet authenticated]
 
You mentioned you used both Java DirContext and ModificationItem. Could you collaborate more on why you need to use both?
Thanks in advance.
 
Thai

We used JDNI.

1. Get the context to your ldap
2. Generate an SSHA hash from the clear text password. Combine "{SSHA}" + base 64 encoding of hash + random salt.
3. Modify the attribute userPassword

Terry

Can you please elaborate?

So by using JNDI, you did not have to use the DA web service correct?

Also, how did you get the ldap context? I know the JNDI context is usually configured in a Tomcat configuration file, like context.xml , but can you be more specific? Where is that ldap context?