0

I am using Delphi 10.3 and IPWorks LDAP component. I can modify most attributes without any issues, such as unicodePwd, givenName, and mail. However, for the userAccountControl attribute of a user, I am unable to set ADS_UF_PASSWD_CANT_CHANGE, of course after successfully binding as an administrator with secure connection and supplying correct DN, because if the connection is not secure, it is impossible to modify the password:

const
  ADS_UF_NORMAL_ACCOUNT = 512;
  ADS_UF_DONT_EXPIRE_PASSWD = 65536;
  ADS_UF_PASSWD_CANT_CHANGE = 64;
  ADS_UF_LOCKOUT = 16;

ipaLDAP1.DN := searchResultDN;
ipaLDAP1.AttrCount := 1;
ipaLDAP1.AttrType[0] := 'userAccountControl';
ipaLDAP1.AttrValue[0] := IntToStr(ADS_UF_NORMAL_ACCOUNT + ADS_UF_DONT_EXPIRE_PASSWD + ADS_UF_LOCKOUT + ADS_UF_PASSWD_CANT_CHANGE);
ipaLDAP1.AttrModOp[0] := amoReplace;

ipaLDAP1.Modify();

It is strange that I can not modify ADS_UF_PASSWD_CANT_CHANGE. It doesn't take effect on the user. When I check the user, this attribute is still unchecked. I don't understand why.

4

1 回答 1

0

userAccountControl是位掩码,因此您应该使用or运算符来组合标志,而不是+运算符。

但是,更重要的是,根据如何使用 UserAccountControl 标志来操作用户帐户属性

PASSWD_CANT_CHANGE
注意:您不能通过直接修改 UserAccountControl 属性来分配此权限。有关如何以编程方式设置权限的信息,请参阅“属性标志说明”部分。

“属性标志描述”部分说:

该页面反过来说:

用户更改自己密码的能力是可以授予或拒绝的权限。要拒绝此权限,请在具有 ADS_ACETYPE_ACCESS_DENIED_OBJECT ace 类型的用户对象的安全描述符自由访问控制列表 (DACL) 中设置两个 ACE。一个 ACE 拒绝授予用户权限,另一个 ACE 拒绝授予 Everyone 组权限。两个 ACE 都是特定于对象的拒绝 ACE,它们指定更改密码的扩展权限的 GUID。要授予此权限,请使用 ADS_ACETYPE_ACCESS_ALLOWED_OBJECT ace type 设置相同的 ACE

以下过程描述了如何修改或添加此权限的 ACE。

修改或添加此权限的 ACE

  1. 绑定到用户对象。

  2. IADsSecurityDescriptorntSecurityDescriptor用户对象的属性中获取对象。

  3. 从属性中获取IADsAccessControlList安全描述符的接口。IADsSecurityDescriptor.DiscretionaryAcl

  4. 枚举对象的 ACE,并搜索具有属性更改密码 GUID ( {AB721A53-1E2F-11D0-9819-00AA0040529B}) 和IADsAccessControlEntry.ObjectType属性“Everyone”或“NT AUTHORITY\SELF”的 ACE IADsAccessControlEntry.Trustee

    注意:“Everyone”和“NT AUTHORITY\SELF”字符串根据域中第一个域控制器的语言进行本地化。因此,不应直接使用字符串。帐户名称应在运行时通过调用LookupAccountSid具有“Everyone”(“S-1-1-0”)和“NT AUTHORITY\SELF”(“S-1-5-10”)的 SID 的函数来获取- 已知的安全主体。阅读用户无法更改密码(LDAP 提供程序)中显示的GetSidAccountNameGetSidAccountName_EveryoneGetSidAccountName_SelfC++ 示例函数演示了如何执行此操作。

  5. 如果用户无法更改密码或用户可以更改密码,请修改IADsAccessControlEntry.AceType找到的 ACE 的属性。ADS_ACETYPE_ACCESS_DENIED_OBJECTADS_ACETYPE_ACCESS_ALLOWED_OBJECT

  6. 如果未找到“Everyone”ACE,请创建一个IADsAccessControlEntry包含下表中显示的属性值的新对象,并使用该IADsAccessControlList.AddAce方法将新条目添加到 ACL。

  7. 如果未找到“NT AUTHORITY\SELF”ACE,则IADsAccessControlEntry使用下表中所示的相同属性值创建一个新对象,但 Trustee 属性包含 SID“S-1-5-10”的帐户名称(“NT AUTHORITY \自己”)。使用该方法将条目添加到 ACL IADsAccessControlList.AddAce

  8. 要更新ntSecurityDescriptor对象的属性,请调用与步骤 2IADs.Put中相同的方法。IADsSecurityDescriptor

  9. 使用该方法将本地更改提交到服务器IADs.SetInfo

  10. 如果创建了任一 ACE,则必须重新排序 ACL,以便 ACE 的顺序正确。为此,请GetNamedSecurityInfo使用对象的 LDAP ADsPath 调用该函数,然后SetNamedSecurityInfo使用相同的 DACL 调用该函数。添加 ACE 时,将自动进行此重新排序。

下表列出了IADsAccessControlEntry对象属性值。

AccessMask
ADS_RIGHT_DS_CONTROL_ACCESS

AceType
ADS_ACETYPE_ACCESS_DENIED_OBJECT如果用户无法更改密码或ADS_ACETYPE_ACCESS_ALLOWED_OBJECT用户可以更改密码。

AceFlags
0

Flags
ADS_FLAG_OBJECT_TYPE_PRESENT

ObjectType
“{AB721A53-1E2F-11D0-9819-00AA0040529B}”是字符串形式的更改密码 GUID。

InheritedObjectType
不曾用过

Trustee
SID“S-1-1-0”(所有人)的帐户名称。

同一页面上提供了一个相当长的代码示例。

于 2020-04-18T02:07:18.743 回答