5

I have created a drop down using CFLDAP. The drop down is the users name for which I will allow a password unlock and reset to occur.

<div id="DESDD" class="form-group" style="display:none;">
                    <select name="DES" id="DES" class="form-control">
                        <option value="" selected>Please select user</option>
                        <cfoutput query="CreateDESDropdown">
                            <option value="#samaccountname#">#cn#</option>
                        </cfoutput>
                    </select>
                </div>

<div id="pass" class="form-group" style="display:none;">
                    <input type="password" name="user_pass" id="user_pass" class="form-control" placeholder="Password" required="">
                </div>
                <div id="sub" class="form-group" style="display:none;">
                    <button type="submit" name="login_user" class="btn btn-primary block full-width m-b">Reset</button>
                </div>

I am stuck here I cannot figure out how to have the user select there name and be able to type in a new password and have it change there password in active directory upon submit.

So basically I have a log in page that only allows managers in. Then it bring them to this page which is a dropdown of names and password input textbox. With a reset submit button. Will someone please tell me how i can allow the user to choose a name from the drop down then just type a password in and have it reset up submitting?

I cannot figure out how to go on from here.

(Apparently posting an image on here is broken) enter image description here

What I have tried:

<cftry>
    <cfscript>
        // You are going to use  the user's credentials to login to LDAP
        // Assuming your LDAP is set up to do so

        // Set up variables
        newPassword = '"thenewpassword!"';
        oldPassword = '"oldpassword"';
        // You would probably pass in a variable here, I typed it out so you would ss the format its expecting
        newUnicodePassword = newPassword.getBytes("UnicodeLittleUnmarked");
        oldUnicodePassword = oldPassword.getBytes("UnicodeLittleUnmarked");
        ldapsURL = "servername:portnumber";

        // Create a Java Hashtable
        javaEnv = CreateObject("java", "java.util.Hashtable").Init();

        // Put stuff in the Hashtable
        javaEnv.put("java.naming.provider.url", ldapsURL);
        // The user's Full DN and Password
        javaEnv.put("java.naming.security.principal", "#distinguishedName#");
        javaEnv.put("java.naming.security.credentials", "#currentPassword#");
        javaEnv.put("java.naming.security.authentication", "simple");
        javaEnv.put("java.naming.security.protocol", "ssl");
        javaEnv.put("java.naming.factory.initial", "com.sun.jndi.ldap.LdapCtxFactory");

        // Create a Java InitialDirContext
        javaCtx = CreateObject("java", "javax.naming.directory.InitialDirContext").Init(javaEnv);

        // Create two Java BasicAttributes
        oldBA = CreateObject("java", "javax.naming.directory.BasicAttribute").Init("unicodePwd", oldUnicodePassword);
        newBA = CreateObject("java", "javax.naming.directory.BasicAttribute").Init("unicodePwd", newUnicodePassword);

        /***********************************************
        *   Stick the attributes into an Java Array and tell it what to do with them
        *   Guess what? A CF Array = a Java Array
        *   1 = DirContext.ADD_ATTRIBUTE
        *   2 = DirContext.REPLACE_ATTRIBUTE
        *   3 = DirContext.REMOVE_ATTRIBUTE
        *  This is the big trick 
        *   If you login above as an admin then you only need to do a 2 Replace but will not run LDAP passoword policy (lenght, complexity, history... etc.)
        *       It will let you change password to anything
        *   If you want to check the LDAP password policy then you need to create the array and first Remove (3) then Add (1)
        *       Error Code 19 means something in the LDAP password policy was violated
        *           I haven't figured out how to read what the error is (like "password length too short" or "you have used this password in the past")
        *       Error Code 49 means invalid username/password
        ************************************************/
        mods = [
            createObject( "java", "javax.naming.directory.ModificationItem").init(3, oldBA),
            createObject( "java", "javax.naming.directory.ModificationItem").init(1, newBA)
        ]; 
        // Run it
        javaCtx.modifyAttributes(distinguishedName,mods);
        javaCtx.close();
    </cfscript>
    // Yeah! I could have scripted the cfcatch but this was easier.
    <cfcatch>
        <cfif find('error code 19',cfcatch.message)>
            <!--- I am using cfwheels so this just displays a nice error message on the next page --->
            <cfset flashInsert(error="New password does not meet requirements defined in the password rules.")>
        <cfelseif isDefined('cfcatch.RootCause.cause.Explanation') and find('error code 49', cfcatch.RootCause.cause.Explanation)>
            <!--- I am using cfwheels so this just displays a nice error message on the next page --->
            <cfset flashInsert(error="Current Password IS incorrect.")>
        <cfelse>    
            <!--- This just pukes the error up hard and uncaught --->
            <cfrethrow>
        </cfif>
        <cfset hasError = true>
    </cfcatch>  
</cftry>

And:

<cfset new_password = '"thenewpassword"' />
<cfset unicodePwd = new_password.getBytes("UnicodeLittleUnmarked") />

