1. 主页 > 世界杯2021 >

通过 LDAP 更改 Windows Active Directory 和 LDS 用户密码 - Windows Server

本文介绍如何通过 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\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