设置对象访问权限

在使用 ADSI COM 对象 IADsSecurityDescriptor(安全描述符)、IADsAccessControlList(DACL 和 SACL)和 IADsAccessControlEntry (ACE) 向 ACL 添加 ACE 时,需要对属性缓存中指定对象的 nTSecurityDescriptor 属性进行更改。 这意味着必须调用包含新 ACE 的对象上的 put 方法以及 IADs.SetInfo 方法,以便将更新的安全描述符从属性缓存写入目录。

有关在 Active Directory 域服务中的对象上设置 ACE 的更多信息和代码示例,请参阅在 Directory 对象上设置 ACE 的示例代码

使用以下常规流程为访问权限创建 ACE,并在对象的 DACL 上设置 ACE。

  1. 获取指向该对象的 IADs 接口指针。

  2. 使用 IADs.Get 方法获取对象的安全描述符。 包含此安全描述符的属性的名称为 nTSecurityDescriptor。 属性将以 VARIANT 的形式返回,其中包含一个 IDispatch 指针(vt 成员是 VT_DISPATCH)。 在该 IDispatch 指针上调用 QueryInterface 以获得 IADsSecurityDescriptor 接口,从而使用该接口上的方法来访问安全描述符的 ACL。

  3. 使用 IADsSecurityDescriptor.DiscretionaryAcl 属性来获取 DACL。 该方法会返回一个 IDispatch 指针。 在 IDispatch 指针上调用 QueryInterface 以获得 IADsAccessControlList 接口,从而使用该接口上的方法来访问 ACL 中的单个 ACE。

  4. 使用 CoCreateInstance 为新 ACE 创建 ADSI COM 对象,并获取指向该对象的 IADsAccessControlEntry 接口指针。 请注意,类 ID 为 CLSID_AccessControlEntry。

  5. 使用 IADsAccessControlEntry 方法来设置 ACE 的属性:

    1. 使用 IADsAccessControlEntry::put_Trustee 设置此 ACE 适用的受托方。 受托方为用户、组或其他安全主体。 应用程序应使用向其应用 ACE 的受托方的用户或组对象的相应属性中的值。 受托方以 BSTR 的形式指定,包括以下几种形式:
      • 域帐户(Windows NT 以前版本中使用的登录名),格式为“<domain>\<user account>”,其中“<domain>”是包含用户的 Windows NT 域的名称,而“<user account>”是指定用户的 sAMAccountName 属性。 例如:“fabrikam\jeffsmith”。
      • 众所周知的安全主体,代表 Windows NT 安全系统定义的特殊身份,例如每个人、本地系统、主体自己、通过身份验证的用户、创建者所有者等。 表示已知安全主体的对象存储在“配置”容器下的“已知安全主体”容器中。 例如,匿名登录。
      • 表示由 Windows NT 安全系统定义的内置用户组的内置组。 其格式为“BUILTIN\<group name>”,其中“<group name>“是内置用户组的名称。 表示内置组的对象存储在域容器下的内置容器中。 例如,“BUILTIN\Administrators”。
      • 指定用户的 SID(字符串格式),即指定用户的 objectSID 属性。 可以使用 Win32 安全性 API 中的 ConvertSidToStringSid 函数将其转换为字符串形式。 例如:“S-1-5-32-548”。
    2. 使用 IADsAccessControlEntry.AccessMask 属性设置指定访问权限的掩码。 ADS_RIGHTS_ENUM 枚举指定了可以在 Directory 对象上设置的访问权限。
    3. 使用 IADsAccessControlEntry.AceType 属性指定允许还是拒绝 AccessMask 设置的访问权限。 对于标准权限,可以是 ADS_ACETYPE_ACCESS_ALLOWEDADS_ACETYPE_ACCESS_DENIED。 对于特定于对象的权限(适用于对象的特定部分或特定类型对象的权限),请使用 ADS_ACETYPE_ACCESS_ALLOWED_OBJECTADS_ACETYPE_ACCESS_DENIED_OBJECTADS_ACETYPE_ENUM枚举指定了可以在 ACE 上设置的访问类型。
    4. 使用 IADsAccessControlEntry.AceFlags 属性来指定指定对象下面的其他容器或对象是否可以继承 ACE。 ADS_ACEFLAG_ENUM 枚举指定了可以在 ACE 上设置的继承标志。
    5. 使用 IADsAccessControlEntry.Flags 属性来指定该权利是否适用于对象的特定部分、继承的对象类型或两者。
    6. 如果 Flags 设置为 ADS_FLAG_OBJECT_TYPE_PRESENT,则设置 IADsAccessControlEntry.ObjectType 属性以指定一个字符串,其中包含 ACE 所适用的对象类(ADS_RIGHT_DS_CREATE_CHILDADS_RIGHT_DS_DELETE_CHILD)、属性、属性集、验证写入或 ACE 适用的扩展权限。 GUID 必须指定为 COM 库中 StringFromGUID2 函数生成的字符串形式。
    7. 如果 Flags 设置为 ADS_FLAG_INHERITED_OBJECT_TYPE_PRESENT,则应设置 IADsAccessControlEntry.InheritedObjectType 属性,以指定包含 ACE 适用的继承对象类别的 GUID 的字符串。 GUID 必须指定为 COM 库中 StringFromGUID2 函数生成的字符串形式。
  6. 使用 IADsAccessControlEntry 对象上的 QueryInterface 方法获取 IDispatch 指针。 IADsAccessControlList.AddAce 方法需要指向 ACE 的 IDispatch 接口指针。

  7. 使用 IADsAccessControlList.AddAce 将新 ACE 添加到 DACL。 请注意,ACL 中 ACE 的顺序可能会影响对对象访问权限的计算。 针对对象的正确访问可能要求创建新的 ACL,将 ACE 按照正确的顺序从现有 ACL 添加到新的 ACL,然后将安全描述符中的现有 ACL 替换为新的 ACL。 有关详细信息,请参阅 DACL 中的 ACE 顺序

  8. 使用 IADsSecurityDescriptor.DiscretionaryAcl 属性将包含新 ACE 的 DACL 写入安全描述符。 有关 DACL 的详细信息,请参阅 Null DACL 和空 DACL

  9. 使用 IADs.Put 方法将对象的 nTSecurityDescriptor 属性的安全描述符写入属性缓存。

  10. 使用 IADs.SetInfo 方法更新目录中对象的属性。