CreatePrivateObjectSecurityWithMultipleInheritance 函数 (securitybaseapi.h)

CreatePrivateObjectSecurityWithMultipleInheritance 函数为调用此函数的资源管理器创建的新私有对象分配和初始化自相对安全描述符。 此函数支持私有对象 (,例如具有附加辅助类的目录服务对象) 由多个对象类型或类组成。

语法

BOOL CreatePrivateObjectSecurityWithMultipleInheritance(
  [in, optional] PSECURITY_DESCRIPTOR ParentDescriptor,
  [in, optional] PSECURITY_DESCRIPTOR CreatorDescriptor,
  [out]          PSECURITY_DESCRIPTOR *NewDescriptor,
  [in, optional] GUID                 **ObjectTypes,
  [in]           ULONG                GuidCount,
  [in]           BOOL                 IsContainerObject,
  [in]           ULONG                AutoInheritFlags,
  [in, optional] HANDLE               Token,
  [in]           PGENERIC_MAPPING     GenericMapping
);

参数

[in, optional] ParentDescriptor

指向对象的父容器 的安全描述符 的指针。 如果没有父容器,则此参数为 NULL

[in, optional] CreatorDescriptor

指向对象创建者提供的安全描述符的指针。 如果对象的创建者未显式传递新对象的安全信息,则此参数可以为 NULL。 或者,此参数可以指向默认的安全描述符。

[out] NewDescriptor

指向变量的指针,用于接收指向新分配的自相对安全描述符的指针。 使用完安全描述符后,请通过调用
DestroyPrivateObjectSecurity 函数。

[in, optional] ObjectTypes

指向 GUID 结构的指针数组,用于标识与 NewDescriptor 关联的对象的对象类型或类。 对于 Active Directory 对象,此数组包含指向对象的结构类和所有附加辅助类的类 GUID 的指针。 如果对象没有 GUID,请将 ObjectTypes 设置为 NULL

[in] GuidCount

ObjectTypes 参数中存在的 GUID 数。

[in] IsContainerObject

指定新对象是否可以包含其他对象。 值为 TRUE 表示新对象是容器。 值为 FALSE 表示新对象不是容器。

[in] AutoInheritFlags

一组位标志,用于控制如何从 ParentDescriptor 继承访问控制项 (ACE) 。 此参数可以是以下值的组合。

含义
SEF_DACL_AUTO_INHERIT
0x01
(DACL) 的新 自由访问控制列表 包含从 ParentDescriptor 的 DACL 继承的 ACE,以及在 CreatorDescriptor 的 DACL 中指定的任何显式 ACE。 如果未设置此标志,则新的 DACL 不会继承 ACE。
SEF_SACL_AUTO_INHERIT
0x02
(SACL) 的新 系统访问控制列表 包含从 ParentDescriptor 的 SACL 继承的 ACE,以及 CreatorDescriptor 的 SACL 中指定的任何显式 ACE。 如果未设置此标志,则新的 SACL 不会继承 ACE。
SEF_DEFAULT_DESCRIPTOR_FOR_OBJECT
0x04
CreatorDescriptorObjectTypes 指定的对象类型的默认描述符。 因此,如果 ParentDescriptorObjectTypes 参数指定的对象类型具有任何特定于对象的 ACE,则 CreatorDescriptor 将被忽略。 如果未继承此类 ACE,则 CreatorDescriptor 的处理方式与未指定此标志一样。
SEF_AVOID_PRIVILEGE_CHECK
0x08
函数不执行权限检查。 如果还设置了SEF_AVOID_OWNER_CHECK标志, 则 Token 参数可以为 NULL。 此标志在实现自动继承时很有用,以避免检查每个更新的子级的权限。
SEF_AVOID_OWNER_CHECK
0x10
函数不会检查结果 NewDescriptor 中所有者的有效性,如备注部分所述。 如果还设置了SEF_AVOID_PRIVILEGE_CHECK标志, 则 Token 参数可以为 NULL
SEF_DEFAULT_OWNER_FROM_PARENT
0x20
NewDescriptor 的所有者默认为 ParentDescriptor 中的所有者。 如果未设置, NewDescriptor 的所有者默认为 Token 参数指定的令牌的所有者。 令牌的所有者在令牌本身中指定。 在任一情况下,如果 CreatorDescriptor 参数不为 NULL,则 NewDescriptor 所有者将从 CreatorDescriptor 设置为所有者。
SEF_DEFAULT_GROUP_FROM_PARENT
0x40
NewDescriptor 组默认为 ParentDescriptor 中的组。 如果未设置, NewDescriptor 组默认为 Token 参数指定的令牌组。 令牌组在令牌本身中指定。 在任一情况下,如果 CreatorDescriptor 参数不是 NULL,则 NewDescriptor 组将设置为 CreatorDescriptor 中的组。
SEF_MACL_NO_WRITE_UP
0x100
强制级别低于 对象的主体无法写入对象。
SEF_MACL_NO_READ_UP
0x200
强制级别低于 对象的主体无法读取对象。
SEF_MACL_NO_EXECUTE_UP
0x400
强制级别低于 对象的主体无法执行对象。
SEF_AVOID_OWNER_RESTRICTION
0x1000
将忽略 ParentDescriptor 参数指定的任何限制,这些限制将限制调用方在 CreatorDescriptor 中指定 DACL 的能力。

