有一段时间我一直试图通过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]。 一个或多个必需属性可能丢失或不正确,或者您无权在服务器上执行此操作。
有什么想法吗?
答案 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>