是否可以通过cfldap更改密码?

时间:2014-04-24 12:44:22

标签: coldfusion ldap

有一段时间我一直试图通过cfldap更改密码。连接通过SSL和端口636(cfssl_basic)进行,在登录时进行测试。我尝试了以下版本的代码:

<cfset password_new_retyp=charsetEncode(charsetDecode('"'&password_new_retyp&'"','UTF-16LE'),'UTF-8'))>
<!---encoded, decoded password --->
<cfldap action="modify"
    dn="#session.dn_addres#" --- i query this on login
    modifyType="replace"
    attributes="unicodePwd=#password_new_retyp#"
    server="xxxx.xxxx.xxx.xx" --- name of server thet i use on login
    secure = "cfssl_basic" 
    port=636
    username="#session.username#" ---username thet is used on login
    password="#password_old#">  ---- pass before changing

并且错误是这样的:

  

尝试执行查询时发生错误:[LDAP:错误代码49 - 80090308:LdapErr:DSID-0C0903C5,注释:AcceptSecurityContext错误,数据52e,v23f0]。

我也尝试过这种方法而不用编码密码:

<cfldap action="modify"
    dn="#session.dn_addres#"
    modifyType="replace"
    attributes="password=#password_new_retyp#"
    server="xxxx.xxxx.xxx.xx"
    secure = "cfssl_basic"
    port=636
    username="#session.username#"
    password="#password_old#" >

和eror是一样的:

  

尝试执行查询时发生错误:[LDAP:错误代码49 - 80090308:LdapErr:DSID-0C0903C5,注释:AcceptSecurityContext错误,数据52e,v23f0]。   一个或多个必需属性可能丢失或不正确,或者您无权在服务器上执行此操作。

有什么想法吗?

1 个答案:

答案 0 :(得分:4)

这是漫长而艰难的道路,但我到了那里。我希望这有助于其他任何人尝试更改密码并实施LDAP密码策略。

来源:基于爱德华史密斯在archived CFTalk thread

中的代码
<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 varibles
        newPassword = '"#newPassword#"';
        oldPassword = '"#currentPassword#"';
        // You would probably pass in a variable here, I typed it out so you would ss the format its expecting
        distinguishedName = "CN=theUser,OU=someOU,DC=DDDD,DC=CCC,DC=AAA,DC=ZZZ";
        newUnicodePassword = newPassword.getBytes("UnicodeLittleUnmarked");
        oldUnicodePassword = oldPassword.getBytes("UnicodeLittleUnmarked");
        ldapsURL = "ldap://#ldapServer#:#ldapPort#";

        // 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>