SetSD method of the __SystemSecurity class
The SetSD method sets the security descriptor for the namespace to which a user is connected. This method requires a security descriptor in binary byte array format. If you are writing a script, use the SetSecurityDescriptor method. For more information, see Securing WMI Namespaces and Changing Access Security on Securable Objects.
If you are programming in C++, you can manipulate the binary security descriptor using SDDL, and the conversion methods ConvertSecurityDescriptorToStringSecurityDescriptor and ConvertStringSecurityDescriptorToSecurityDescriptor.
A user must have the WRITE_DAC permission, and by default, an administrator has that permission. The only part of the security descriptor that is used is the noninherited access control entry (ACE) in the discretionary access control list (DACL). By setting the CONTAINER_INHERIT flag in the ACEs, the security descriptor affects child namespaces. Both allow and deny ACEs are permitted.
Note
Because deny and allow ACEs are both permitted in a DACL, the order of ACEs is important. For more information, see Ordering of ACEs in a DACL.
Syntax
HRESULT SetSD(
[in] uint8 SD[]
);
Parameters
-
SD [in]
-
Byte array that makes up the security descriptor.
Return value
Returns an HRESULT that indicates the status of a method call. For scripting and Visual Basic applications, the result can be obtained from OutParameters.ReturnValue. For more information, see Constructing InParameters Objects and Parsing OutParameters Objects.
The following list lists the return values that are significant to SetSD.
-
S_OK
-
Method executed successfully.
-
WBEM_E_ACCESS_DENIED
-
Caller does not have sufficient rights to call this method.
-
WBEM_E_METHOD_DISABLED
-
Attempted to run this method on OS that does not support it.
-
WBEM_E_INVALID_OBJECT
-
SD does not pass basic validity tests.
-
WBEM_E_INVALID_PARAMETER
-
SD is not valid due to one of the following:
- DACL is missing.
- DACL is not valid.
- ACE has the WBEM_FULL_WRITE_REP flag set, and the WBEM_PARTIAL_WRITE_REP or WBEM_WRITE_PROVIDER flag is not set.
- ACE has the INHERIT_ONLY_ACE flag set without the CONTAINER_INHERIT_ACE flag.
- ACE has an unknown access bit set.
- ACE has a flag set that is not in the table.
- ACE has a type that is not in the table.
- The owner and group are missing from the SD.
For more information about the access control entry (ACE) flags, see WMI Security Constants.
Remarks
For more information about modifying namespace security programmatically or manually, see Securing WMI Namespaces.
Examples
The following script shows how to use SetSD to set the namespace security descriptor for the root namespace and change it to the byte array shown in 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
The following C# code sample uses the System.Security.AccessControl.RawSecurityDescriptor to enumerate, insert and remove new CommonAce objects in RawSecurityDescriptor.DiscretionaryAcl and then convert it back to an byte array to save it via SetSD. An SecurityIdentifier can be retrieved by using NTAccount and Translate.
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);
Requirements
Requirement | Value |
---|---|
Minimum supported client |
Windows Vista |
Minimum supported server |
Windows Server 2008 |
Namespace |
All WMI namespaces |