__SystemSecurity类的 SetSD 方法

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

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

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

注意

由于在 DACL 中都允许拒绝和允许 ACE,因此 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

尝试在不支持此方法的 OS 上运行此方法。

WBEM_E_INVALID_OBJECT

SD 不通过基本有效性测试。

WBEM_E_INVALID_PARAMETER

SD 无效,原因如下之一:

  • 缺少 DACL。
  • DACL 无效。
  • ACE 设置了 WBEM_FULL_WRITE_REP 标志,并且未设置 WBEM_PARTIAL_WRITE_REPWBEM_WRITE_PROVIDER 标志。
  • ACE 设置了 没有CONTAINER_INHERIT_ACE 标志 的INHERIT_ONLY_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 命名空间