/// <summary> /// the constructor /// </summary> /// <param name="flags">the security descriptor control flag</param> /// <param name="owner">the owner sid</param> /// <param name="group">the group sid</param> /// <param name="sacl">the sacl</param> /// <param name="dacl">the dacl</param> public _RawSecurityDescriptor(SECURITY_DESCRIPTOR_Control flags, _SID?owner, _SID?group, _RawAcl sacl, _RawAcl dacl) { controlFlags = flags; ownerSid = owner; groupSid = group; this.sacl = sacl; this.dacl = dacl; }
/// <summary> /// the constructor /// </summary> /// <param name="binary">the input binary</param> /// <param name="offset">the offset in the binary</param> public _RawSecurityDescriptor(byte[] binary, int offset) { if (binary == null) { throw new ArgumentNullException(nameof(binary)); } if (offset < 0 || offset > binary.Length - 0x14) { throw new ArgumentOutOfRangeException(nameof(offset)); } controlFlags = (SECURITY_DESCRIPTOR_Control)BitConverter.ToUInt16(binary, offset + 2); //Get owner sid int ownerStart = BitConverter.ToInt32(binary, offset + 4); if (ownerStart != 0) { ownerSid = new _SID(binary, ownerStart); } //Get group sid int groupStart = BitConverter.ToInt32(binary, offset + 8); if (groupStart != 0) { groupSid = new _SID(binary, groupStart); } //Get sacl int saclStart = BitConverter.ToInt32(binary, offset + 12); if (saclStart != 0) { sacl = new _RawAcl(binary, saclStart); } //Get dacl int daclStart = BitConverter.ToInt32(binary, offset + 16); if (daclStart != 0) { dacl = new _RawAcl(binary, daclStart); } }
public string GetSddlForm(SECURITY_DESCRIPTOR_Control flags, bool isDacl) { StringBuilder result = new StringBuilder(); if (isDacl) { if (flags.HasFlag(SECURITY_DESCRIPTOR_Control.DACLProtected)) { result.Append("P"); } if (flags.HasFlag(SECURITY_DESCRIPTOR_Control.DACLInheritanceRequired)) { result.Append("AR"); } if (flags.HasFlag(SECURITY_DESCRIPTOR_Control.DACLAutoInherited)) { result.Append("AI"); } } else { if (flags.HasFlag(SECURITY_DESCRIPTOR_Control.SACLProtected)) { result.Append("P"); } if (flags.HasFlag(SECURITY_DESCRIPTOR_Control.SACLInheritanceRequired)) { result.Append("AR"); } if (flags.HasFlag(SECURITY_DESCRIPTOR_Control.SACLAutoInherited)) { result.Append("AI"); } } foreach (var ace in list) { result.Append(ace.GetSddlForm()); } return(result.ToString()); }
/// <summary> /// Create a _SECURITY_DESCRIPTOR structure in self-relative format. /// </summary> /// <param name="control">An unsigned 16-bit field that specifies control access bit flags.</param> /// <param name="ownerSid">The SID of the owner of the object</param> /// <param name="groupSid">The SID of the group of the object.</param> /// <param name="sacl">The SACL of the object.</param> /// <param name="dacl">The DACL of the object.</param> /// <returns> Output security descriptor for the object.</returns> public static _SECURITY_DESCRIPTOR CreateSecurityDescriptor( SECURITY_DESCRIPTOR_Control control, _SID? ownerSid, _SID? groupSid, _ACL? sacl, _ACL? dacl) { RawAcl sRawAcl = null; RawAcl dRawAcl = null; SecurityIdentifier rawOwnerSid = null; SecurityIdentifier rawGroupSid = null; if (ownerSid != null) { rawOwnerSid = new SecurityIdentifier(TypeMarshal.ToBytes(ownerSid.Value), 0); } if (groupSid != null) { rawGroupSid = new SecurityIdentifier(TypeMarshal.ToBytes(groupSid.Value), 0); } if (sacl != null) { sRawAcl = new RawAcl(DtypUtility.EncodeAcl(sacl.Value), 0); } if (dacl != null) { dRawAcl = new RawAcl(DtypUtility.EncodeAcl(dacl.Value), 0); } RawSecurityDescriptor rawSecurityDescriptor = new RawSecurityDescriptor( (ControlFlags)control, rawOwnerSid, rawGroupSid, sRawAcl, dRawAcl); byte[] rawSecurityDescriptorBytes = new byte[rawSecurityDescriptor.BinaryLength]; rawSecurityDescriptor.GetBinaryForm(rawSecurityDescriptorBytes, 0); return DtypUtility.DecodeSecurityDescriptor(rawSecurityDescriptorBytes); }
/// <summary> /// ComputeACL. MS-DTYP section 2.5.4.4 /// </summary> /// <param name="computeType">Enumeration of COMPUTE_DACL and COMPUTE_SACL.</param> /// <param name="parentAcl">ACL from the parent security descriptor.</param> /// <param name="parentControl">Control flags from the parent security descriptor.</param> /// <param name="creatorAcl">ACL supplied in the security descriptor by the creator.</param> /// <param name="creatorControl">Control flags supplied in the security descriptor by the creator.</param> /// <param name="isContainerObject">TRUE if the object is a container; otherwise, FALSE.</param> /// <param name="objectTypes">Array of GUIDs for the object type being created.</param> /// <param name="autoInheritFlags"> /// A set of bit flags that control how access control entries (ACEs) are /// inherited from ParentDescriptor. /// </param> /// <param name="genericMapping"> /// Mapping of generic permissions to resource manager-specific permissions supplied by the caller. /// </param> /// <param name="owner">Owner to use in substituting the CreatorOwner SID.</param> /// <param name="group">Group to use in substituting the CreatorGroup SID.</param> /// <param name="token">Token for default values.</param> /// <param name="computedControl">ComputedControl</param> /// <returns>Computed ACL</returns> public static _ACL? ComputeACL( AclComputeType computeType, _ACL? parentAcl, SECURITY_DESCRIPTOR_Control parentControl, _ACL? creatorAcl, SECURITY_DESCRIPTOR_Control creatorControl, bool isContainerObject, Guid[] objectTypes, SecurityDescriptorAutoInheritFlags autoInheritFlags, GenericMapping genericMapping, _SID owner, _SID group, Token token, out SECURITY_DESCRIPTOR_Control computedControl) { #region Pseudocode v20110329 //// The details of the algorithm to merge the parent ACL and the supplied ACL. //// The Control flags computed are slightly different based on whether it is the //// ACL in the DACL or the SACL field of the descriptor. //// The caller specifies whether it is a DACL or a SACL using the parameter, //// ComputeType. //Set ComputedACL to NULL //Set ComputedControl to NULL //CALL ContainsInheritableACEs WITH ParentACL RETURNING ParentHasInheritableACEs //IF ParentHasInheritableACEs = TRUE THEN // // The Parent ACL has inheritable ACEs. The Parent ACL should be used if no Creator // // ACL is supplied, or if the Creator ACL was supplied AND it is a default ACL based // // on object type information // IF(CreatorACL is not present) OR // ((CreatorACL is present) AND // (AutoInheritFlags contains DEFAULT_DESCRIPTOR_FOR_OBJECT)) // THEN // // Use only the inherited ACEs from the parent. First compute the ACL from the // // parent ACL, then clean it up by resolving the generic mappings etc. // CALL ComputeInheritedACLFromParent WITH // ACL set to ParentACL, // IsContainerObject set to IsContainerObject, // ObjectTypes set to ObjectTypes // RETURNING NextACL // CALL PostProcessACL WITH // ACL set to NextACL, // CopyFilter set to CopyInheritedAces, // Owner set to Owner, // Group set to Group, // GenericMapping set to GenericMapping // RETURNING FinalACL // Set ComputedACL to FinalACL // RETURN // ENDIF //IF ((CreatorACL is present) AND // (AutoInheritFlags does not contain DEFAULT_DESCRIPTOR_FOR_OBJECT)) //THEN // // Since a creator ACL is present, and we’re not defaulting the // // descriptor, determine which ACEs are inherited and compute the new ACL // CALL PreProcessACLFromCreator WITH // ACL set to CreatorACL // RETURNING PreACL // CALL ComputeInheritedACLFromCreator WITH // ACL set to PreACL, // IsContainerObject set to IsContainerObject, // ObjectTypes set to ObjectTypes // RETURNING TmpACL // // Special handling for DACL types of ACLs // IF (ComputeType = DACL_COMPUTE) THEN // // DACL-specific operations // IF (CreatorControl does not have DACL_PROTECTED flag set) AND // (AutoInheritFlags contains DACL_AUTO_INHERIT) // THEN // // We’re not working from a protected DACL, and we’re supposed to // // allow automatic inheritance. Compute the inherited ACEs from // // Parent ACL this time, and append that to the ACL that we’re building // CALL ComputeInheritedACLFromParent WITH // ACL set to ParentACL, // IsContainerObject set to IsContainerObject, // ObjectTypes set to ObjectTypes // RETURNING InheritedParentACL // Append InheritedParentACL.ACEs to TmpACL.ACE // Set DACL_AUTO_INHERITED flag in ComputedControl // ENDIF // ENDIF // DACL-Specific behavior // IF (ComputeType = SACL_COMPUTE) THEN // // Similar to the above, perform SACL-specific operations // IF (CreatorControl does not have SACL_PROTECTED flag set) AND // (AutoInheritFlags contains SACL_AUTO_INHERIT flag) // THEN // // We’re not working from a protected SACL, and we’re supposed to // // allow automatic inheritance. Compute the inherited ACEs from // // Parent ACL this time, and append that to the ACL that we’re building // CALL ComputeInheritedACLFromParent WITH // ACL set to ParentACL, // IsContainerObject set to IsContainerObject, // ObjectTypes set to ObjectTypes // RETURNING InheritedParentACL // Append InheritedParentACL.ACEs to TmpACL.ACE // Set SACL_AUTO_INHERITED flag in ComputedControl // ENDIF // ENDIF // SACL-Specific behavior // CALL PostProcessACL WITH // ACL set to TmpACL, // CopyFilter set to CopyInheritedAces, // Owner set to Owner, // Group set to Group, // GenericMapping set to GenericMapping // RETURNING ProcessedACL // Set ComputedACL to ProcessedACL // RETURN //ENDIF // CreatorACL is present //ELSE // ParentACL does not contain inheritable ACEs // IF CreatorACL = NULL THEN // // No ACL supplied for the object // IF (ComputeType = DACL_COMPUTE) THEN // Set TmpACL to Token.DefaultDACL // ELSE // // No default for SACL; left as NULL // ENDIF // ELSE // // Explicit ACL was supplied for the object - either default or not. // // In either case, use it for the object, since there are no inherited ACEs. // CALL PreProcessACLFromCreator WITH CreatorACL // RETURNING TmpACL // ENDIF // CALL PostProcessACL WITH // ACL set to TmpACL, // CopyFilter set to CopyAllAces, // Owner set to Owner, // Group set to Group, // GenericMapping set to GenericMapping // RETURNING ProcessedACL // Set ComputedACL to ProcessedACL //ENDIF //// END ComputeACL #endregion _ACL? computedACL = null; computedControl = SECURITY_DESCRIPTOR_Control.None; _ACL tmpAcl = new _ACL(); _ACL preAcl = new _ACL(); if (parentAcl != null && ContainsInheritableACEs(parentAcl.Value)) { // ParentACL contains inheritable ACEs if ((creatorAcl == null) || ((creatorAcl != null) && (autoInheritFlags & SecurityDescriptorAutoInheritFlags.DEFAULT_DESCRIPTOR_FOR_OBJECT) == SecurityDescriptorAutoInheritFlags.DEFAULT_DESCRIPTOR_FOR_OBJECT)) { // Use only the inherited ACEs from the parent _ACL nextAcl = ComputeInheritedACLfromParent(parentAcl.Value, isContainerObject, objectTypes); _ACL finalAcl = PostProcessACL(nextAcl, CopyFilter.CopyInheritedAces, owner, group, genericMapping); computedACL = finalAcl; } else { preAcl = PreProcessACLfromCreator(creatorAcl.Value); tmpAcl = ComputeInheritedACLfromCreator(preAcl, isContainerObject, objectTypes); _ACL? inheritedAcl = null; if ((computeType == AclComputeType.COMPUTE_DACL) && (creatorControl & SECURITY_DESCRIPTOR_Control.DACLProtected) == SECURITY_DESCRIPTOR_Control.None && (autoInheritFlags & SecurityDescriptorAutoInheritFlags.DACL_AUTO_INHERIT) == SecurityDescriptorAutoInheritFlags.DACL_AUTO_INHERIT) { // Compute the inherited ACEs from the parent inheritedAcl = ComputeInheritedACLfromParent( parentAcl.Value, isContainerObject, objectTypes); computedControl |= SECURITY_DESCRIPTOR_Control.DACLAutoInherited; } else if ((computeType == AclComputeType.COMPUTE_SACL) && (creatorControl & SECURITY_DESCRIPTOR_Control.SACLProtected) == SECURITY_DESCRIPTOR_Control.None && (autoInheritFlags & SecurityDescriptorAutoInheritFlags.SACL_AUTO_INHERIT) == SecurityDescriptorAutoInheritFlags.SACL_AUTO_INHERIT) { // Compute the inherited ACEs from the parent inheritedAcl = ComputeInheritedACLfromParent( parentAcl.Value, isContainerObject, objectTypes); computedControl |= SECURITY_DESCRIPTOR_Control.SACLAutoInherited; } if (inheritedAcl != null) { List<object> tmpAces = new List<object>(); tmpAces.AddRange(tmpAcl.Aces); tmpAces.AddRange(inheritedAcl.Value.Aces); tmpAcl.Aces = tmpAces.ToArray(); tmpAcl.AceCount = (ushort)tmpAcl.Aces.Length; tmpAcl.AclSize = DtypUtility.CalculateAclSize(tmpAcl); } computedACL = PostProcessACL(tmpAcl, CopyFilter.CopyInheritedAces, owner, group, genericMapping); } } else { // ParentACL does not contain inheritable ACEs if (creatorAcl == null) { if (computeType == AclComputeType.COMPUTE_DACL) { tmpAcl = token.DefaultDACL; } else { //No default for SACL;left as NULL return null; } } else { // Explicit ACL was supplied for the object - either default or not. // In either case, use it for the object, since there are no inherited ACEs. tmpAcl = PreProcessACLfromCreator(creatorAcl.Value); } computedACL = PostProcessACL(tmpAcl, CopyFilter.CopyAllAces, owner, group, genericMapping); } if (computedACL != null) { computedControl |= ((computeType == AclComputeType.COMPUTE_DACL) ? SECURITY_DESCRIPTOR_Control.DACLPresent : SECURITY_DESCRIPTOR_Control.SACLPresent); } return computedACL; }
/// <summary> /// Create the binary from the buffer /// </summary> /// <param name="binary">The input binary</param> /// <param name="offset">The offset in the binary</param> public void GetBinaryForm(byte[] binary, int offset) { if (binary == null) { throw new ArgumentNullException(nameof(binary)); } int binaryLength = Size; if (offset < 0 || offset > binary.Length - binaryLength) { throw new ArgumentOutOfRangeException(nameof(offset)); } SECURITY_DESCRIPTOR_Control controlFlags = this.controlFlags; binary[offset] = 1; //revision binary[offset + 1] = 0; //Sbz1 DtypUtility.WriteUInt16ToByteArray((ushort)controlFlags, binary, offset + 2); int pointer = DtypUtility.SECURITY_DESCRIPTOR_FIXED_LENGTH; if (Owner != null) { DtypUtility.WriteInt32ToByteArray(pointer, binary, offset + 4); Owner.Value.GetBinaryForm(binary, offset + pointer); pointer += Owner.Value.Size; } else { DtypUtility.WriteInt32ToByteArray(0, binary, offset + 4); } if (Group != null) { DtypUtility.WriteInt32ToByteArray(pointer, binary, offset + 8); Group.Value.GetBinaryForm(binary, offset + pointer); pointer += Group.Value.Size; } else { DtypUtility.WriteInt32ToByteArray(0, binary, offset + 8); } _RawAcl sacl = this.SACL; if (this.controlFlags.HasFlag(SECURITY_DESCRIPTOR_Control.SACLPresent)) { DtypUtility.WriteInt32ToByteArray(pointer, binary, offset + 12); sacl.GetBinaryForm(binary, offset + pointer); pointer += this.SACL.Size; } else { DtypUtility.WriteInt32ToByteArray(0, binary, offset + 12); } _RawAcl dacl = this.DACL; if (this.controlFlags.HasFlag(SECURITY_DESCRIPTOR_Control.DACLPresent)) { DtypUtility.WriteInt32ToByteArray(pointer, binary, offset + 16); dacl.GetBinaryForm(binary, offset + pointer); pointer += this.DACL.Size; } else { DtypUtility.WriteInt32ToByteArray(0, binary, offset + 16); } }
public _RawSecurityDescriptor(string sddl) { this.controlFlags |= SECURITY_DESCRIPTOR_Control.SelfRelative; }