__SystemSecurity 类的 SetSD 方法

SetSD 方法为用户连接的命名空间设置安全描述符。 此方法需要二进制字节数组格式的安全描述符。 如果正在编写脚本,请使用 SetSecurityDescriptor 方法。 有关详细信息,请参阅保护 WMI 命名空间更改安全对象的访问安全性

如果使用 C++ 进行编程,则可以使用 SDDL 以及转换方法 ConvertSecurityDescriptorToStringSecurityDescriptorConvertStringSecurityDescriptorToSecurityDescriptor 来操作二进制安全描述符。

用户必须具有 WRITE_DAC 权限,默认情况下,管理员具有该权限。 安全描述符中仅用的部分是自定义访问控制列表 (DACL) 中的非继承访问控制项 (ACE)。 通过在 ACE 中设置 CONTAINER_INHERIT 标志,安全描述符会影响子命名空间。 允许 ACE 和拒绝 ACE 都是允许的。

注意

由于拒绝 ACE 和允许 ACE 在 DACL 中都是允许的,因此 ACE 的顺序很重要。 有关详细信息,请参阅 DACL 中 ACE 的排序

语法

HRESULT SetSD(
  [in] uint8 SD[]
);

parameters

SD [in]

构成安全描述符的字节数组。

返回值

返回指示方法调用状态的 HRESULT。 对于脚本和 Visual Basic 应用程序,可以从 OutParameters.ReturnValue 获得结果。 有关详细信息,请参阅构造 InParameters 对象和解析 OutParameters 对象

下表列出了对 SetSD 至关重要的返回值。

S_OK

方法已成功执行。

WBEM_E_ACCESS_DENIED

调用方权限不足,无法调用此方法。

WBEM_E_METHOD_DISABLED

尝试在不支持此方法的操作系统上运行了此方法。

WBEM_E_INVALID_OBJECT

SD 没有通过基本的有效性测试。

WBEM_E_INVALID_PARAMETER

由于以下原因之一,SD 无效:

  • 缺少 DACL。
  • DACL 无效。
  • ACE 设置了 WBEM_FULL_WRITE_REP 标志,并且未设置 WBEM_PARTIAL_WRITE_REP 或 WBEM_WRITE_PROVIDER 标志。
  • ACE 设置了 INHERIT_ONLY_ACE 标志,但未设置 CONTAINER_INHERIT_ACE 标志。
  • ACE 设置了未知的访问位。
  • ACE 设置了表中没有的标志。
  • ACE 设置了表中没有的类型。
  • SD 中缺少所有者和组。

有关访问控制项 (ACE) 标志的详细信息,请参阅 WMI 安全常量

备注

若要详细了解如何以编程方式或手动修改命名空间安全性的,请参阅保护 WMI 命名空间

示例

以下脚本显示如何使用 SetSD 为根命名空间设置命名空间安全描述符并将其更改为 strSD 中显示的字节数组。

' Hard-coded security descriptor
strSD = array( 1, 0, 4,129,72, 0, 0, 0, _ 
              88, 0, 0,  0, 0, 0, 0, 0, _
              20, 0, 0,  0, 2, 0,52, 0, _
               2, 0, 0,  0, 0, 2,24, 0, _
              63, 0, 6,  0, 1, 2, 0, 0, _
               0, 0, 0,  5,32, 0, 0, 0, _
              32, 2, 0,  0, 0, 2,20, 0, _
              63, 0, 6,  0, 1, 1, 0, 0, _
               0, 0, 0,  1, 0, 0, 0, 0, _
               1, 2, 0,  0, 0, 0, 0, 5, _
              32, 0, 0,  0,32, 2, 0, 0, _
               1, 2, 0,  0, 0, 0, 0, 5, _
              32, 0, 0,  0,32, 2, 0, 0)

' Connect to WMI and the root namespace.
Set oSvc = CreateObject( _
                         "WbemScripting.SWbemLocator"). _
                         ConnectServer(,"Root\Cimv2")

' Get the single __SystemSecurity object in this namespace.
Set oSecurity = oSvc.Get("__SystemSecurity=@")

' Change the namespace security.
nReturn = oSecurity.SetSD(strSD)
WScript.Echo "ReturnValue " & nReturn

以下 C# 代码示例使用 System.Security.AccessControl.RawSecurityDescriptor 在 RawSecurityDescriptor.DiscretionaryAcl 中枚举、插入和删除新的 CommonAce 对象,然后将其转换回字节数组并通过 SetSD 保存。 可以使用 NTAccount 和 Translate 检索 SecurityIdentifier。

 byte[] sdValueByteArray = new Byte[0];

            string accountName = "My User or Group";

            AceFlags aceFlags = AceFlags.ContainerInherit;

            int accessRights = 131107; // Search for Namespace Access Rights Constants and build an Flags enum

            RawSecurityDescriptor rawSecurityDescriptor = new RawSecurityDescriptor(sdValueByteArray, 0);

            NTAccount ntAccount = new NTAccount(accountName);

            IdentityReference identityReference = ntAccount.Translate(typeof(SecurityIdentifier));

            if (identityReference == null)

            {

                string message = string.Format("The IdentityReference of NTAccount '{0}' is null.", accountName);

                throw new Exception(message);

            }

            SecurityIdentifier securityIdentifier = identityReference as SecurityIdentifier;

            if (securityIdentifier == null)

            {

                string message = "The IdentityReference of NTAccount '{0}' is not an SecurityIdentifier.";

                throw new Exception(message);

            }

            CommonAce commonAce;

            foreach (GenericAce genericAce in rawSecurityDescriptor.DiscretionaryAcl)

            {

                commonAce = genericAce as CommonAce;

                if (commonAce == null)

                {

                    continue;

                }

                if (commonAce.SecurityIdentifier.Value.Equals(securityIdentifier.Value, StringComparison.OrdinalIgnoreCase))

                {

                    return;

                }

            }

            commonAce = new CommonAce(aceFlags, AceQualifier.AccessAllowed, (int)accessRights, securityIdentifier, false, null);

            rawSecurityDescriptor.DiscretionaryAcl.InsertAce(rawSecurityDescriptor.DiscretionaryAcl.Count, commonAce);

要求

要求
最低受支持的客户端
Windows Vista
最低受支持的服务器
Windows Server 2008
命名空间
所有 WMI 命名空间

另请参阅

WMI 系统类

__SystemSecurity

__SystemSecurity::GetSD

WMI 安全常量

Win32_ACE

Win32_SecurityDescriptor

保护 WMI 命名空间