__SystemSecurity 类的 SetSD 方法
SetSD 方法为用户连接的命名空间设置安全描述符。 此方法需要二进制字节数组格式的安全描述符。 如果正在编写脚本,请使用 SetSecurityDescriptor 方法。 有关详细信息,请参阅保护 WMI 命名空间和更改安全对象的访问安全性。
如果使用 C++ 进行编程,则可以使用 SDDL 以及转换方法 ConvertSecurityDescriptorToStringSecurityDescriptor 和 ConvertStringSecurityDescriptorToSecurityDescriptor 来操作二进制安全描述符。
用户必须具有 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 命名空间 |