From a94caf1d0f527f7f351cdc4644bd7aac99f70e88 Mon Sep 17 00:00:00 2001 From: Jeremy Kuhne Date: Thu, 6 Jun 2019 15:16:53 -0700 Subject: [PATCH] Expose SecurityDescriptor as protected (dotnet/corefx#38283) * Expose SecurityDescriptor as protected Classes derived from ObjectSecurity depended on seeing the _securityDescriptor field, which is marked internal. Internal visibility no longer works as types have split into different assemblies and is causing failures, such as dotnet/corefx#35993. This change also ran the UpdateVSConfigurations target on the changed libraries. * Address feedback Commit migrated from https://github.com/dotnet/corefx/commit/7570445805fe57966ff6494fcd582de8b79088a0 --- .../System.IO.FileSystem.AccessControl.sln | 8 +- .../src/System.IO.FileSystem.AccessControl.csproj | 2 +- .../AccessControl/DirectoryObjectSecurity.cs | 128 +++++++++------------ .../tests/DirectoryObjectSecurityTests.cs | 24 ++++ .../System.Security.AccessControl.sln | 8 +- .../ref/System.Security.AccessControl.cs | 1 + .../Security/AccessControl/ObjectSecurity.cs | 11 +- .../System.Security.AccessControl.Tests.csproj | 2 +- 8 files changed, 93 insertions(+), 91 deletions(-) diff --git a/src/libraries/System.IO.FileSystem.AccessControl/System.IO.FileSystem.AccessControl.sln b/src/libraries/System.IO.FileSystem.AccessControl/System.IO.FileSystem.AccessControl.sln index 2c9f7c4..4f5aa74 100644 --- a/src/libraries/System.IO.FileSystem.AccessControl/System.IO.FileSystem.AccessControl.sln +++ b/src/libraries/System.IO.FileSystem.AccessControl/System.IO.FileSystem.AccessControl.sln @@ -26,10 +26,10 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {5915DD11-5D57-45A9-BFB0-56FEB7741E1F}.Debug|Any CPU.ActiveCfg = netstandard-Windows_NT-Debug|Any CPU - {5915DD11-5D57-45A9-BFB0-56FEB7741E1F}.Debug|Any CPU.Build.0 = netstandard-Windows_NT-Debug|Any CPU - {5915DD11-5D57-45A9-BFB0-56FEB7741E1F}.Release|Any CPU.ActiveCfg = netstandard-Windows_NT-Release|Any CPU - {5915DD11-5D57-45A9-BFB0-56FEB7741E1F}.Release|Any CPU.Build.0 = netstandard-Windows_NT-Release|Any CPU + {5915DD11-5D57-45A9-BFB0-56FEB7741E1F}.Debug|Any CPU.ActiveCfg = netcoreapp-Windows_NT-Debug|Any CPU + {5915DD11-5D57-45A9-BFB0-56FEB7741E1F}.Debug|Any CPU.Build.0 = netcoreapp-Windows_NT-Debug|Any CPU + {5915DD11-5D57-45A9-BFB0-56FEB7741E1F}.Release|Any CPU.ActiveCfg = netcoreapp-Windows_NT-Release|Any CPU + {5915DD11-5D57-45A9-BFB0-56FEB7741E1F}.Release|Any CPU.Build.0 = netcoreapp-Windows_NT-Release|Any CPU {D77FBA6C-1AA6-45A4-93E2-97A370672C53}.Debug|Any CPU.ActiveCfg = netcoreapp-Windows_NT-Debug|Any CPU {D77FBA6C-1AA6-45A4-93E2-97A370672C53}.Debug|Any CPU.Build.0 = netcoreapp-Windows_NT-Debug|Any CPU {D77FBA6C-1AA6-45A4-93E2-97A370672C53}.Release|Any CPU.ActiveCfg = netcoreapp-Windows_NT-Release|Any CPU diff --git a/src/libraries/System.IO.FileSystem.AccessControl/src/System.IO.FileSystem.AccessControl.csproj b/src/libraries/System.IO.FileSystem.AccessControl/src/System.IO.FileSystem.AccessControl.csproj index 58a5568..8bee62f 100644 --- a/src/libraries/System.IO.FileSystem.AccessControl/src/System.IO.FileSystem.AccessControl.csproj +++ b/src/libraries/System.IO.FileSystem.AccessControl/src/System.IO.FileSystem.AccessControl.csproj @@ -1,4 +1,4 @@ - + {D77FBA6C-1AA6-45A4-93E2-97A370672C53} true diff --git a/src/libraries/System.IO.FileSystem.AccessControl/src/System/Security/AccessControl/DirectoryObjectSecurity.cs b/src/libraries/System.IO.FileSystem.AccessControl/src/System/Security/AccessControl/DirectoryObjectSecurity.cs index 75d79bb..a514e77 100644 --- a/src/libraries/System.IO.FileSystem.AccessControl/src/System/Security/AccessControl/DirectoryObjectSecurity.cs +++ b/src/libraries/System.IO.FileSystem.AccessControl/src/System/Security/AccessControl/DirectoryObjectSecurity.cs @@ -2,35 +2,15 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -// -// Managed ACL wrapper for directories - - -using Microsoft.Win32.SafeHandles; -using Microsoft.Win32; -using System.Collections; -using System.Diagnostics; -using System.IO; -using System.Reflection; -using System.Runtime.InteropServices; -using System.Runtime.Versioning; -using System.Security.AccessControl; using System.Security.Principal; -using System; namespace System.Security.AccessControl { + /// + /// Managed ACL wrapper for directories. Base for System.DirectoryServices.ActiveDirectorySecurity. + /// public abstract class DirectoryObjectSecurity : ObjectSecurity { - #region Private Members - - internal CommonSecurityDescriptor _securityDescriptor; - - #endregion - - #region Constructors - protected DirectoryObjectSecurity() : base(true, true) { @@ -44,12 +24,8 @@ namespace System.Security.AccessControl { throw new ArgumentNullException(nameof(securityDescriptor)); } - - _securityDescriptor = securityDescriptor; } - #endregion - #region Private Methods // Ported from NDP\clr\src\BCL\System\Security\Principal\SID.cs since we can't access System.Security.Principal.IdentityReference's internals @@ -86,16 +62,16 @@ namespace System.Security.AccessControl if (access) { - if ((_securityDescriptor.ControlFlags & ControlFlags.DiscretionaryAclPresent) != 0) + if ((SecurityDescriptor.ControlFlags & ControlFlags.DiscretionaryAclPresent) != 0) { - acl = _securityDescriptor.DiscretionaryAcl; + acl = SecurityDescriptor.DiscretionaryAcl; } } else // !access == audit { - if ((_securityDescriptor.ControlFlags & ControlFlags.SystemAclPresent) != 0) + if ((SecurityDescriptor.ControlFlags & ControlFlags.SystemAclPresent) != 0) { - acl = _securityDescriptor.SystemAcl; + acl = SecurityDescriptor.SystemAcl; } } @@ -284,7 +260,7 @@ namespace System.Security.AccessControl { bool result = true; - if (_securityDescriptor.DiscretionaryAcl == null) + if (SecurityDescriptor.DiscretionaryAcl == null) { if (modification == AccessControlModification.Remove || modification == AccessControlModification.RemoveAll || modification == AccessControlModification.RemoveSpecific) { @@ -294,7 +270,7 @@ namespace System.Security.AccessControl //_securityDescriptor.DiscretionaryAcl = new DiscretionaryAcl(IsContainer, IsDS, GenericAcl.AclRevisionDS, 1); //_securityDescriptor.AddControlFlags(ControlFlags.DiscretionaryAclPresent); - _securityDescriptor.AddDiscretionaryAcl(GenericAcl.AclRevisionDS, 1); + SecurityDescriptor.AddDiscretionaryAcl(GenericAcl.AclRevisionDS, 1); } else if ((modification == AccessControlModification.Add || modification == AccessControlModification.Set || modification == AccessControlModification.Reset) && (rule.ObjectFlags != ObjectAceFlags.None)) @@ -302,16 +278,16 @@ namespace System.Security.AccessControl // // This will result in an object ace being added to the dacl, so the dacl revision must be AclRevisionDS // - if (_securityDescriptor.DiscretionaryAcl.Revision < GenericAcl.AclRevisionDS) + if (SecurityDescriptor.DiscretionaryAcl.Revision < GenericAcl.AclRevisionDS) { // // we need to create a new dacl with the same aces as the existing one but the revision should be AclRevisionDS // - byte[] binaryForm = new byte[_securityDescriptor.DiscretionaryAcl.BinaryLength]; - _securityDescriptor.DiscretionaryAcl.GetBinaryForm(binaryForm, 0); + byte[] binaryForm = new byte[SecurityDescriptor.DiscretionaryAcl.BinaryLength]; + SecurityDescriptor.DiscretionaryAcl.GetBinaryForm(binaryForm, 0); binaryForm[0] = GenericAcl.AclRevisionDS; // revision is the first byte of the binary form - _securityDescriptor.DiscretionaryAcl = new DiscretionaryAcl(IsContainer, IsDS, new RawAcl(binaryForm, 0)); + SecurityDescriptor.DiscretionaryAcl = new DiscretionaryAcl(IsContainer, IsDS, new RawAcl(binaryForm, 0)); } } @@ -323,29 +299,29 @@ namespace System.Security.AccessControl { case AccessControlModification.Add: //_securityDescriptor.DiscretionaryAcl.AddAccess(AccessControlType.Allow, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); - _securityDescriptor.DiscretionaryAcl.AddAccess(AccessControlType.Allow, sid, rule); + SecurityDescriptor.DiscretionaryAcl.AddAccess(AccessControlType.Allow, sid, rule); break; case AccessControlModification.Set: //_securityDescriptor.DiscretionaryAcl.SetAccess(AccessControlType.Allow, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); - _securityDescriptor.DiscretionaryAcl.SetAccess(AccessControlType.Allow, sid, rule); + SecurityDescriptor.DiscretionaryAcl.SetAccess(AccessControlType.Allow, sid, rule); break; case AccessControlModification.Reset: - _securityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Deny, sid, -1, InheritanceFlags.ContainerInherit, 0, ObjectAceFlags.None, Guid.Empty, Guid.Empty); + SecurityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Deny, sid, -1, InheritanceFlags.ContainerInherit, 0, ObjectAceFlags.None, Guid.Empty, Guid.Empty); //_securityDescriptor.DiscretionaryAcl.SetAccess(AccessControlType.Allow, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); - _securityDescriptor.DiscretionaryAcl.SetAccess(AccessControlType.Allow, sid, rule); + SecurityDescriptor.DiscretionaryAcl.SetAccess(AccessControlType.Allow, sid, rule); break; case AccessControlModification.Remove: //result = _securityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Allow, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); - result = _securityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Allow, sid, rule); + result = SecurityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Allow, sid, rule); break; case AccessControlModification.RemoveAll: - result = _securityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Allow, sid, -1, InheritanceFlags.ContainerInherit, 0, ObjectAceFlags.None, Guid.Empty, Guid.Empty); + result = SecurityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Allow, sid, -1, InheritanceFlags.ContainerInherit, 0, ObjectAceFlags.None, Guid.Empty, Guid.Empty); if (result == false) - { + { throw new InvalidOperationException(SR.InvalidOperation_RemoveFail); } @@ -353,7 +329,7 @@ namespace System.Security.AccessControl case AccessControlModification.RemoveSpecific: //_securityDescriptor.DiscretionaryAcl.RemoveAccessSpecific(AccessControlType.Allow, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); - _securityDescriptor.DiscretionaryAcl.RemoveAccessSpecific(AccessControlType.Allow, sid, rule); + SecurityDescriptor.DiscretionaryAcl.RemoveAccessSpecific(AccessControlType.Allow, sid, rule); break; default: @@ -368,29 +344,29 @@ nameof(modification), { case AccessControlModification.Add: //_securityDescriptor.DiscretionaryAcl.AddAccess(AccessControlType.Deny, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); - _securityDescriptor.DiscretionaryAcl.AddAccess(AccessControlType.Deny, sid, rule); + SecurityDescriptor.DiscretionaryAcl.AddAccess(AccessControlType.Deny, sid, rule); break; case AccessControlModification.Set: //_securityDescriptor.DiscretionaryAcl.SetAccess(AccessControlType.Deny, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); - _securityDescriptor.DiscretionaryAcl.SetAccess(AccessControlType.Deny, sid, rule); + SecurityDescriptor.DiscretionaryAcl.SetAccess(AccessControlType.Deny, sid, rule); break; case AccessControlModification.Reset: - _securityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Allow, sid, -1, InheritanceFlags.ContainerInherit, 0, ObjectAceFlags.None, Guid.Empty, Guid.Empty); + SecurityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Allow, sid, -1, InheritanceFlags.ContainerInherit, 0, ObjectAceFlags.None, Guid.Empty, Guid.Empty); //_securityDescriptor.DiscretionaryAcl.SetAccess(AccessControlType.Deny, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); - _securityDescriptor.DiscretionaryAcl.SetAccess(AccessControlType.Deny, sid, rule); + SecurityDescriptor.DiscretionaryAcl.SetAccess(AccessControlType.Deny, sid, rule); break; case AccessControlModification.Remove: //result = _securityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Deny, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); - result = _securityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Deny, sid, rule); + result = SecurityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Deny, sid, rule); break; case AccessControlModification.RemoveAll: - result = _securityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Deny, sid, -1, InheritanceFlags.ContainerInherit, 0, ObjectAceFlags.None, Guid.Empty, Guid.Empty); + result = SecurityDescriptor.DiscretionaryAcl.RemoveAccess(AccessControlType.Deny, sid, -1, InheritanceFlags.ContainerInherit, 0, ObjectAceFlags.None, Guid.Empty, Guid.Empty); if (result == false) - { + { throw new InvalidOperationException(SR.InvalidOperation_RemoveFail); } @@ -398,7 +374,7 @@ nameof(modification), case AccessControlModification.RemoveSpecific: //_securityDescriptor.DiscretionaryAcl.RemoveAccessSpecific(AccessControlType.Deny, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); - _securityDescriptor.DiscretionaryAcl.RemoveAccessSpecific(AccessControlType.Deny, sid, rule); + SecurityDescriptor.DiscretionaryAcl.RemoveAccessSpecific(AccessControlType.Deny, sid, rule); break; default: @@ -408,7 +384,7 @@ nameof(modification), } } else - { + { throw new ArgumentException(SR.Format(SR.TypeUnrecognized_AccessControl, rule.AccessControlType)); } @@ -424,7 +400,7 @@ nameof(modification), { bool result = true; - if (_securityDescriptor.SystemAcl == null) + if (SecurityDescriptor.SystemAcl == null) { if (modification == AccessControlModification.Remove || modification == AccessControlModification.RemoveAll || modification == AccessControlModification.RemoveSpecific) { @@ -434,7 +410,7 @@ nameof(modification), //_securityDescriptor.SystemAcl = new SystemAcl(IsContainer, IsDS, GenericAcl.AclRevisionDS, 1); //_securityDescriptor.AddControlFlags(ControlFlags.SystemAclPresent); - _securityDescriptor.AddSystemAcl(GenericAcl.AclRevisionDS, 1); + SecurityDescriptor.AddSystemAcl(GenericAcl.AclRevisionDS, 1); } else if ((modification == AccessControlModification.Add || modification == AccessControlModification.Set || modification == AccessControlModification.Reset) && (rule.ObjectFlags != ObjectAceFlags.None)) @@ -442,16 +418,16 @@ nameof(modification), // // This will result in an object ace being added to the sacl, so the sacl revision must be AclRevisionDS // - if (_securityDescriptor.SystemAcl.Revision < GenericAcl.AclRevisionDS) + if (SecurityDescriptor.SystemAcl.Revision < GenericAcl.AclRevisionDS) { // // we need to create a new sacl with the same aces as the existing one but the revision should be AclRevisionDS // - byte[] binaryForm = new byte[_securityDescriptor.SystemAcl.BinaryLength]; - _securityDescriptor.SystemAcl.GetBinaryForm(binaryForm, 0); + byte[] binaryForm = new byte[SecurityDescriptor.SystemAcl.BinaryLength]; + SecurityDescriptor.SystemAcl.GetBinaryForm(binaryForm, 0); binaryForm[0] = GenericAcl.AclRevisionDS; // revision is the first byte of the binary form - _securityDescriptor.SystemAcl = new SystemAcl(IsContainer, IsDS, new RawAcl(binaryForm, 0)); + SecurityDescriptor.SystemAcl = new SystemAcl(IsContainer, IsDS, new RawAcl(binaryForm, 0)); } } @@ -461,29 +437,29 @@ nameof(modification), { case AccessControlModification.Add: //_securityDescriptor.SystemAcl.AddAudit(rule.AuditFlags, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); - _securityDescriptor.SystemAcl.AddAudit(sid, rule); + SecurityDescriptor.SystemAcl.AddAudit(sid, rule); break; case AccessControlModification.Set: //_securityDescriptor.SystemAcl.SetAudit(rule.AuditFlags, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); - _securityDescriptor.SystemAcl.SetAudit(sid, rule); + SecurityDescriptor.SystemAcl.SetAudit(sid, rule); break; case AccessControlModification.Reset: - _securityDescriptor.SystemAcl.RemoveAudit(AuditFlags.Failure | AuditFlags.Success, sid, -1, InheritanceFlags.ContainerInherit, 0, ObjectAceFlags.None, Guid.Empty, Guid.Empty); + SecurityDescriptor.SystemAcl.RemoveAudit(AuditFlags.Failure | AuditFlags.Success, sid, -1, InheritanceFlags.ContainerInherit, 0, ObjectAceFlags.None, Guid.Empty, Guid.Empty); //_securityDescriptor.SystemAcl.SetAudit(rule.AuditFlags, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); - _securityDescriptor.SystemAcl.SetAudit(sid, rule); + SecurityDescriptor.SystemAcl.SetAudit(sid, rule); break; case AccessControlModification.Remove: //result = _securityDescriptor.SystemAcl.RemoveAudit(rule.AuditFlags, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); - result = _securityDescriptor.SystemAcl.RemoveAudit(sid, rule); + result = SecurityDescriptor.SystemAcl.RemoveAudit(sid, rule); break; case AccessControlModification.RemoveAll: - result = _securityDescriptor.SystemAcl.RemoveAudit(AuditFlags.Failure | AuditFlags.Success, sid, -1, InheritanceFlags.ContainerInherit, 0, ObjectAceFlags.None, Guid.Empty, Guid.Empty); + result = SecurityDescriptor.SystemAcl.RemoveAudit(AuditFlags.Failure | AuditFlags.Success, sid, -1, InheritanceFlags.ContainerInherit, 0, ObjectAceFlags.None, Guid.Empty, Guid.Empty); if (result == false) - { + { throw new InvalidOperationException(SR.InvalidOperation_RemoveFail); } @@ -491,7 +467,7 @@ nameof(modification), case AccessControlModification.RemoveSpecific: //_securityDescriptor.SystemAcl.RemoveAuditSpecific(rule.AuditFlags, sid, rule.AccessMask, rule.InheritanceFlags, rule.PropagationFlags, rule.ObjectFlags, rule.ObjectType, rule.InheritedObjectType); - _securityDescriptor.SystemAcl.RemoveAuditSpecific(sid, rule); + SecurityDescriptor.SystemAcl.RemoveAuditSpecific(sid, rule); break; default: @@ -505,9 +481,9 @@ nameof(modification), return result; } - #endregion +#endregion - #region public Methods +#region public Methods public virtual AccessRule AccessRuleFactory(IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type, Guid objectType, Guid inheritedObjectType) { @@ -542,9 +518,9 @@ nameof(modification), //} return ModifyAudit(modification, rule as ObjectAuditRule, out modified); } - #endregion +#endregion - #region Public Methods +#region Public Methods protected void AddAccessRule(ObjectAccessRule rule) { @@ -619,7 +595,7 @@ nameof(modification), try { - if (_securityDescriptor == null) + if (SecurityDescriptor == null) { return true; } @@ -644,7 +620,7 @@ nameof(modification), try { - if (_securityDescriptor == null) + if (SecurityDescriptor == null) { return; } @@ -665,7 +641,7 @@ nameof(modification), throw new ArgumentNullException(nameof(rule)); } - if (_securityDescriptor == null) + if (SecurityDescriptor == null) { return; } @@ -793,6 +769,6 @@ nameof(modification), return GetRules(false, includeExplicit, includeInherited, targetType); } - #endregion +#endregion } } diff --git a/src/libraries/System.IO.FileSystem.AccessControl/tests/DirectoryObjectSecurityTests.cs b/src/libraries/System.IO.FileSystem.AccessControl/tests/DirectoryObjectSecurityTests.cs index ae38f85..d1ff2ba 100644 --- a/src/libraries/System.IO.FileSystem.AccessControl/tests/DirectoryObjectSecurityTests.cs +++ b/src/libraries/System.IO.FileSystem.AccessControl/tests/DirectoryObjectSecurityTests.cs @@ -20,6 +20,30 @@ namespace System.Security.AccessControl private const int ReadAttributeAccessMask = 0x80; [Fact] + public void SetCustomDescriptor_Success() + { + // We didn't allow setting the security descriptor in core due to assembly refactoring. + // GetAccessRules() would throw a null ref after setting the descriptor. We now expose + // the descriptor as a protected property (instead of internal). + // https://github.com/dotnet/corefx/issues/34151 + + var customObjectSecurity = new CustomDirectoryObjectSecurity(); + + // DACL:SDDL_PROTECTED SDDL_AUTO_INHERITED + // (SDDL_ACCESS_ALLOWED;SDDL_OBJECT_INHERIT SDDL_CONTAINER_INHERIT;access mask;;;SDDL_BUILTIN_USERS) + customObjectSecurity.SetSecurityDescriptorSddlForm("D:PAI(A;OICI;0x1200a9;;;BU)"); + var rules = customObjectSecurity.GetAccessRules(true, true, typeof(SecurityIdentifier)); + + Assert.Equal(1, rules.Count); + CustomAccessRule rule = (CustomAccessRule)rules[0]; + // Should be users group + Assert.Equal(rule.IdentityReference.Value, "S-1-5-32-545"); + Assert.Equal(AccessControlType.Allow, rule.AccessControlType); + Assert.Equal(InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, rule.InheritanceFlags); + Assert.Equal(0x1200a9, rule.AccessMaskValue); + } + + [Fact] public void ObjectInitialization_DefaultConstructor_Success() { var customObjectSecurity = new CustomDirectoryObjectSecurity(); diff --git a/src/libraries/System.Security.AccessControl/System.Security.AccessControl.sln b/src/libraries/System.Security.AccessControl/System.Security.AccessControl.sln index 80ad7fa..fa76fec 100644 --- a/src/libraries/System.Security.AccessControl/System.Security.AccessControl.sln +++ b/src/libraries/System.Security.AccessControl/System.Security.AccessControl.sln @@ -26,10 +26,10 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {70FAC855-CAC6-4523-8477-880548D58A1B}.Debug|Any CPU.ActiveCfg = netstandard-Windows_NT-Debug|Any CPU - {70FAC855-CAC6-4523-8477-880548D58A1B}.Debug|Any CPU.Build.0 = netstandard-Windows_NT-Debug|Any CPU - {70FAC855-CAC6-4523-8477-880548D58A1B}.Release|Any CPU.ActiveCfg = netstandard-Windows_NT-Release|Any CPU - {70FAC855-CAC6-4523-8477-880548D58A1B}.Release|Any CPU.Build.0 = netstandard-Windows_NT-Release|Any CPU + {70FAC855-CAC6-4523-8477-880548D58A1B}.Debug|Any CPU.ActiveCfg = netcoreapp-Windows_NT-Debug|Any CPU + {70FAC855-CAC6-4523-8477-880548D58A1B}.Debug|Any CPU.Build.0 = netcoreapp-Windows_NT-Debug|Any CPU + {70FAC855-CAC6-4523-8477-880548D58A1B}.Release|Any CPU.ActiveCfg = netcoreapp-Windows_NT-Release|Any CPU + {70FAC855-CAC6-4523-8477-880548D58A1B}.Release|Any CPU.Build.0 = netcoreapp-Windows_NT-Release|Any CPU {D27FFA1F-B446-4D24-B60A-1F88385CDB6D}.Debug|Any CPU.ActiveCfg = netcoreapp-Windows_NT-Debug|Any CPU {D27FFA1F-B446-4D24-B60A-1F88385CDB6D}.Debug|Any CPU.Build.0 = netcoreapp-Windows_NT-Debug|Any CPU {D27FFA1F-B446-4D24-B60A-1F88385CDB6D}.Release|Any CPU.ActiveCfg = netcoreapp-Windows_NT-Release|Any CPU diff --git a/src/libraries/System.Security.AccessControl/ref/System.Security.AccessControl.cs b/src/libraries/System.Security.AccessControl/ref/System.Security.AccessControl.cs index 0e34e54..9cf13d0 100644 --- a/src/libraries/System.Security.AccessControl/ref/System.Security.AccessControl.cs +++ b/src/libraries/System.Security.AccessControl/ref/System.Security.AccessControl.cs @@ -401,6 +401,7 @@ namespace System.Security.AccessControl public virtual void PurgeAuditRules(System.Security.Principal.IdentityReference identity) { } protected void ReadLock() { } protected void ReadUnlock() { } + protected System.Security.AccessControl.CommonSecurityDescriptor SecurityDescriptor { get { throw null; } } public void SetAccessRuleProtection(bool isProtected, bool preserveInheritance) { } public void SetAuditRuleProtection(bool isProtected, bool preserveInheritance) { } public void SetGroup(System.Security.Principal.IdentityReference identity) { } diff --git a/src/libraries/System.Security.AccessControl/src/System/Security/AccessControl/ObjectSecurity.cs b/src/libraries/System.Security.AccessControl/src/System/Security/AccessControl/ObjectSecurity.cs index c284b32..d2a01db 100644 --- a/src/libraries/System.Security.AccessControl/src/System/Security/AccessControl/ObjectSecurity.cs +++ b/src/libraries/System.Security.AccessControl/src/System/Security/AccessControl/ObjectSecurity.cs @@ -9,12 +9,8 @@ ** ===========================================================*/ -using Microsoft.Win32; -using System; -using System.Collections; using System.Diagnostics; using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security.Principal; using System.Threading; @@ -39,7 +35,7 @@ namespace System.Security.AccessControl private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); - internal CommonSecurityDescriptor _securityDescriptor; + internal readonly CommonSecurityDescriptor _securityDescriptor; private bool _ownerModified = false; private bool _groupModified = false; @@ -147,6 +143,11 @@ namespace System.Security.AccessControl #region Protected Properties and Methods + /// + /// Gets the security descriptor for this instance. + /// + protected CommonSecurityDescriptor SecurityDescriptor => _securityDescriptor; + protected void ReadLock() { _lock.EnterReadLock(); diff --git a/src/libraries/System.Security.AccessControl/tests/System.Security.AccessControl.Tests.csproj b/src/libraries/System.Security.AccessControl/tests/System.Security.AccessControl.Tests.csproj index b0804d1..b1957e3 100644 --- a/src/libraries/System.Security.AccessControl/tests/System.Security.AccessControl.Tests.csproj +++ b/src/libraries/System.Security.AccessControl/tests/System.Security.AccessControl.Tests.csproj @@ -2,7 +2,7 @@ {70FAC855-CAC6-4523-8477-880548D58A1B} Linux;NetBSD;OSX - netcoreapp-Windows_NT-Debug;netcoreapp-Windows_NT-Release;netfx-Windows_NT-Debug;netfx-Windows_NT-Release;uap-Windows_NT-Debug;nuap-Windows_NT-Release + netcoreapp-Windows_NT-Debug;netcoreapp-Windows_NT-Release;netfx-Windows_NT-Debug;netfx-Windows_NT-Release;uap-Windows_NT-Debug;uap-Windows_NT-Release -- 2.7.4