<cfset javaEnv = CreateObject("java", "java.util.Hashtable").Init() />

<cfset ldapsURL = "servername:serverport" />
<cfset javaEnv.put("java.naming.provider.url", ldapsURL) />
<cfset javaEnv.put("java.naming.security.credentials", "oldpassword") />
<cfset javaEnv.put("java.naming.security.authentication", "simple") />
<cfset javaEnv.put("java.naming.security.protocol", "ssl") />
<cfset javaEnv.put("java.naming.factory.initial", "com.sun.jndi.ldap.LdapCtxFactory") />

<cfset javaCtx = CreateObject("java", "javax.naming.directory.InitialDirContext").Init(javaEnv) />
<cfset javaAttr = CreateObject("java", "javax.naming.directory.BasicAttributes").Init("unicodePwd", unicodePwd) />


<cfset javaCtx.close() />
David Brierton
  • 6,977
  • 12
  • 47
  • 104
  • About that white screen. Check your error logs . You might see java heap space or garbage collection errors. – Dan Bracuk Feb 11 '17 at 03:42
  • Different sites I found about it but can not get it to work on my end. https://groups.yahoo.com/neo/groups/CFTalk/conversations/topics/160110 http://macromedia.coldfusion.advanced-techniques.narkive.com/GL9wk7C7/cfldap-ad-password-reset http://stackoverflow.com/questions/23269273/is-it-possible-to-change-the-password-via-cfldap – David Brierton Feb 13 '17 at 18:29
  • It is difficult to discern exactly what you are having trouble with. Perhaps it would help to explain how that code you have tried is not working as you expected. Are you receiving any errors? Etc. – Miguel-F Feb 13 '17 at 19:12
  • @Miguel-F I am only getting a white screen. For some reason things dont work and always just show me a white screen... I am very new to coding. I try writing try and catches but still just all white. Iv read about creating an ssl connection but im not sure how to do that or why I would need too. Do you know what I am trying to do? I have a dropdown coming in from a cfldap for the user to select a name. Now i have a textbox for a new password to be entered. Upon submit I want to update the password in active directory for the user chosen in the dropdown. Do you know how to do this? – David Brierton Feb 14 '17 at 13:22
  • just not sure what ouputfile does – David Brierton Feb 14 '17 at 14:01
  • Yes, that is one way to do it. The `outputfile` attribute tells ColdFusion to write any output generated by the command to the file name you specify. So there will be no output to the screen, output is redirected to the file name. What happened when you tried that command? Your ColdFusion service user will need rights to execute that command as well. – Miguel-F Feb 14 '17 at 14:08
  • nothing happens lol just a white screen and nothing to the file – David Brierton Feb 14 '17 at 14:38
  • errr so frustrating – David Brierton Feb 14 '17 at 14:38
  • i put my credentials didnt have the variables and nothing happened – David Brierton Feb 14 '17 at 14:39
  • @Miguel-F do you have time to chat maybe you can help me get this working? – David Brierton Feb 14 '17 at 15:23
  • @Miguel-F System error 5 has occured Access is denied. means? http://stackoverflow.com/questions/42230379/net-use-in-cmd-prompt-system-error-5 – David Brierton Feb 14 '17 at 15:53
  • 1
    @DanBracuk how do I assign the user cfexecute runs as? – David Brierton Feb 14 '17 at 19:05
  • I´ve recently implemented a "resetPassword" routine for a customer. Some points you should check: 1) You don´t need to supply the old password in the modify request 2) The new password must be encoded in UTF-16LE and also must include double quotation marks (you´re doing this, already) 3) In order to unlock an account account you must also modify the "userAccountControl" attribute – Philippe Sevestre Feb 20 '17 at 14:36
  • @PhilippeSevestre want to share some guidance of how to do this? Iv been trying to figure it out for weeks :( http://stackoverflow.com/questions/42234407/cfexecute-assigning-it-to-run-with-administrator-rights – David Brierton Feb 21 '17 at 16:19
  • Hi, the Java code I use to change someone´s password goes like this: Attribute attrPwd = new BasicAttribute("unicodePwd", ('"' + plainTextPassword + '"').getBytes("UTF-16LE"); Attribute attrAcc = new BasicAttribute("userAccountControl", "512"); ModificationItem[] mods = new ModificationItem[] { new ModificationItem(DirContext.REPLACE_ATTRIBUTE,attrPwd), new ModificationItem(DirContext.REPLACE_ATTRIBUTE,attrAcc), }; ctx.modifyAttributes(name, mods); Key point: I use "account operator" credentials in order to connect to AD. This connection MUST use SSL. – Philippe Sevestre Feb 22 '17 at 19:06
  • Google "Jespa". The jespa.ldap.LdapAccount.setPassword method would make easy work of something like this. Also SSL is not required because Jespa uses NTLM session security by default (just like a real Windows client would). – squarewav Feb 28 '17 at 16:39

0 Answers0