本文介绍如何通过 LDAP 更改 Windows Active Directory 和 LDS 用户密码。
适用于: Windows Active Directory
原始 KB 编号: 269190
总结
根据某些限制,可以通过轻型目录访问协议(LDAP)设置 Windows Active Directory 和轻型目录服务 (LDS) 密码。 本文介绍如何设置或更改密码属性。
这些步骤也适用于 Active Directory 应用程序模式(ADAM)和 LDS 用户和 userProxy 对象,其方式与 AD 用户相同。 有关详细信息,请参阅文章末尾的其他提示。
详细信息
密码存储在 AD 和 LDS 数据库中的 unicodePwd 属性中的用户对象上。 此属性可以在受限条件下写入,但无法读取。 只能修改该属性;不能在创建对象时添加它,也不能通过搜索进行查询。
若要修改此属性,客户端必须具有与服务器的 128 位传输层安全性(TLS)/安全套接字层(SSL)连接。 只要满足最小密钥长度,也可以使用使用 Windows 新技术 LAN 管理器(NTLM)或 Kerberos 创建 SSP 的会话密钥的加密会话。
若要使用此连接,可以使用 TLS/SSL:
- 服务器必须拥有 128 位 RSA 连接的服务器证书。
- 客户端必须信任生成服务器证书的证书颁发机构(CA)。
- 客户端和服务器必须能够进行 128 位加密。
unicodePwd 属性的语法为八进制字符串;但是,目录服务需要八进制字符串将包含 UNICODE 字符串(如属性指示的名称)。 这意味着,在 LDAP 中传递的此属性的任何值必须是 BER 编码的 UNICODE 字符串(基本编码规则)作为八进制字符串。 此外,UNICODE 字符串必须以不属于所需密码的引号开头和结尾。
有两种修改 unicodePwd 属性的可能方法。 第一个类似于常规用户更改密码操作。 在这种情况下,修改请求必须同时包含删除和添加操作。 删除操作必须包含当前密码,并带有引号。 添加操作必须包含所需的新密码,其中包含其周围的引号。
修改此属性的第二种方法类似于管理员重置用户的密码。 为此,客户端必须绑定为具有足够权限的用户才能修改其他用户的密码。 此修改请求应包含单个替换操作,其中包含用引号括起来的新所需密码。 如果客户端具有足够的权限,则无论旧密码是什么,此密码都将成为新密码。
以下两个函数提供了这些操作的示例:
ULONG ChangeUserPassword(WCHAR* pszUserDN, WCHAR* pszOldPassword,WCHAR* pszNewPassword)
{
ULONG err = 1;
LDAPMod modNewPassword;
LDAPMod modOldPassword;
LDAPMod *modEntry[3];
BERVAL newPwdBerVal;
BERVAL oldPwdBerVal;
BERVAL *newPwd_attr[2];
BERVAL *oldPwd_attr[2];
WCHAR pszNewPasswordWithQuotes[1024];
WCHAR pszOldPasswordWithQuotes[1024];
// Build an array of LDAPMod.
// For setting unicodePwd, this MUST be a double op.
modEntry[0] = &modOldPassword;
modEntry[1] = &modNewPassword;
modEntry[2] = NULL;
// Build mod struct for unicodePwd Add.
modNewPassword.mod_op = LDAP_MOD_ADD | LDAP_MOD_BVALUES;
modNewPassword.mod_type =L"unicodePwd";
modNewPassword.mod_vals.modv_bvals = newPwd_attr;
// Build mod struct for unicodePwd Delete.
modOldPassword.mod_op = LDAP_MOD_DELETE | LDAP_MOD_BVALUES;
modOldPassword.mod_type =L"unicodePwd";
modOldPassword.mod_vals.modv_bvals = oldPwd_attr;
// Password will be single valued, so we only have one element.
newPwd_attr[0] = &newPwdBerVal;
newPwd_attr[1]= NULL;
oldPwd_attr[0] = &oldPwdBerVal;
oldPwd_attr[1]= NULL;
// Surround the passwords in quotes.
wsprintf(pszNewPasswordWithQuotes,L"\"%s\"",pszNewPassword);
wsprintf(pszOldPasswordWithQuotes,L"\"%s\"",pszOldPassword);
// Build the BER structures with the UNICODE passwords w/quotes.
newPwdBerVal.bv_len = wcslen(pszNewPasswordWithQuotes) * sizeof(WCHAR);
newPwdBerVal.bv_val = (char*)pszNewPasswordWithQuotes;
oldPwdBerVal.bv_len = wcslen(pszOldPasswordWithQuotes) * sizeof(WCHAR);
oldPwdBerVal.bv_val = (char*)pszOldPasswordWithQuotes;
// Perform single modify.
err = ldap_modify_s(ldapConnection,
pszUserDN,
modEntry
);
if (err == LDAP_SUCCESS )
wprintf(L"\nPassword successfully changed!\n");
else
wprintf(L"\nPassword change failed!\n");
return err;
}
ULONG SetUserPassword(WCHAR* pszUserDN, WCHAR* pszPassword)
{
ULONG err = 1;
LDAPMod modPassword;
LDAPMod *modEntry[2];
BERVAL pwdBerVal;
BERVAL *pwd_attr[2];
WCHAR pszPasswordWithQuotes[1024];
// Build an array of LDAPMod.
// For setting unicodePwd, this MUST be a single op.
modEntry[0] = &modPassword;
modEntry[1] = NULL;
// Build mod struct for unicodePwd.
modPassword.mod_op = LDAP_MOD_REPLACE | LDAP_MOD_BVALUES;
modPassword.mod_type =L"unicodePwd";
modPassword.mod_vals.modv_bvals = pwd_attr;
// Password will be single valued, so we only have one element.
pwd_attr[0] = &pwdBerVal;
pwd_attr[1]= NULL;
// Surround the password in quotes.
wsprintf(pszPasswordWithQuotes,L"\"%s\"",pszPassword);
// Build the BER structure with the UNICODE password.
pwdBerVal.bv_len = wcslen(pszPasswordWithQuotes) * sizeof(WCHAR);
pwdBerVal.bv_val = (char*)pszPasswordWithQuotes;
// Perform single modify.
err = ldap_modify_s(ldapConnection,
pszUserDN,
modEntry
);
if (err == LDAP_SUCCESS )
wprintf(L"\nPassword succesfully set!\n");
else
wprintf(L"\nPassword set failed!\n");
return err;
}
提示
- 若要使用 UserProxy 对象配置 LDS 实例以进行密码重置,必须允许将 LDS 服务帐户(默认值:LDS 计算机帐户)约束委派到域控制器,以防用户登录使用 Kerberos。
- 如果使用 LDAP 简单绑定,则必须使用 Windows Server 2022 或更高版本,并设置注册表项以将管理员 LDAP 会话凭据转发到Active Directory 域控制器:
注册表项: HKLM\system\currentcontrolset\services<LDS 实例>\Parameters
注册表项:允许 ClearText 登录类型
类型:REG_DWORD
数据: 0:不允许转发凭据(默认)
1:允许转发密码重置的凭据 - 请注意,这两种情况下的更改都意味着 LDS 服务器应被视为第 0 层设备,因为它可以在域控制器上启动安全敏感任务。
适用于
- Windows Server 2012 Datacenter
- Windows Server 2012 Standard
- Windows Server 2012 R2 Datacenter
- Windows Server 2012 R2 Standard
- Windows Server 2016
- Windows Server 2019
- Windows Server 2022
- Windows 8.1 企业版
- Windows 8.1 专业版
- Windows 10
- Windows 11