Yesterday a colleague needed to decode a Windows security descriptor stored in the registry as REG_BINARY. It defines security for a COM object. I've used Windows Powershell to help him:
PS>$binSD = (get-itemproperty hklm:\software\Microsoft\Ole).DefaultLaunchPermission
PS>$sd = new-object System.Security.AccessControl.RawSecurityDescriptor $binSD,0
PS>$sd
ControlFlags : DiscretionaryAclPresent, SelfRelative
Owner : S-1-5-32-544
Group : S-1-5-32-544
SystemAcl :
DiscretionaryAcl : {System.Security.AccessControl.CommonAce, System.Security.AccessControl.Co
mmonAce, System.Security.AccessControl.CommonAce}
ResourceManagerControl : 0
BinaryLength : 124
That looks not so bad, but the access control list was the interesting item. Use this:
PS>$sd.DiscretionaryAcl | format-table AceQualifier, AccessMask,
@{ Label="SID"; Expression={$_.SecurityIdentifier.Translate("System.Security.Principal.NTAccount")} },
IsInherited, InheritanceFlags, PropagationFlags, AuditFlags -auto -wrap
and you get
AceQualifier AccessMask SecurityIdentifier IsInherited InheritanceFlags PropagationFlags AuditFlags
------------ ---------- ------------------ ----------- ---------------- ---------------- ----------
AccessAllowed 31 S-1-5-32-544 False None None None
AccessAllowed 31 S-1-5-4 False None None None
AccessAllowed 31 S-1-5-18 False None None None
Nice, but better would be to have the NT account names for the security identifier (SID). A short look into the documentation of the SecurityIdentifier object resulted in this:
PS>$sd.DiscretionaryAcl | format-table AceQualifier, AccessMask,
@{ Label="SID"; Expression={$_.SecurityIdentifier.Translate("System.Security.Principal.NTAccount")} },
IsInherited, InheritanceFlags, PropagationFlags, AuditFlags -auto -wrap
and you get
AceQualifier AccessMask SID IsInherited InheritanceFlags PropagationFlags AuditFlags
------------ ---------- --- ----------- ---------------- ---------------- ----------
AccessAllowed 31 BUILTIN\Administrators False None None None
AccessAllowed 31 NT AUTHORITY\INTERACTIVE False None None None
AccessAllowed 31 NT AUTHORITY\SYSTEM False None None None
The strange @{} parameter of format-table is called a calculated property. It defines the label of the table column "SID" and a script block to calculate the contents. In this case it calls the Translate Method on the SecurityIdentifier object to get the NT account name of the SID.
BTW, that works with other security descriptors, too, e.g. service SDs, which are stored in the registry as well.
Have I mentioned that really like Powershell? 