[in, optional] Token

代表其创建对象的客户端进程的访问令牌的句柄。 如果这是 模拟令牌,则它必须处于 SecurityIdentification 级别或更高级别。 有关 SecurityIdentification 模拟级别的完整说明,请参阅 SECURITY_IMPERSONATION_LEVEL 枚举类型。

客户端令牌包含默认安全信息,例如默认所有者、主组和 DACL。 如果信息不在输入安全描述符中,则此函数使用这些默认值。 令牌必须打开才能 TOKEN_QUERY 访问。

如果以下所有条件都为 true,则除了 TOKEN_QUERY 访问外,还必须打开句柄以 TOKEN_DUPLICATE 访问。

  • 令牌句柄是指主令牌。
  • 令牌的安全描述符包含一个或多个具有 OwnerRights SID 的 ACE。
  • CreatorDescriptor 参数指定安全描述符。
  • 此函数的调用方不会在 AutoInheritFlags 参数中设置SEF_AVOID_OWNER_RESTRICTION标志。

[in] GenericMapping

指向 GENERIC_MAPPING 结构的指针,该结构指定从每个泛型权限到对象特定权限的映射。

返回值

如果函数成功,该函数将返回非零值。

如果函数失败,则返回零。 调用 GetLastError 获取扩展错误信息。 下表列出了一些扩展错误代码及其含义。

