You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

勾选“下次登录需改密码”时,如何用ldap3修改AD用户密码?

解决AD用户"下次登录必须改密码"时无法绑定修改密码的问题

当AD用户账号被勾选“下次登录必须更改密码”时,用户无法通过旧密码完成LDAP绑定(错误码773),导致无法用自身连接执行密码修改操作。以下是两种可行的解决方案:

方案1:使用具有权限的服务账号修改密码

这是最稳定的方案,核心思路是用一个拥有重置用户密码权限的AD服务账号先完成LDAP绑定,再通过该连接修改目标用户的密码。

操作步骤

  1. 在AD中创建一个服务账号,并为其赋予目标用户所在OU的“重置密码”权限:

    • 打开AD用户和计算机,找到目标用户所在OU,右键→属性→安全→高级
    • 添加服务账号,在权限列表中勾选“重置密码”,应用设置
  2. 修改代码如下(替换服务账号信息):

from ldap3 import ALL, Connection, Server
from ldap3.core.exceptions import LDAPBindError, LDAPOperationResult

# 解析UAC值的函数(避免使用内置函数名sum作为参数)
def Calc(arr, sum_val):
    ds = sum_val
    res = []
    tt = arr
    donee = True
    a = 0
    while donee:
        a = 0
        for i in tt:
            if i == ds:
                res.append(i)
                ds = 0
            if i > ds:
                break
            a += 1
        if ds == 0:
            donee = False
            break
        tt = tt[0:a]
        ds = ds - tt[a-1]
        if ds < 0:
            break
        res.append(tt[a-1])
    return res

uac_val = [1,2,8,16,32,64,128,256,512,2048,4096,8192,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216,67108864]

# LDAP服务器配置
ldsp_server = f"ldaps://192.168.16.130"
root_dn = "dc=DOMAIN,dc=com"

# 目标用户信息
ldap_user_name = 'user1'
ldap_password = 'OldPassword'
user_dn = f'cn={ldap_user_name},cn=Users,{root_dn}'

# 服务账号信息(需拥有重置密码权限)
service_user_dn = 'cn=ADServiceAccount,cn=Users,dc=DOMAIN,dc=com'
service_user_pwd = 'ServiceAccountPassword'

try:
    server = Server(ldsp_server, get_info=ALL, use_ssl=True)
    # 先尝试用用户自身凭证绑定
    conn = Connection(server, user=user_dn, password=ldap_password)
    
    if not conn.bind():
        print(conn.result)
        err = str(conn.result).split("data")[1].split(',')[0].strip()
        
        if err == "773":
            print(f"{ldap_user_name}的密码需在下次登录时修改")
            newpass = input("请输入新密码: ")
            # 用服务账号建立连接
            service_conn = Connection(server, user=service_user_dn, password=service_user_pwd)
            if service_conn.bind():
                # 执行密码修改
                change_success = service_conn.extend.microsoft.modify_password(user_dn, newpass)
                if change_success:
                    print("密码修改成功!")
                else:
                    print("密码修改失败:", service_conn.result)
                service_conn.unbind()
            else:
                print("服务账号绑定失败,无法修改密码:", service_conn.result)
        else:
            print("绑定失败原因:", conn.result)
        conn.unbind()
        exit(0)
    else:
        print("成功绑定LDAP服务器")
        print(f"查询用户: DOMAIN/{ldap_user_name}")
        
        # 直接通过entry属性获取值,避免字符串分割的不可靠性
        if conn.search(user_dn, '(objectClass=user)', attributes=['userAccountControl', 'pwdLastSet']):
            entry = conn.entries[0]
            print(entry)
            uac_value = entry.userAccountControl.value
            pwd_last_set = entry.pwdLastSet.value
            print("上次密码修改日期:", pwd_last_set)
            print("UAC值:", uac_value)
            uac_flags = Calc(uac_val, uac_value)
            if 65536 in uac_flags:
                print("该用户密码永不过期!")
        else:
            print("获取用户详情失败")
        conn.unbind()
        exit(0)

except (LDAPBindError, LDAPOperationResult) as e:
    print("绑定失败错误:", conn.result)
    if 'conn' in locals():
        conn.unbind()
    exit(0)

方案2:尝试用未绑定连接修改密码(兼容性有限)

部分AD环境允许用户在绑定失败返回773的情况下,直接使用未认证的连接执行密码修改操作。可以尝试修改原代码,去掉exit(0),直接在bind失败后调用修改方法,但这种方式不保证在所有AD环境下生效:

# 原代码中773分支修改为:
if err == "773" :
    print(f"{ldap_user_name}的密码需在下次登录时修改")
    newpass = input("请输入新密码: ")
    # 直接使用当前未绑定的连接尝试修改
    ii = conn.extend.microsoft.modify_password(user, newpass)
    print(ii)
    if ii:
        print("密码修改成功!")
    else:
        print("密码修改失败!")
    # 不要立即exit,后续可以尝试重新绑定

关键注意事项

  • 原代码中使用sum作为函数参数,这是Python内置函数名,容易引发冲突,建议改为sum_val
  • 原代码通过字符串分割解析用户属性的方式不可靠,直接使用entry.属性名.value是更稳定的做法
  • 服务账号的权限必须配置正确,否则无法完成密码修改操作

内容的提问来源于stack exchange,提问作者therealdanish

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 10:45:32