public static List <string> GetInheritedFrom(FileSystemInfo item, ObjectSecurity sd) { var inheritedFrom = new List <string>(); var sdBytes = sd.GetSecurityDescriptorBinaryForm(); byte[] aclBytes = null; var rawSd = new RawSecurityDescriptor(sdBytes, 0); var aceCount = 0; if (rawSd.SystemAcl != null) { aceCount = rawSd.SystemAcl.Count; aclBytes = new byte[rawSd.SystemAcl.BinaryLength]; rawSd.SystemAcl.GetBinaryForm(aclBytes, 0); try { inheritedFrom = GetInheritedFrom(item.FullName, aclBytes, aceCount, item is DirectoryInfo ? true : false, SECURITY_INFORMATION.SACL_SECURITY_INFORMATION); } catch { inheritedFrom = new List <string>(); for (int i = 0; i < aceCount; i++) { inheritedFrom.Add("unknown parent"); } } } else if (rawSd.DiscretionaryAcl != null) { aceCount = rawSd.DiscretionaryAcl.Count; aclBytes = new byte[rawSd.DiscretionaryAcl.BinaryLength]; rawSd.DiscretionaryAcl.GetBinaryForm(aclBytes, 0); try { inheritedFrom = GetInheritedFrom(item.FullName, aclBytes, aceCount, item is DirectoryInfo ? true : false, SECURITY_INFORMATION.DACL_SECURITY_INFORMATION); } catch { inheritedFrom = new List <string>(); for (int i = 0; i < aceCount; i++) { inheritedFrom.Add("unknown parent"); } } } return(inheritedFrom); }
public NativeSecurityAttributes(ObjectSecurity managedSecurityObject, bool inheritHandle) { length = Marshal.SizeOf(typeof(NativeSecurityAttributes)); byte[] binarySecurityDescriptor = managedSecurityObject.GetSecurityDescriptorBinaryForm(); securityDescriptor = Marshal.AllocHGlobal(binarySecurityDescriptor.Length); Marshal.Copy(binarySecurityDescriptor, 0, securityDescriptor, binarySecurityDescriptor.Length); this.inheritHandle = inheritHandle; }
public static List <string> GetInheritedFrom(string path, ObjectSecurity sd, bool isContainer) { var inheritedFrom = new List <string>(); path = Path.GetLongPath(path); uint returnValue = 0; GENERIC_MAPPING genericMap = new GENERIC_MAPPING(); genericMap.GenericRead = (uint)MappedGenericRights.FILE_GENERIC_READ; genericMap.GenericWrite = (uint)MappedGenericRights.FILE_GENERIC_WRITE; genericMap.GenericExecute = (uint)MappedGenericRights.FILE_GENERIC_EXECUTE; genericMap.GenericAll = (uint)MappedGenericRights.FILE_GENERIC_ALL; var sdBytes = sd.GetSecurityDescriptorBinaryForm(); var commonSd = new CommonSecurityDescriptor(isContainer, false, sdBytes, 0); var aclBytes = new byte[commonSd.DiscretionaryAcl.BinaryLength]; commonSd.DiscretionaryAcl.GetBinaryForm(aclBytes, 0); var pInheritInfo = Marshal.AllocHGlobal(commonSd.DiscretionaryAcl.Count * Marshal.SizeOf(typeof(PINHERITED_FROM))); returnValue = GetInheritanceSource( path, ResourceType.FileObject, SECURITY_INFORMATION.DACL_SECURITY_INFORMATION, isContainer, IntPtr.Zero, 0, aclBytes, IntPtr.Zero, ref genericMap, pInheritInfo ); if (returnValue != 0) { throw new System.ComponentModel.Win32Exception((int)returnValue); } for (int i = 0; i < commonSd.DiscretionaryAcl.Count; i++) { var inheritInfo = pInheritInfo.ElementAt <PINHERITED_FROM>(i); inheritedFrom.Add( !string.IsNullOrEmpty(inheritInfo.AncestorName) && inheritInfo.AncestorName.StartsWith(@"\\?\") ? inheritInfo.AncestorName.Substring(4) : inheritInfo.AncestorName ); } FreeInheritedFromArray(pInheritInfo, (ushort)commonSd.DiscretionaryAcl.Count, IntPtr.Zero); Marshal.FreeHGlobal(pInheritInfo); return(inheritedFrom); }
/// <summary> /// Initializes the SecurityAttributes structure from an instance of <see cref="ObjectSecurity"/>. /// </summary> /// <param name="memoryHandle">A handle that will refer to the memory allocated by this object for storage of the /// security descriptor. As long as this object is used, the memory handle should be kept alive, and afterwards it /// should be disposed as soon as possible.</param> /// <param name="securityDescriptor">The security descriptor to assign to this object. This parameter may be <see langword="null"/>.</param> public void Initialize(out SafeGlobalMemoryBufferHandle memoryHandle, ObjectSecurity securityDescriptor) { nLength = (uint)Marshal.SizeOf(this); if (securityDescriptor == null) { memoryHandle = new SafeGlobalMemoryBufferHandle(); } else { byte[] src = securityDescriptor.GetSecurityDescriptorBinaryForm(); memoryHandle = new SafeGlobalMemoryBufferHandle(src.Length); memoryHandle.CopyFrom(src, 0, src.Length); } bInheritHandle = 0; }
private void SetSecurityDescriptor(string path, ObjectSecurity sd, AccessControlSections sections) { var currentPrivilegeState = new PlatformInvokes.TOKEN_PRIVILEGE(); byte[] securityDescriptorBinary = null; try { // Get the binary form of the descriptor. PlatformInvokes.EnableTokenPrivilege("SeBackupPrivilege", ref currentPrivilegeState); securityDescriptorBinary = sd.GetSecurityDescriptorBinaryForm(); } finally { PlatformInvokes.RestoreTokenPrivilege("SeBackupPrivilege", ref currentPrivilegeState); } try { PlatformInvokes.EnableTokenPrivilege("SeRestorePrivilege", ref currentPrivilegeState); // Transfer it to the new file / directory. // We keep these two code branches so that we can have more // granular information when we ouput the object type via // WriteSecurityDescriptorObject. if (Directory.Exists(path)) { DirectorySecurity newDescriptor = new DirectorySecurity(); newDescriptor.SetSecurityDescriptorBinaryForm(securityDescriptorBinary, sections); new DirectoryInfo(path).SetAccessControl(newDescriptor); WriteSecurityDescriptorObject(newDescriptor, path); } else { FileSecurity newDescriptor = new FileSecurity(); newDescriptor.SetSecurityDescriptorBinaryForm(securityDescriptorBinary, sections); new FileInfo(path).SetAccessControl(newDescriptor); WriteSecurityDescriptorObject(newDescriptor, path); } } finally { PlatformInvokes.RestoreTokenPrivilege("SeRestorePrivilege", ref currentPrivilegeState); } }
/// <summary>Sort ACEs according to canonical form for this <see cref="ObjectSecurity"/>.</summary> /// <param name="objectSecurity">The object security whose DiscretionaryAcl will be made canonical.</param> public static void CanonicalizeAccessRules(this ObjectSecurity objectSecurity) { if (objectSecurity == null) { throw new ArgumentNullException(nameof(objectSecurity)); } if (objectSecurity.AreAccessRulesCanonical) { return; } // Get raw SD from objectSecurity and canonicalize DACL var sd = new RawSecurityDescriptor(objectSecurity.GetSecurityDescriptorBinaryForm(), 0); sd.DiscretionaryAcl.Canonicalize(); // Convert SD back into objectSecurity objectSecurity.SetSecurityDescriptorBinaryForm(sd.GetBinaryForm()); }
private int GetEffectivePermissions_AuthzAccessCheck(ObjectSecurity sd) { var request = new AUTHZ_ACCESS_REQUEST(); request.DesiredAccess = StdAccess.MAXIMUM_ALLOWED; request.PrincipalSelfSid = null; request.ObjectTypeList = IntPtr.Zero; request.ObjectTypeListLength = 0; request.OptionalArguments = IntPtr.Zero; var reply = new AUTHZ_ACCESS_REPLY(); reply.ResultListLength = 1; reply.SaclEvaluationResults = IntPtr.Zero; reply.GrantedAccessMask = pGrantedAccess = Marshal.AllocHGlobal(sizeof(uint)); reply.Error = pErrorSecObj = Marshal.AllocHGlobal(sizeof(uint)); byte[] rawSD = sd.GetSecurityDescriptorBinaryForm(); if (!AuthzAccessCheck( AuthzACFlags.None, userClientCtxt, ref request, IntPtr.Zero, rawSD, null, 0, ref reply, IntPtr.Zero)) { var error = Marshal.GetLastWin32Error(); if (error != 0) { throw new Win32Exception(); } } var grantedAccess = Marshal.ReadInt32(pGrantedAccess); return(grantedAccess); }
private static SafeGlobalMemoryBufferHandle ToUnmanagedSecurityAttributes(ObjectSecurity securityDescriptor) { if (securityDescriptor == null) { return(new SafeGlobalMemoryBufferHandle()); } byte[] src = securityDescriptor.GetSecurityDescriptorBinaryForm(); var safeBuffer = new SafeGlobalMemoryBufferHandle(src.Length); try { safeBuffer.CopyFrom(src, 0, src.Length); return(safeBuffer); } catch { safeBuffer.Close(); throw; } }
internal static void SetAccessControlCore(string path, SafeFileHandle handle, ObjectSecurity objectSecurity, AccessControlSections includeSections, PathFormat pathFormat) { if (pathFormat == PathFormat.RelativePath) { Path.CheckSupportedPathFormat(path, true, true); } if (objectSecurity == null) { throw new ArgumentNullException("objectSecurity"); } var managedDescriptor = objectSecurity.GetSecurityDescriptorBinaryForm(); using (var safeBuffer = new SafeGlobalMemoryBufferHandle(managedDescriptor.Length)) { var pathLp = Path.GetExtendedLengthPathCore(null, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.CheckInvalidPathChars); safeBuffer.CopyFrom(managedDescriptor, 0, managedDescriptor.Length); SECURITY_DESCRIPTOR_CONTROL control; uint revision; var success = Security.NativeMethods.GetSecurityDescriptorControl(safeBuffer, out control, out revision); var lastError = Marshal.GetLastWin32Error(); if (!success) { NativeError.ThrowException(lastError, pathLp); } PrivilegeEnabler privilegeEnabler = null; try { var securityInfo = SECURITY_INFORMATION.None; var pDacl = IntPtr.Zero; if ((includeSections & AccessControlSections.Access) != 0) { bool daclDefaulted, daclPresent; success = Security.NativeMethods.GetSecurityDescriptorDacl(safeBuffer, out daclPresent, out pDacl, out daclDefaulted); lastError = Marshal.GetLastWin32Error(); if (!success) { NativeError.ThrowException(lastError, pathLp); } if (daclPresent) { securityInfo |= SECURITY_INFORMATION.DACL_SECURITY_INFORMATION; securityInfo |= (control & SECURITY_DESCRIPTOR_CONTROL.SE_DACL_PROTECTED) != 0 ? SECURITY_INFORMATION.PROTECTED_DACL_SECURITY_INFORMATION : SECURITY_INFORMATION.UNPROTECTED_DACL_SECURITY_INFORMATION; } } var pSacl = IntPtr.Zero; if ((includeSections & AccessControlSections.Audit) != 0) { bool saclDefaulted, saclPresent; success = Security.NativeMethods.GetSecurityDescriptorSacl(safeBuffer, out saclPresent, out pSacl, out saclDefaulted); lastError = Marshal.GetLastWin32Error(); if (!success) { NativeError.ThrowException(lastError, pathLp); } if (saclPresent) { securityInfo |= SECURITY_INFORMATION.SACL_SECURITY_INFORMATION; securityInfo |= (control & SECURITY_DESCRIPTOR_CONTROL.SE_SACL_PROTECTED) != 0 ? SECURITY_INFORMATION.PROTECTED_SACL_SECURITY_INFORMATION : SECURITY_INFORMATION.UNPROTECTED_SACL_SECURITY_INFORMATION; privilegeEnabler = new PrivilegeEnabler(Privilege.Security); } } var pOwner = IntPtr.Zero; if ((includeSections & AccessControlSections.Owner) != 0) { bool ownerDefaulted; success = Security.NativeMethods.GetSecurityDescriptorOwner(safeBuffer, out pOwner, out ownerDefaulted); lastError = Marshal.GetLastWin32Error(); if (!success) { NativeError.ThrowException(lastError, pathLp); } if (pOwner != IntPtr.Zero) { securityInfo |= SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION; } } var pGroup = IntPtr.Zero; if ((includeSections & AccessControlSections.Group) != 0) { bool groupDefaulted; success = Security.NativeMethods.GetSecurityDescriptorGroup(safeBuffer, out pGroup, out groupDefaulted); lastError = Marshal.GetLastWin32Error(); if (!success) { NativeError.ThrowException(lastError, pathLp); } if (pGroup != IntPtr.Zero) { securityInfo |= SECURITY_INFORMATION.GROUP_SECURITY_INFORMATION; } } if (!Utils.IsNullOrWhiteSpace(pathLp)) { // SetNamedSecurityInfo() // 2013-01-13: MSDN does not confirm LongPath usage but a Unicode version of this function exists. lastError = (int)Security.NativeMethods.SetNamedSecurityInfo(pathLp, SE_OBJECT_TYPE.SE_FILE_OBJECT, securityInfo, pOwner, pGroup, pDacl, pSacl); if (lastError != Win32Errors.ERROR_SUCCESS) { NativeError.ThrowException(lastError, pathLp); } } else { if (NativeMethods.IsValidHandle(handle)) { lastError = (int)Security.NativeMethods.SetSecurityInfo(handle, SE_OBJECT_TYPE.SE_FILE_OBJECT, securityInfo, pOwner, pGroup, pDacl, pSacl); if (lastError != Win32Errors.ERROR_SUCCESS) { NativeError.ThrowException(lastError); } } } } finally { if (null != privilegeEnabler) { privilegeEnabler.Dispose(); } } } }
/// <summary>Initializes a new instance of the <see cref="PinnedSecurityDescriptor"/> class.</summary> /// <param name="sd">The object security.</param> public PinnedSecurityDescriptor(ObjectSecurity sd) { bytes = sd.GetSecurityDescriptorBinaryForm(); SetObject(bytes); }
internal static void SetAccessControlCore(string path, SafeFileHandle handle, ObjectSecurity objectSecurity, AccessControlSections includeSections, PathFormat pathFormat) { if (pathFormat == PathFormat.RelativePath) { Path.CheckSupportedPathFormat(path, true, true); } if (objectSecurity == null) { throw new ArgumentNullException("objectSecurity"); } byte[] managedDescriptor = objectSecurity.GetSecurityDescriptorBinaryForm(); using (var safeBuffer = new SafeGlobalMemoryBufferHandle(managedDescriptor.Length)) { string pathLp = Path.GetExtendedLengthPathCore(null, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.CheckInvalidPathChars); safeBuffer.CopyFrom(managedDescriptor, 0, managedDescriptor.Length); SecurityDescriptorControl control; uint revision; if (!Security.NativeMethods.GetSecurityDescriptorControl(safeBuffer, out control, out revision)) { NativeError.ThrowException(Marshal.GetLastWin32Error(), pathLp); } PrivilegeEnabler privilegeEnabler = null; try { var securityInfo = SecurityInformation.None; IntPtr pDacl = IntPtr.Zero; if ((includeSections & AccessControlSections.Access) != 0) { bool daclDefaulted, daclPresent; if (!Security.NativeMethods.GetSecurityDescriptorDacl(safeBuffer, out daclPresent, out pDacl, out daclDefaulted)) { NativeError.ThrowException(Marshal.GetLastWin32Error(), pathLp); } if (daclPresent) { securityInfo |= SecurityInformation.Dacl; securityInfo |= (control & SecurityDescriptorControl.DaclProtected) != 0 ? SecurityInformation.ProtectedDacl : SecurityInformation.UnprotectedDacl; } } IntPtr pSacl = IntPtr.Zero; if ((includeSections & AccessControlSections.Audit) != 0) { bool saclDefaulted, saclPresent; if (!Security.NativeMethods.GetSecurityDescriptorSacl(safeBuffer, out saclPresent, out pSacl, out saclDefaulted)) { NativeError.ThrowException(Marshal.GetLastWin32Error(), pathLp); } if (saclPresent) { securityInfo |= SecurityInformation.Sacl; securityInfo |= (control & SecurityDescriptorControl.SaclProtected) != 0 ? SecurityInformation.ProtectedSacl : SecurityInformation.UnprotectedSacl; privilegeEnabler = new PrivilegeEnabler(Privilege.Security); } } IntPtr pOwner = IntPtr.Zero; if ((includeSections & AccessControlSections.Owner) != 0) { bool ownerDefaulted; if (!Security.NativeMethods.GetSecurityDescriptorOwner(safeBuffer, out pOwner, out ownerDefaulted)) { NativeError.ThrowException(Marshal.GetLastWin32Error(), pathLp); } if (pOwner != IntPtr.Zero) { securityInfo |= SecurityInformation.Owner; } } IntPtr pGroup = IntPtr.Zero; if ((includeSections & AccessControlSections.Group) != 0) { bool groupDefaulted; if (!Security.NativeMethods.GetSecurityDescriptorGroup(safeBuffer, out pGroup, out groupDefaulted)) { NativeError.ThrowException(Marshal.GetLastWin32Error(), pathLp); } if (pGroup != IntPtr.Zero) { securityInfo |= SecurityInformation.Group; } } uint lastError; if (!Utils.IsNullOrWhiteSpace(pathLp)) { // SetNamedSecurityInfo() // In the ANSI version of this function, the name is limited to MAX_PATH characters. // To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\" to the path. // 2013-01-13: MSDN does not confirm LongPath usage but a Unicode version of this function exists. lastError = Security.NativeMethods.SetNamedSecurityInfo(pathLp, ObjectType.FileObject, securityInfo, pOwner, pGroup, pDacl, pSacl); if (lastError != Win32Errors.ERROR_SUCCESS) { NativeError.ThrowException(lastError, pathLp); } } else { if (NativeMethods.IsValidHandle(handle)) { lastError = Security.NativeMethods.SetSecurityInfo(handle, ObjectType.FileObject, securityInfo, pOwner, pGroup, pDacl, pSacl); if (lastError != Win32Errors.ERROR_SUCCESS) { NativeError.ThrowException((int)lastError); } } } } finally { if (privilegeEnabler != null) { privilegeEnabler.Dispose(); } } } }