返回代码 说明
ERROR_INVALID_PRIMARY_GROUP
函数无法检索新安全描述符的主组。
ERROR_INVALID_OWNER
函数无法检索新安全描述符的所有者,或者无法将 SID) 分配为所有者 (安全标识符 。 针对传入的令牌验证所有者 SID 时会出现这种情况。
ERROR_NO_TOKEN
函数收到 NULL ,而不是用于所有者验证或 权限 检查的令牌。
ERROR_PRIVILEGE_NOT_HELD
正在设置 SACL,SEF_AVOID_PRIVILEGE_CHECK未传入,传入的令牌未启用SE_SECURITY_NAME。

注解

CreatePrivateObjectSecurityEx 函数与在 ObjectTypes 中使用单个 GUID 调用 CreatePrivateObjectSecurityWithMultipleInheritance 函数相同。

AutoInheritFlags 不同于 SECURITY_DESCRIPTOR 结构的 Control 成员中类似命名的位。 有关控制位的说明,请参阅 SECURITY_DESCRIPTOR_CONTROL

如果 AutoInheritFlags 指定SEF_DACL_AUTO_INHERIT位,则函数将以下规则应用于新安全描述符中的 DACL:

  • 在新的安全描述 符的控制成员 中设置SE_DACL_AUTO_INHERITED标志。
  • 无论 CreatorDescriptor 是默认安全描述符还是由创建者显式指定,新安全描述符的 DACL 都从 ParentDescriptor 继承 ACE。 新的 DACL 是继承规则定义的父和创建者 DACL 的组合。 具体而言, ParentDescriptor 中可继承到所有子对象或 ObjectTypes 中列出的任何对象类的任何 ACE 都将应用于新的 DACL。
  • 继承的 ACE 标记为INHERITED_ACE。
如果 AutoInheritFlags 指定SEF_SACL_AUTO_INHERIT位,则函数会将类似的规则应用于新的 SACL。

对于 DACL 和 SCL,ParentDescriptorCreatorDescriptor 中的某些类型的 ACE 将被操作,并可能被 NewDescriptor 中的两个 ACE 取代。 具体而言,至少包含以下可映射元素之一的可继承 ACE 可能会导致输出安全描述符中出现两个 ACE。 可映射元素包括:

  • ACCESS_MASK中的通用访问权限
  • 创建者所有者 SID 或创建者组 SID 作为 ACE 使用者标识符
具有这些可映射元素的 ACE 将导致 NewDescriptor 中生成以下两个 ACE:
  • 一个 ACE,它是原始副本,但设置了INHERIT_ONLY标志。 但是,如果存在以下两个条件之一,则不会创建此 ACE:
    • IsContainerObject 参数为 FALSE。 可继承的 ACE 在非容器对象上毫无意义。
    • 原始 ACE 包含 NO_PROPAGATE_INHERIT 标志。 原始 ACE 旨在作为子级的有效 ACE 继承,但不能继承到这些子级以下。
  • 一个有效的 ACE,其中打开INHERITED_ACE位并将泛型元素映射到特定元素:
    • 通用访问权限由输入 GenericMapping 中指示的相应标准和特定访问权限取代。
    • 创建者所有者 SID 替换为生成的 NewDescriptor 中的所有者
    • 创建者组 SID 替换为生成的 NewDescriptor 中的组
如果 AutoInheritFlags 未指定SEF_AVOID_OWNER_CHECK位,则根据以下规则执行所有者有效性检查。 生成的 NewDescriptor 中的所有者必须是合法格式的 SID,并且必须与 Token 中的 TokenUser 匹配,或者必须与 Token 中的 TokenGroups 中的组匹配。 组的属性:
  • 必须包含SE_GROUP_OWNER
  • 不得包含SE_GROUP_USE_FOR_DENY_ONLY
无权访问最终将设置所有者的客户端令牌的调用方可以选择跳过所有者验证检查。

若要为新对象创建安全描述符,请调用 CreatePrivateObjectSecurityWithMultipleInheritance ,其中 ParentDescriptor 设置为父容器的安全描述符, 将 CreatorDescriptor 设置为对象创建者提出的安全描述符。

若要验证对象上的当前安全描述符,请调用 CreatePrivateObjectSecurityWithMultipleInheritance并将 ParentDescriptor 设置为父容器的安全描述符, 将 CreatorDescriptor 设置为对象的当前安全描述符。 此调用可确保 ACE 适当地从父安全描述符继承到子安全描述符。

如果 CreatorDescriptor 安全描述符包含 SACL, 则令牌 必须启用SE_SECURITY_NAME特权,或者调用方必须在 AutoInheritFlags 中指定SEF_AVOID_PRIVILEGE_CHECK标志。

要求

要求
最低受支持的客户端 Windows XP [仅限桌面应用]
最低受支持的服务器 Windows Server 2003 [仅限桌面应用]
目标平台 Windows
标头 securitybaseapi.h (包括 Windows.h)
Library Advapi32.lib
DLL Advapi32.dll

另请参阅

CreatePrivateObjectSecurityEx

DestroyPrivateObjectSecurity

GENERIC_MAPPING

GUID

SECURITY_DESCRIPTOR

SECURITY_DESCRIPTOR_CONTROL

SECURITY_IMPERSONATION_LEVEL