ldap3 extend.microsoft.modify_password修改AD密码始终返回false
问题原因
c.extend.microsoft.modify_password 始终返回False是以下几个问题共同导致的:
- 加密连接配置无效:你定义Server时使用
ldap://前缀,同时开启use_ssl=True是不生效的。AD的密码修改操作强制要求走SSL/TLS加密通道,LDAP over SSL必须使用ldaps://前缀对接636端口,你当前的配置没有建立有效加密连接,密码请求会被AD直接丢弃。 - 新建用户默认禁用:调用
add创建用户时没有指定userAccountControl属性,AD对新建无密码用户默认设置该值为546,对应账户禁用状态,禁用状态下不允许设置密码。 - 方法传参错误:
modify_password的签名为modify_password(user_dn, new_password, old_password),如果是管理员执行重置密码操作(不需要验证用户旧密码),必须显式传入old_password=None;省略该参数时库默认走用户自主改密逻辑,要求必须提供正确旧密码,自然会执行失败。 - 对象类配置错误:你给用户对象附加了
posixGroup对象类,该类是为用户组设计的,绑定到用户对象会触发AD的属性schema校验异常,干扰密码操作。 - 密码可能不满足复杂度要求:你使用的测试密码
Formation123仅包含大小写字母和数字,AD默认域密码策略要求密码至少包含三类字符(大写、小写、数字、特殊字符),可能触发复杂度校验失败。
解决方法
按以下步骤调整代码即可:
- 修正LDAP连接配置,使用
ldaps://前缀对接AD的636端口,测试环境如果使用AD自签名证书可配置跳过证书校验,生产环境建议配置正式证书信任。 - 创建用户时移除错误的
posixGroup对象类,先将userAccountControl设为546(合法的禁用状态值,适配无密码的新建用户场景)。 - 调用
modify_password时显式传入old_password=None,明确走管理员重置密码逻辑,密码调整为符合域复杂度要求的格式(比如加一个特殊字符)。 - 密码设置成功后,将
userAccountControl修改为512,启用用户账户。 - 操作失败时直接打印
c.result查看AD返回的具体错误信息,方便快速定位问题(比如权限不足、策略拦截等)。
修正后的可运行参考代码:
from ldap3 import Server, Connection, ALL, Tls, MODIFY_REPLACE import ssl # 测试环境自签名证书用该配置跳过校验,生产环境请替换为正式证书验证逻辑 tls_conf = Tls(validate=ssl.CERT_NONE, version=ssl.PROTOCOL_TLSv1_2) # 注意使用ldaps://前缀,走636加密端口 server = Server("ldaps://192.168.x.xx", use_ssl=True, tls=tls_conf, get_info=ALL) # 管理员账号建议使用「域\用户名」格式或完整DN,避免账号解析失败 conn = Connection(server, user='mjc\\adminldap', password='xxxxxxx', auto_bind=True) user_dn = 'cn=jtest,ou=users,ou=MJC,dc=mjc,dc=lan' # 创建用户,移除错误的posixGroup对象类,初始设置为禁用状态 conn.add( user_dn, ['user', 'top'], { 'cn': 'jtest', 'sAMAccountName':'jtest', 'mail':'jtest@gmail.com', 'telephoneNumber':'0102030405', 'displayName':'jtest', 'userAccountControl': 546 } ) # 管理员重置密码,显式传入old_password=None,密码添加特殊字符满足复杂度要求 reset_ok = conn.extend.microsoft.modify_password(user_dn, 'Formation123!', old_password=None) if reset_ok: # 密码设置成功后启用账户 conn.modify(user_dn, {'userAccountControl': (MODIFY_REPLACE, [512])}) print("用户创建、密码设置、账户启用完成") else: # 打印具体错误信息方便排查 print(f"操作失败,错误详情:{conn.result}")
额外验证点
如果调整后依然报错,逐一检查以下项:
- 确认你使用的管理员账号
adminldap对目标OU有「重置用户密码」的权限 - 确认AD域控的636端口已开放、LDAPS服务已正常启用
- 确认域密码策略没有额外的长度、字符、历史密码限制
内容的提问来源于stack exchange,提问作者Fujah
相关产品推荐
相关产品推荐

