我需要在 Python Web 应用程序(Flask)中实现“更新密码”功能。目标是允许用户在远程 Active Directory 服务器上自行更新他的密码。
我以这个快速单元测试结束
import os
import ldap
def test_change_passwd():
ad_server = "ldaps://ad.xxx_domain.com"
ad_dn = "CN={0},OU=Users,OU=AF,DC=xxx_domain,DC=com"
username = 'my_username'
old_pwd = 'the_old_complicated_password'
new_pwd = 'the_new_complicated_password'
cert = os.path.join('/path', "to", 'server_cert.cer')
# LDAP connection initialization
l = ldap.initialize(ad_server)
# Set LDAP protocol version used
l.protocol_version = ldap.VERSION3
# Force cert validation
l.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_DEMAND)
# Set path name of file containing all trusted CA certificates
l.set_option(ldap.OPT_X_TLS_CACERTFILE, cert)
# Force libldap to create a new SSL context (must be last TLS option!)
l.set_option(ldap.OPT_X_TLS_NEWCTX, 0)
# Bind
l.simple_bind_s(ad_dn.format(username), old_pwd)
# Now, perform the password update
newpwd_utf16 = '"{0}"'.format(new_pwd).encode('utf-16-le')
mod_list = [(ldap.MOD_REPLACE, "unicodePwd", newpwd_utf16)]
l.modify_s(ad_dn.format(username), mod_list)
当我运行它时,它在最后一行 ( l.modify_s()
) 上失败并出现以下错误:
INSUFFICIENT_ACCESS: {'info': u'00000005: SecErr: DSID-031A11D7, problem 4003 (INSUFF_ACCESS_RIGHTS), data 0\n', 'desc': u'Insufficient access'}
我不知道问题是来自我的 python 代码还是我的用户在目录中的错误配置。另外,我不是AD服务器的管理员(对此一无所知)。
我是否需要为我的用户设置一些特殊的东西以允许他自行更新他的密码?我是否使用正确的方法更新密码?
注意:我也尝试过这种方法来更新密码,但没有成功:
l.passwd_s(dn.format(username), old_pwd, new_pwd)
失败并出现错误:
PROTOCOL_ERROR({'info': u'0000203D: LdapErr: DSID-0C0911D4, comment: Unknown extended request OID, data 0, v3839', 'desc': u'Protocol error'},)
我到处读到这个功能不应该与 AD 服务器一起使用......
MS Active Directory 区分了两种不同的用例。
注意:
old_passwd_value
两者new_passwd_value
都必须是奇怪的双引号低端 UTF-16 编码,就像您的代码片段中一样。如果管理员设置了另一个用户的密码,您可以使用您的代码:
mod_list = [ (ldap0.MOD_REPLACE, 'unicodePwd', [new_passwd_value]), ]
如果用户更改自己的密码,您必须使用:
mod_list = [ (ldap0.MOD_DELETE, 'unicodePwd', [old_passwd_value]), (ldap0.MOD_ADD, 'unicodePwd', [new_passwd_value]), ]