diff options
author | James Bellinger <jfb@zer7.com> | 2012-07-04 02:57:27 +0400 |
---|---|---|
committer | James Bellinger <jfb@zer7.com> | 2012-07-08 02:45:06 +0400 |
commit | 9322e0d16b0edc054947279af34d3c7afb286c89 (patch) | |
tree | ae2d9d5cc9ad53599e52d721775ab6cfc2acd6f3 /mcs/class/corlib/System.Security.AccessControl | |
parent | 5817dada36f80f0e5947aeba6847c6123bed7db5 (diff) |
ACLs now work on Windows. Tests all the way up to DirectorySecurityTest and FileSecurityTest.
NativeObjectSecurity is implemented.
I've done it in such a way that, for OSes that do not have a unified API for all ACLs,
overrides can be done in subclasses such as FileSystemSecurity without trouble.
ObjectSecurity, CommonObjectSecurity, and DirectoryObjectSecurity all implemented.
MutexSecurity, PipeSecurity, etc. all just add type specialization and nothing else. Implemented all of these as well.
Access and Audit rules now correctly use NTAccount in their string overloads (see unit tests).
The constructors all provide correct AccessMasks now. In other words, these classes are all now un-broken/no longer stubs.
More unit tests for CommonSecurityDescriptor and fixes to pass them.
A few had checks that were redundant (implemented by (Authorization|Audit|Access)Rule) as well. These have been removed.
The Allow Everyone Full Access default for null DiscretionaryAcls in CommonSecurityDescriptor is, I think,
properly implemented. This required some changes to GenericSecurityDescriptor as well, but now Mono matches
MS.NET on GetSddl/GetBinaryForm for null DiscretionaryAcl including roundtrip.
What's still missing:
(1) CommonAcl's RemoveAccess/RemoveAudit. RemoveAll and RemoveSpecific work so it's not a big issue.
(2) CommonAcl merging will not yet try to merge a CommonAce together with an ObjectAce.
(3) The various *Security constructors. Get/SetAccessControl work on files and directories.
However, you still have to create and then set. I am not too familiar with Mono runtime internal
calls, but to someone who is: If the SECURITY_ATTRIBUTES parameter to Create*'s lpSecurityDescriptor
pointed to the output of GenericSecurityDescriptor's GetBinaryForm, that would be a complete
implementation.
Diffstat (limited to 'mcs/class/corlib/System.Security.AccessControl')
32 files changed, 1334 insertions, 522 deletions
diff --git a/mcs/class/corlib/System.Security.AccessControl/AccessRule.cs b/mcs/class/corlib/System.Security.AccessControl/AccessRule.cs index c9ebdf8525e..414255d6c96 100644 --- a/mcs/class/corlib/System.Security.AccessControl/AccessRule.cs +++ b/mcs/class/corlib/System.Security.AccessControl/AccessRule.cs @@ -42,20 +42,9 @@ namespace System.Security.AccessControl { : base (identity, accessMask, isInherited, inheritanceFlags, propagationFlags) { - if (!(identity is SecurityIdentifier)) { - throw new ArgumentException ("identity"); - } if (type < AccessControlType.Allow || type > AccessControlType.Deny) { - throw new ArgumentException ("type"); - } - - - if (accessMask == 0) { - /* FIXME: check inheritance and - * propagation flags too - */ - throw new ArgumentOutOfRangeException (); + throw new ArgumentException ("Invalid access control type.", "type"); } this.type = type; diff --git a/mcs/class/corlib/System.Security.AccessControl/AuditRule.cs b/mcs/class/corlib/System.Security.AccessControl/AuditRule.cs index d346c20fa2e..0ea9ad243d3 100644 --- a/mcs/class/corlib/System.Security.AccessControl/AuditRule.cs +++ b/mcs/class/corlib/System.Security.AccessControl/AuditRule.cs @@ -42,17 +42,8 @@ namespace System.Security.AccessControl { : base (identity, accessMask, isInherited, inheritanceFlags, propagationFlags) { - if (!(identity is SecurityIdentifier)) { - /* FIXME: check auditFlags too */ - throw new ArgumentException ("identity"); - } - - if (accessMask == 0) { - /* FIXME: check inheritance and - * propagation flags too - */ - throw new ArgumentOutOfRangeException (); - } + if (auditFlags != ((AuditFlags.Success | AuditFlags.Failure) & auditFlags)) + throw new ArgumentException ("Invalid audit flags.", "auditFlags"); this.auditFlags = auditFlags; } diff --git a/mcs/class/corlib/System.Security.AccessControl/AuthorizationRule.cs b/mcs/class/corlib/System.Security.AccessControl/AuthorizationRule.cs index 0a0e8813d13..12c3941390f 100644 --- a/mcs/class/corlib/System.Security.AccessControl/AuthorizationRule.cs +++ b/mcs/class/corlib/System.Security.AccessControl/AuthorizationRule.cs @@ -48,6 +48,9 @@ namespace System.Security.AccessControl { InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags) { + if (null == identity) + throw new ArgumentNullException ("identity"); + if (!(identity is SecurityIdentifier) && !(identity is NTAccount)) throw new ArgumentException ("identity"); diff --git a/mcs/class/corlib/System.Security.AccessControl/AuthorizationRuleCollection.cs b/mcs/class/corlib/System.Security.AccessControl/AuthorizationRuleCollection.cs index a8a453332b3..a7975c16d21 100644 --- a/mcs/class/corlib/System.Security.AccessControl/AuthorizationRuleCollection.cs +++ b/mcs/class/corlib/System.Security.AccessControl/AuthorizationRuleCollection.cs @@ -33,7 +33,7 @@ namespace System.Security.AccessControl { public sealed class AuthorizationRuleCollection : ReadOnlyCollectionBase { - private AuthorizationRuleCollection (AuthorizationRule [] rules) + internal AuthorizationRuleCollection (AuthorizationRule [] rules) { InnerList.AddRange (rules); } diff --git a/mcs/class/corlib/System.Security.AccessControl/CommonAcl.cs b/mcs/class/corlib/System.Security.AccessControl/CommonAcl.cs index 64a5db201aa..df52d498809 100644 --- a/mcs/class/corlib/System.Security.AccessControl/CommonAcl.cs +++ b/mcs/class/corlib/System.Security.AccessControl/CommonAcl.cs @@ -72,10 +72,10 @@ namespace System.Security.AccessControl is_container = isContainer; is_ds = isDS; raw_acl = rawAcl; - CleanAndRetestCanonicity (); + CanonicalizeAndClearAefa (); } - bool is_canonical, is_container, is_ds; + bool is_aefa, is_canonical, is_container, is_ds; internal RawAcl raw_acl; public override sealed int BinaryLength { @@ -98,12 +98,18 @@ namespace System.Security.AccessControl get { return is_ds; } } + // See CommonSecurityDescriptorTest's AefaModifiedFlagIsStoredOnDiscretionaryAcl unit test. + internal bool IsAefa { + get { return is_aefa; } + set { is_aefa = value; } + } + public override sealed byte Revision { get { return raw_acl.Revision; } } public override sealed GenericAce this[int index] { - get { return raw_acl [index]; } + get { return CopyAce (raw_acl [index]); } set { throw new NotSupportedException (); } } @@ -130,7 +136,7 @@ namespace System.Security.AccessControl throw new InvalidOperationException("ACL is not canonical."); } - internal void CleanAndRetestCanonicity () + internal void CanonicalizeAndClearAefa () { RemoveAces<GenericAce> (IsAceMeaningless); @@ -140,6 +146,8 @@ namespace System.Security.AccessControl ApplyCanonicalSortToExplicitAces (); MergeExplicitAces (); } + + IsAefa = false; } internal virtual bool IsAceMeaningless (GenericAce ace) @@ -191,9 +199,9 @@ namespace System.Security.AccessControl { int i; for (i = 0; i < Count; i ++) { - if (this [i].IsInherited) break; + if (raw_acl [i].IsInherited) break; - QualifiedAce ace = this [i] as QualifiedAce; + QualifiedAce ace = raw_acl [i] as QualifiedAce; if (ace == null || ace.AceQualifier != AceQualifier.AccessDenied) break; } return i; @@ -203,7 +211,7 @@ namespace System.Security.AccessControl { int i; for (i = 0; i < Count; i ++) - if (this [i].IsInherited) break; + if (raw_acl [i].IsInherited) break; return i; } @@ -386,8 +394,15 @@ namespace System.Security.AccessControl RequireCanonicity (); int pos = GetAceInsertPosition (newAce.AceQualifier); - raw_acl.InsertAce (pos, newAce); - CleanAndRetestCanonicity (); + raw_acl.InsertAce (pos, CopyAce (newAce)); + CanonicalizeAndClearAefa (); + } + + GenericAce CopyAce (GenericAce ace) + { + byte[] binaryForm = new byte[ace.BinaryLength]; + ace.GetBinaryForm (binaryForm, 0); + return GenericAce.CreateFromBinaryForm (binaryForm, 0); } internal abstract int GetAceInsertPosition (AceQualifier aceQualifier); @@ -435,7 +450,7 @@ namespace System.Security.AccessControl if (ace.AuditFlags != auditFlags) return false; return true; }); - CleanAndRetestCanonicity (); + CanonicalizeAndClearAefa (); } internal void RemoveAceSpecific (AceQualifier aceQualifier, @@ -473,7 +488,7 @@ namespace System.Security.AccessControl if (ace.InheritedObjectAceType != objectType) return false; return true; }); - CleanAndRetestCanonicity (); + CanonicalizeAndClearAefa (); } internal void SetAce (AceQualifier aceQualifier, @@ -513,7 +528,7 @@ namespace System.Security.AccessControl return oldAce.AceQualifier == newAce.AceQualifier && oldAce.SecurityIdentifier == newAce.SecurityIdentifier; }); - CleanAndRetestCanonicity (); + CanonicalizeAndClearAefa (); AddAce (newAce); } diff --git a/mcs/class/corlib/System.Security.AccessControl/CommonObjectSecurity.cs b/mcs/class/corlib/System.Security.AccessControl/CommonObjectSecurity.cs index 3addb6c5f56..bba69b45df7 100644 --- a/mcs/class/corlib/System.Security.AccessControl/CommonObjectSecurity.cs +++ b/mcs/class/corlib/System.Security.AccessControl/CommonObjectSecurity.cs @@ -4,8 +4,10 @@ // Authors: // Dick Porter <dick@ximian.com> // Atsushi Enomoto <atsushi@ximian.com> +// James Bellinger <jfb@zer7.com> // // Copyright (C) 2005-2007 Novell, Inc (http://www.novell.com) +// Copyright (C) 2012 James Bellinger // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -29,153 +31,215 @@ using System.Collections.Generic; -namespace System.Security.AccessControl { - - [MonoTODO ("required for NativeObjectSecurity - implementation is missing")] - public abstract class CommonObjectSecurity : ObjectSecurity { - +namespace System.Security.AccessControl +{ + public abstract class CommonObjectSecurity : ObjectSecurity + { protected CommonObjectSecurity (bool isContainer) : base (isContainer, false) { } - List<AccessRule> access_rules = new List<AccessRule> (); - List<AuditRule> audit_rules = new List<AuditRule> (); + internal CommonObjectSecurity (CommonSecurityDescriptor securityDescriptor) + : base (securityDescriptor) + { + } public AuthorizationRuleCollection GetAccessRules (bool includeExplicit, bool includeInherited, Type targetType) { - throw new NotImplementedException (); + return InternalGetAccessRules (includeExplicit, includeInherited, targetType); } public AuthorizationRuleCollection GetAuditRules (bool includeExplicit, bool includeInherited, Type targetType) { - throw new NotImplementedException (); + return InternalGetAuditRules (includeExplicit, includeInherited, targetType); } - // Access - protected void AddAccessRule (AccessRule rule) { - access_rules.Add (rule); - AccessRulesModified = true; + bool modified; + ModifyAccess (AccessControlModification.Add, rule, out modified); } protected bool RemoveAccessRule (AccessRule rule) { - throw new NotImplementedException (); + bool modified; + return ModifyAccess (AccessControlModification.Remove, rule, out modified); } protected void RemoveAccessRuleAll (AccessRule rule) { - throw new NotImplementedException (); + bool modified; + ModifyAccess (AccessControlModification.RemoveAll, rule, out modified); } protected void RemoveAccessRuleSpecific (AccessRule rule) { - throw new NotImplementedException (); + bool modified; + ModifyAccess (AccessControlModification.RemoveSpecific, rule, out modified); } protected void ResetAccessRule (AccessRule rule) { - throw new NotImplementedException (); + bool modified; + ModifyAccess (AccessControlModification.Reset, rule, out modified); } protected void SetAccessRule (AccessRule rule) { - throw new NotImplementedException (); - } + bool modified; + ModifyAccess (AccessControlModification.Set, rule, out modified); + } protected override bool ModifyAccess (AccessControlModification modification, AccessRule rule, out bool modified) - { - foreach (AccessRule r in access_rules) { - if (rule != r) - continue; + { + if (null == rule) + throw new ArgumentNullException ("rule"); + + modified = true; + + WriteLock (); + try { switch (modification) { case AccessControlModification.Add: - AddAccessRule (rule); + descriptor.DiscretionaryAcl.AddAccess (rule.AccessControlType, + SidFromIR (rule.IdentityReference), + rule.AccessMask, + rule.InheritanceFlags, + rule.PropagationFlags); break; case AccessControlModification.Set: - SetAccessRule (rule); + descriptor.DiscretionaryAcl.SetAccess (rule.AccessControlType, + SidFromIR (rule.IdentityReference), + rule.AccessMask, + rule.InheritanceFlags, + rule.PropagationFlags); break; case AccessControlModification.Reset: - ResetAccessRule (rule); - break; + PurgeAccessRules (rule.IdentityReference); + goto case AccessControlModification.Add; case AccessControlModification.Remove: - RemoveAccessRule (rule); + modified = descriptor.DiscretionaryAcl.RemoveAccess (rule.AccessControlType, + SidFromIR (rule.IdentityReference), + rule.AccessMask, + rule.InheritanceFlags, + rule.PropagationFlags); break; case AccessControlModification.RemoveAll: - RemoveAccessRuleAll (rule); + PurgeAccessRules (rule.IdentityReference); break; case AccessControlModification.RemoveSpecific: - RemoveAccessRuleSpecific (rule); + descriptor.DiscretionaryAcl.RemoveAccessSpecific (rule.AccessControlType, + SidFromIR (rule.IdentityReference), + rule.AccessMask, + rule.InheritanceFlags, + rule.PropagationFlags); break; + default: + throw new ArgumentOutOfRangeException ("modification"); } - modified = true; - return true; + + if (modified) AccessRulesModified = true; + } finally { + WriteUnlock (); } - modified = false; - return false; + + return modified; } - // Audit - protected void AddAuditRule (AuditRule rule) { - audit_rules.Add (rule); - AuditRulesModified = true; + bool modified; + ModifyAudit (AccessControlModification.Add, rule, out modified); } protected bool RemoveAuditRule (AuditRule rule) { - throw new NotImplementedException (); + bool modified; + return ModifyAudit (AccessControlModification.Remove, rule, out modified); } protected void RemoveAuditRuleAll (AuditRule rule) { - throw new NotImplementedException (); + bool modified; + ModifyAudit (AccessControlModification.RemoveAll, rule, out modified); } protected void RemoveAuditRuleSpecific (AuditRule rule) { - throw new NotImplementedException (); + bool modified; + ModifyAudit (AccessControlModification.RemoveSpecific, rule, out modified); } protected void SetAuditRule (AuditRule rule) { - throw new NotImplementedException (); + bool modified; + ModifyAudit (AccessControlModification.Set, rule, out modified); } protected override bool ModifyAudit (AccessControlModification modification, AuditRule rule, out bool modified) { - foreach (AuditRule r in audit_rules) { - if (rule != r) - continue; + if (null == rule) + throw new ArgumentNullException ("rule"); + + modified = true; + + WriteLock (); + try { switch (modification) { case AccessControlModification.Add: - AddAuditRule (rule); + if (null == descriptor.SystemAcl) + descriptor.SystemAcl = new SystemAcl (IsContainer, IsDS, 1); + + descriptor.SystemAcl.AddAudit (rule.AuditFlags, + SidFromIR (rule.IdentityReference), + rule.AccessMask, + rule.InheritanceFlags, + rule.PropagationFlags); break; case AccessControlModification.Set: - SetAuditRule (rule); + if (null == descriptor.SystemAcl) + descriptor.SystemAcl = new SystemAcl (IsContainer, IsDS, 1); + + descriptor.SystemAcl.SetAudit (rule.AuditFlags, + SidFromIR (rule.IdentityReference), + rule.AccessMask, + rule.InheritanceFlags, + rule.PropagationFlags); + break; + case AccessControlModification.Reset: break; - //case AccessControlModification.Reset: - // ResetAuditRule (rule); - // break; case AccessControlModification.Remove: - RemoveAuditRule (rule); + if (null == descriptor.SystemAcl) + modified = false; + else + modified = descriptor.SystemAcl.RemoveAudit (rule.AuditFlags, + SidFromIR (rule.IdentityReference), + rule.AccessMask, + rule.InheritanceFlags, + rule.PropagationFlags); break; case AccessControlModification.RemoveAll: - RemoveAuditRuleAll (rule); + PurgeAuditRules (rule.IdentityReference); break; case AccessControlModification.RemoveSpecific: - RemoveAuditRuleSpecific (rule); + if (null != descriptor.SystemAcl) + descriptor.SystemAcl.RemoveAuditSpecific (rule.AuditFlags, + SidFromIR (rule.IdentityReference), + rule.AccessMask, + rule.InheritanceFlags, + rule.PropagationFlags); break; + default: + throw new ArgumentOutOfRangeException ("modification"); } - AuditRulesModified = true; - modified = true; - return true; + + if (modified) AuditRulesModified = true; + } finally { + WriteUnlock (); } - modified = false; - return false; + + return modified; } } } diff --git a/mcs/class/corlib/System.Security.AccessControl/CommonSecurityDescriptor.cs b/mcs/class/corlib/System.Security.AccessControl/CommonSecurityDescriptor.cs index ce5fb6cb2d8..60bb7b2cde5 100644 --- a/mcs/class/corlib/System.Security.AccessControl/CommonSecurityDescriptor.cs +++ b/mcs/class/corlib/System.Security.AccessControl/CommonSecurityDescriptor.cs @@ -35,13 +35,13 @@ namespace System.Security.AccessControl { public sealed class CommonSecurityDescriptor : GenericSecurityDescriptor { - bool isContainer; - bool isDS; + bool is_container; + bool is_ds; ControlFlags flags; SecurityIdentifier owner; SecurityIdentifier group; - SystemAcl systemAcl; - DiscretionaryAcl discretionaryAcl; + SystemAcl system_acl; + DiscretionaryAcl discretionary_acl; public CommonSecurityDescriptor (bool isContainer, bool isDS, RawSecurityDescriptor rawSecurityDescriptor) { @@ -95,14 +95,14 @@ namespace System.Security.AccessControl SystemAcl systemAcl, DiscretionaryAcl discretionaryAcl) { - IsContainer = isContainer; - IsDS = isDS; + this.flags = flags & ~ControlFlags.SystemAclPresent; + this.is_container = isContainer; + this.is_ds = isDS; + Owner = owner; Group = group; SystemAcl = systemAcl; DiscretionaryAcl = discretionaryAcl; - - this.flags = flags & ~ControlFlags.SystemAclPresent; } public override ControlFlags ControlFlags { @@ -119,26 +119,32 @@ namespace System.Security.AccessControl } public DiscretionaryAcl DiscretionaryAcl { - get { return discretionaryAcl; } + get { return discretionary_acl; } set { if (value == null) { value = new DiscretionaryAcl (IsContainer, IsDS, 1); value.AddAccess (AccessControlType.Allow, new SecurityIdentifier ("WD"), -1, - InheritanceFlags.None, PropagationFlags.None); + IsContainer ? InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit + : InheritanceFlags.None, PropagationFlags.None); + value.IsAefa = true; } CheckAclConsistency (value); - discretionaryAcl = value; + discretionary_acl = value; } } + internal override GenericAcl InternalDacl { + get { return DiscretionaryAcl; } + } + public override SecurityIdentifier Group { - get { return group; } + get { return group; } set { group = value; } } public bool IsContainer { - get { return isContainer; } + get { return is_container; } } public bool IsDiscretionaryAclCanonical { @@ -146,7 +152,7 @@ namespace System.Security.AccessControl } public bool IsDS { - get { return isDS; } + get { return is_ds; } } public bool IsSystemAclCanonical { @@ -154,20 +160,24 @@ namespace System.Security.AccessControl } public override SecurityIdentifier Owner { - get { return owner; } + get { return owner; } set { owner = value; } } public SystemAcl SystemAcl { - get { return systemAcl; } + get { return system_acl; } set { if (value != null) CheckAclConsistency (value); - systemAcl = value; + system_acl = value; } } + internal override GenericAcl InternalSacl { + get { return SystemAcl; } + } + public void PurgeAccessControl (SecurityIdentifier sid) { DiscretionaryAcl.Purge (sid); @@ -182,6 +192,8 @@ namespace System.Security.AccessControl public void SetDiscretionaryAclProtection (bool isProtected, bool preserveInheritance) { + DiscretionaryAcl.IsAefa = false; + if (!isProtected) { flags &= ~ControlFlags.DiscretionaryAclProtected; return; @@ -201,18 +213,22 @@ namespace System.Security.AccessControl } flags |= ControlFlags.SystemAclProtected; - if (!preserveInheritance) + if (!preserveInheritance && SystemAcl != null) SystemAcl.RemoveInheritedAces (); } void CheckAclConsistency (CommonAcl acl) { if (IsContainer != acl.IsContainer) - throw new ArgumentExcetion ("IsContainer must match between descriptor and ACL."); + throw new ArgumentException ("IsContainer must match between descriptor and ACL."); if (IsDS != acl.IsDS) throw new ArgumentException ("IsDS must match between descriptor and ACL."); } + + internal override bool DaclIsUnmodifiedAefa { + get { return DiscretionaryAcl.IsAefa; } + } } } diff --git a/mcs/class/corlib/System.Security.AccessControl/CryptoKeyAccessRule.cs b/mcs/class/corlib/System.Security.AccessControl/CryptoKeyAccessRule.cs index 42327131b44..c6b50fa077e 100644 --- a/mcs/class/corlib/System.Security.AccessControl/CryptoKeyAccessRule.cs +++ b/mcs/class/corlib/System.Security.AccessControl/CryptoKeyAccessRule.cs @@ -33,26 +33,23 @@ namespace System.Security.AccessControl { public sealed class CryptoKeyAccessRule : AccessRule { - CryptoKeyRights rights; - public CryptoKeyAccessRule (IdentityReference identity, CryptoKeyRights cryptoKeyRights, AccessControlType type) - // FIXME: accessMask=0 likely causes an error - : base (identity, 0, false, InheritanceFlags.None, PropagationFlags.None, AccessControlType.Allow) + : base (identity, (int)cryptoKeyRights, false, + InheritanceFlags.None, PropagationFlags.None, AccessControlType.Allow) { - this.rights = cryptoKeyRights; } public CryptoKeyAccessRule (string identity, CryptoKeyRights cryptoKeyRights, AccessControlType type) - : this (new SecurityIdentifier (identity), cryptoKeyRights, type) + : this (new NTAccount (identity), cryptoKeyRights, type) { } public CryptoKeyRights CryptoKeyRights { - get { return rights; } + get { return (CryptoKeyRights)AccessMask; } } } } diff --git a/mcs/class/corlib/System.Security.AccessControl/CryptoKeyAuditRule.cs b/mcs/class/corlib/System.Security.AccessControl/CryptoKeyAuditRule.cs index f2b4a85ded8..a740747e412 100644 --- a/mcs/class/corlib/System.Security.AccessControl/CryptoKeyAuditRule.cs +++ b/mcs/class/corlib/System.Security.AccessControl/CryptoKeyAuditRule.cs @@ -33,25 +33,22 @@ namespace System.Security.AccessControl { public sealed class CryptoKeyAuditRule : AuditRule { - CryptoKeyRights rights; - public CryptoKeyAuditRule (IdentityReference identity, CryptoKeyRights cryptoKeyRights, AuditFlags flags) - : base (identity, 0, false, InheritanceFlags.None, PropagationFlags.None, flags) + : base (identity, (int)cryptoKeyRights, false, InheritanceFlags.None, PropagationFlags.None, flags) { - this.rights = cryptoKeyRights; } public CryptoKeyAuditRule (string identity, CryptoKeyRights cryptoKeyRights, AuditFlags flags) - : this (new SecurityIdentifier (identity), cryptoKeyRights, flags) + : this (new NTAccount (identity), cryptoKeyRights, flags) { } public CryptoKeyRights CryptoKeyRights { - get { return rights; } + get { return (CryptoKeyRights)AccessMask; } } } } diff --git a/mcs/class/corlib/System.Security.AccessControl/CryptoKeySecurity.cs b/mcs/class/corlib/System.Security.AccessControl/CryptoKeySecurity.cs index a275ba28520..40ac82ba4e1 100644 --- a/mcs/class/corlib/System.Security.AccessControl/CryptoKeySecurity.cs +++ b/mcs/class/corlib/System.Security.AccessControl/CryptoKeySecurity.cs @@ -5,8 +5,10 @@ // Sebastien Pouliot <sebastien@ximian.com> // Dick Porter <dick@ximian.com> // Atsushi Enomoto <atsushi@ximian.com> +// James Bellinger <jfb@zer7.com> // // Copyright (C) 2005-2007 Novell, Inc (http://www.novell.com) +// Copyright (C) 2012 James Bellinger // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -34,17 +36,15 @@ namespace System.Security.AccessControl { public sealed class CryptoKeySecurity : NativeObjectSecurity { -// CommonSecurityDescriptor securityDescriptor; - - [MonoTODO] public CryptoKeySecurity () + : base (false, ResourceType.Unknown) { } - [MonoTODO] public CryptoKeySecurity (CommonSecurityDescriptor securityDescriptor) + : base (securityDescriptor, ResourceType.Unknown) { -// this.securityDescriptor = securityDescriptor; + } public override Type AccessRightType { @@ -59,84 +59,73 @@ namespace System.Security.AccessControl get { return typeof (CryptoKeyAuditRule); } } - // AccessRule - - public override sealed AccessRule AccessRuleFactory (IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type) + public override sealed AccessRule AccessRuleFactory (IdentityReference identityReference, int accessMask, + bool isInherited, InheritanceFlags inheritanceFlags, + PropagationFlags propagationFlags, AccessControlType type) { return new CryptoKeyAccessRule (identityReference, (CryptoKeyRights) accessMask, type); } - [MonoTODO] public void AddAccessRule (CryptoKeyAccessRule rule) { - throw new NotImplementedException (); + AddAccessRule ((AccessRule)rule); } - [MonoTODO] public bool RemoveAccessRule (CryptoKeyAccessRule rule) { - throw new NotImplementedException (); + return RemoveAccessRule ((AccessRule)rule); } - [MonoTODO] public void RemoveAccessRuleAll (CryptoKeyAccessRule rule) { - throw new NotImplementedException (); + RemoveAccessRuleAll ((AccessRule)rule); } - [MonoTODO] public void RemoveAccessRuleSpecific (CryptoKeyAccessRule rule) { - throw new NotImplementedException (); + RemoveAccessRuleSpecific ((AccessRule)rule); } - [MonoTODO] public void ResetAccessRule (CryptoKeyAccessRule rule) { - throw new NotImplementedException (); + ResetAccessRule ((AccessRule)rule); } - [MonoTODO] public void SetAccessRule (CryptoKeyAccessRule rule) { - throw new NotImplementedException (); + SetAccessRule ((AccessRule)rule); } - // AuditRule - - public override sealed AuditRule AuditRuleFactory (IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags flags) + public override sealed AuditRule AuditRuleFactory (IdentityReference identityReference, int accessMask, + bool isInherited, InheritanceFlags inheritanceFlags, + PropagationFlags propagationFlags, AuditFlags flags) { return new CryptoKeyAuditRule (identityReference, (CryptoKeyRights) accessMask, flags); } - [MonoTODO] public void AddAuditRule (CryptoKeyAuditRule rule) { - throw new NotImplementedException (); + AddAuditRule ((AuditRule)rule); } - [MonoTODO] public bool RemoveAuditRule (CryptoKeyAuditRule rule) { - throw new NotImplementedException (); + return RemoveAuditRule((AuditRule)rule); } - [MonoTODO] public void RemoveAuditRuleAll (CryptoKeyAuditRule rule) { - throw new NotImplementedException (); + RemoveAuditRuleAll((AuditRule)rule); } - [MonoTODO] public void RemoveAuditRuleSpecific (CryptoKeyAuditRule rule) { - throw new NotImplementedException (); + RemoveAuditRuleSpecific((AuditRule)rule); } - [MonoTODO] public void SetAuditRule (CryptoKeyAuditRule rule) { - throw new NotImplementedException (); + SetAuditRule((AuditRule)rule); } } } diff --git a/mcs/class/corlib/System.Security.AccessControl/DirectoryObjectSecurity.cs b/mcs/class/corlib/System.Security.AccessControl/DirectoryObjectSecurity.cs index ac62eec7069..83d9bab9196 100644 --- a/mcs/class/corlib/System.Security.AccessControl/DirectoryObjectSecurity.cs +++ b/mcs/class/corlib/System.Security.AccessControl/DirectoryObjectSecurity.cs @@ -3,8 +3,10 @@ // // Author: // Dick Porter <dick@ximian.com> +// James Bellinger <jfb@zer7.com> // // Copyright (C) 2006 Novell, Inc (http://www.novell.com) +// Copyright (C) 2012 James Bellinger // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -28,103 +30,294 @@ using System.Security.Principal; -namespace System.Security.AccessControl { - public abstract class DirectoryObjectSecurity : ObjectSecurity { +namespace System.Security.AccessControl +{ + public abstract class DirectoryObjectSecurity : ObjectSecurity + { protected DirectoryObjectSecurity () - : base (false, true) + : base (true, true) { } protected DirectoryObjectSecurity (CommonSecurityDescriptor securityDescriptor) - : base (securityDescriptor != null && securityDescriptor.IsContainer, true) + : base (securityDescriptor) { - if (securityDescriptor == null) - throw new ArgumentNullException ("securityDescriptor"); } - public virtual AccessRule AccessRuleFactory (IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type, Guid objectType, Guid inheritedObjectType) + // For MoMA. NotImplementedException is correct for this base class. + Exception GetNotImplementedException () { - throw new NotImplementedException (); + return new NotImplementedException (); } - public virtual AuditRule AuditRuleFactory (IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags flags, Guid objectType, Guid inheritedObjectType) + public virtual AccessRule AccessRuleFactory (IdentityReference identityReference, int accessMask, + bool isInherited, InheritanceFlags inheritanceFlags, + PropagationFlags propagationFlags, AccessControlType type, + Guid objectType, Guid inheritedObjectType) { - throw new NotImplementedException (); + throw GetNotImplementedException (); } - public AuthorizationRuleCollection GetAccessRules (bool includeExplicit, bool includeInherited, Type targetType) + internal override AccessRule InternalAccessRuleFactory (QualifiedAce ace, Type targetType, + AccessControlType type) { - throw new NotImplementedException (); + ObjectAce oace = ace as ObjectAce; + if (null == oace || ObjectAceFlags.None == oace.ObjectAceFlags) + return base.InternalAccessRuleFactory (ace, targetType, type); + + return AccessRuleFactory (ace.SecurityIdentifier.Translate (targetType), + ace.AccessMask, ace.IsInherited, + ace.InheritanceFlags, ace.PropagationFlags, type, + oace.ObjectAceType, oace.InheritedObjectAceType); } - public AuthorizationRuleCollection GetAuditRules (bool includeExplicit, bool includeInherited, Type targetType) + public virtual AuditRule AuditRuleFactory (IdentityReference identityReference, int accessMask, + bool isInherited, InheritanceFlags inheritanceFlags, + PropagationFlags propagationFlags, AuditFlags flags, + Guid objectType, Guid inheritedObjectType) { - throw new NotImplementedException (); + throw GetNotImplementedException (); } - - protected void AddAccessRule (ObjectAccessRule rule) + + internal override AuditRule InternalAuditRuleFactory (QualifiedAce ace, Type targetType) { - throw new NotImplementedException (); + ObjectAce oace = ace as ObjectAce; + if (null == oace || ObjectAceFlags.None == oace.ObjectAceFlags) + return base.InternalAuditRuleFactory (ace, targetType); + + return AuditRuleFactory (ace.SecurityIdentifier.Translate (targetType), + ace.AccessMask, ace.IsInherited, + ace.InheritanceFlags, ace.PropagationFlags, ace.AuditFlags, + oace.ObjectAceType, oace.InheritedObjectAceType); } - protected void AddAuditRule (ObjectAuditRule rule) + public AuthorizationRuleCollection GetAccessRules (bool includeExplicit, bool includeInherited, Type targetType) { - throw new NotImplementedException (); + return InternalGetAccessRules (includeExplicit, includeInherited, targetType); } - protected override bool ModifyAccess (AccessControlModification modification, AccessRule rule, out bool modified) + public AuthorizationRuleCollection GetAuditRules (bool includeExplicit, bool includeInherited, Type targetType) { - throw new NotImplementedException (); + return InternalGetAuditRules (includeExplicit, includeInherited, targetType); } - protected override bool ModifyAudit (AccessControlModification modification, AuditRule rule, out bool modified) + protected void AddAccessRule (ObjectAccessRule rule) { - throw new NotImplementedException (); + bool modified; + ModifyAccess (AccessControlModification.Add, rule, out modified); } protected bool RemoveAccessRule (ObjectAccessRule rule) { - throw new NotImplementedException (); + bool modified; + return ModifyAccess (AccessControlModification.Remove, rule, out modified); } protected void RemoveAccessRuleAll (ObjectAccessRule rule) { - throw new NotImplementedException (); + bool modified; + ModifyAccess (AccessControlModification.RemoveAll, rule, out modified); } protected void RemoveAccessRuleSpecific (ObjectAccessRule rule) { - throw new NotImplementedException (); + bool modified; + ModifyAccess (AccessControlModification.RemoveSpecific, rule, out modified); } - protected bool RemoveAuditRule (ObjectAuditRule rule) + protected void ResetAccessRule (ObjectAccessRule rule) { - throw new NotImplementedException (); + bool modified; + ModifyAccess (AccessControlModification.Reset, rule, out modified); } - protected void RemoveAuditRuleAll (ObjectAuditRule rule) + protected void SetAccessRule (ObjectAccessRule rule) { - throw new NotImplementedException (); + bool modified; + ModifyAccess (AccessControlModification.Set, rule, out modified); } - protected void RemoveAuditRuleSpecific (ObjectAuditRule rule) + protected override bool ModifyAccess (AccessControlModification modification, AccessRule rule, out bool modified) + { + if (null == rule) + throw new ArgumentNullException ("rule"); + + ObjectAccessRule orule = rule as ObjectAccessRule; + if (null == orule) + throw new ArgumentException ("rule"); + + modified = true; + + WriteLock (); + try { + switch (modification) { + case AccessControlModification.Add: + descriptor.DiscretionaryAcl.AddAccess (orule.AccessControlType, + SidFromIR (orule.IdentityReference), + orule.AccessMask, + orule.InheritanceFlags, + orule.PropagationFlags, + orule.ObjectFlags, + orule.ObjectType, + orule.InheritedObjectType); + break; + case AccessControlModification.Set: + descriptor.DiscretionaryAcl.SetAccess (orule.AccessControlType, + SidFromIR (orule.IdentityReference), + orule.AccessMask, + orule.InheritanceFlags, + orule.PropagationFlags, + orule.ObjectFlags, + orule.ObjectType, + orule.InheritedObjectType); + break; + case AccessControlModification.Reset: + PurgeAccessRules (orule.IdentityReference); + goto case AccessControlModification.Add; + case AccessControlModification.Remove: + modified = descriptor.DiscretionaryAcl.RemoveAccess (orule.AccessControlType, + SidFromIR (orule.IdentityReference), + rule.AccessMask, + orule.InheritanceFlags, + orule.PropagationFlags, + orule.ObjectFlags, + orule.ObjectType, + orule.InheritedObjectType); + break; + case AccessControlModification.RemoveAll: + PurgeAccessRules (orule.IdentityReference); + break; + case AccessControlModification.RemoveSpecific: + descriptor.DiscretionaryAcl.RemoveAccessSpecific (orule.AccessControlType, + SidFromIR (orule.IdentityReference), + orule.AccessMask, + orule.InheritanceFlags, + orule.PropagationFlags, + orule.ObjectFlags, + orule.ObjectType, + orule.InheritedObjectType); + break; + default: + throw new ArgumentOutOfRangeException ("modification"); + } + + if (modified) AccessRulesModified = true; + } finally { + WriteUnlock (); + } + + return modified; + } + + protected void AddAuditRule (ObjectAuditRule rule) { - throw new NotImplementedException (); + bool modified; + ModifyAudit (AccessControlModification.Add, rule, out modified); } - protected void ResetAccessRule (ObjectAccessRule rule) + protected bool RemoveAuditRule (ObjectAuditRule rule) { - throw new NotImplementedException (); + bool modified; + return ModifyAudit (AccessControlModification.Remove, rule, out modified); } - protected void SetAccessRule (ObjectAccessRule rule) + protected void RemoveAuditRuleAll (ObjectAuditRule rule) { - throw new NotImplementedException (); + bool modified; + ModifyAudit (AccessControlModification.RemoveAll, rule, out modified); + } + + protected void RemoveAuditRuleSpecific (ObjectAuditRule rule) + { + bool modified; + ModifyAudit (AccessControlModification.RemoveSpecific, rule, out modified); } protected void SetAuditRule (ObjectAuditRule rule) { - throw new NotImplementedException (); + bool modified; + ModifyAudit (AccessControlModification.Set, rule, out modified); + } + + protected override bool ModifyAudit (AccessControlModification modification, AuditRule rule, out bool modified) + { + if (null == rule) + throw new ArgumentNullException ("rule"); + + ObjectAuditRule orule = rule as ObjectAuditRule; + if (null == orule) + throw new ArgumentException ("rule"); + + modified = true; + + WriteLock (); + try { + switch (modification) { + case AccessControlModification.Add: + if (null == descriptor.SystemAcl) + descriptor.SystemAcl = new SystemAcl (IsContainer, IsDS, 1); + + descriptor.SystemAcl.AddAudit (orule.AuditFlags, + SidFromIR (orule.IdentityReference), + orule.AccessMask, + orule.InheritanceFlags, + orule.PropagationFlags, + orule.ObjectFlags, + orule.ObjectType, + orule.InheritedObjectType); + break; + case AccessControlModification.Set: + if (null == descriptor.SystemAcl) + descriptor.SystemAcl = new SystemAcl (IsContainer, IsDS, 1); + + descriptor.SystemAcl.SetAudit (orule.AuditFlags, + SidFromIR (orule.IdentityReference), + orule.AccessMask, + orule.InheritanceFlags, + orule.PropagationFlags, + orule.ObjectFlags, + orule.ObjectType, + orule.InheritedObjectType); + break; + case AccessControlModification.Reset: + break; + case AccessControlModification.Remove: + if (null == descriptor.SystemAcl) + modified = false; + else + modified = descriptor.SystemAcl.RemoveAudit (orule.AuditFlags, + SidFromIR (orule.IdentityReference), + orule.AccessMask, + orule.InheritanceFlags, + orule.PropagationFlags, + orule.ObjectFlags, + orule.ObjectType, + orule.InheritedObjectType); + break; + case AccessControlModification.RemoveAll: + PurgeAuditRules (orule.IdentityReference); + break; + case AccessControlModification.RemoveSpecific: + if (null != descriptor.SystemAcl) + descriptor.SystemAcl.RemoveAuditSpecific (orule.AuditFlags, + SidFromIR (orule.IdentityReference), + orule.AccessMask, + orule.InheritanceFlags, + orule.PropagationFlags, + orule.ObjectFlags, + orule.ObjectType, + orule.InheritedObjectType); + break; + default: + throw new ArgumentOutOfRangeException ("modification"); + } + + if (modified) AuditRulesModified = true; + } finally { + WriteUnlock (); + } + + return modified; } } } diff --git a/mcs/class/corlib/System.Security.AccessControl/DirectorySecurity.cs b/mcs/class/corlib/System.Security.AccessControl/DirectorySecurity.cs index a0a6d34dcfd..b4acd323834 100644 --- a/mcs/class/corlib/System.Security.AccessControl/DirectorySecurity.cs +++ b/mcs/class/corlib/System.Security.AccessControl/DirectorySecurity.cs @@ -27,18 +27,18 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // -namespace System.Security.AccessControl { - public sealed class DirectorySecurity : FileSystemSecurity { +namespace System.Security.AccessControl +{ + public sealed class DirectorySecurity : FileSystemSecurity + { public DirectorySecurity () : base (true) { - throw new PlatformNotSupportedException (); } public DirectorySecurity (string name, AccessControlSections includeSections) : base (true, name, includeSections) { - throw new PlatformNotSupportedException (); } } } diff --git a/mcs/class/corlib/System.Security.AccessControl/DiscretionaryAcl.cs b/mcs/class/corlib/System.Security.AccessControl/DiscretionaryAcl.cs index ba7167c3d04..1d3156fc57a 100644 --- a/mcs/class/corlib/System.Security.AccessControl/DiscretionaryAcl.cs +++ b/mcs/class/corlib/System.Security.AccessControl/DiscretionaryAcl.cs @@ -72,6 +72,7 @@ namespace System.Security.AccessControl objectFlags, objectType, inheritedObjectType); } + [MonoTODO] public bool RemoveAccess (AccessControlType accessType, SecurityIdentifier sid, int accessMask, @@ -81,6 +82,7 @@ namespace System.Security.AccessControl throw new NotImplementedException (); } + [MonoTODO] public bool RemoveAccess (AccessControlType accessType, SecurityIdentifier sid, int accessMask, diff --git a/mcs/class/corlib/System.Security.AccessControl/EventWaitHandleAccessRule.cs b/mcs/class/corlib/System.Security.AccessControl/EventWaitHandleAccessRule.cs index f51994b8fc3..1de2005c6a9 100644 --- a/mcs/class/corlib/System.Security.AccessControl/EventWaitHandleAccessRule.cs +++ b/mcs/class/corlib/System.Security.AccessControl/EventWaitHandleAccessRule.cs @@ -33,26 +33,23 @@ namespace System.Security.AccessControl { public sealed class EventWaitHandleAccessRule : AccessRule { - EventWaitHandleRights rights; - public EventWaitHandleAccessRule (IdentityReference identity, EventWaitHandleRights eventRights, AccessControlType type) - // FIXME: accessMask=0 likely causes an error - : base (identity, 0, false, InheritanceFlags.None, PropagationFlags.None, AccessControlType.Allow) + : base (identity, (int)eventRights, false, + InheritanceFlags.None, PropagationFlags.None, AccessControlType.Allow) { - this.rights = eventRights; } public EventWaitHandleAccessRule (string identity, EventWaitHandleRights eventRights, AccessControlType type) - : this (new SecurityIdentifier (identity), eventRights, type) + : this (new NTAccount (identity), eventRights, type) { } public EventWaitHandleRights EventWaitHandleRights { - get { return rights; } + get { return (EventWaitHandleRights)AccessMask; } } } } diff --git a/mcs/class/corlib/System.Security.AccessControl/EventWaitHandleAuditRule.cs b/mcs/class/corlib/System.Security.AccessControl/EventWaitHandleAuditRule.cs index c1418dbc7a2..8503546568d 100644 --- a/mcs/class/corlib/System.Security.AccessControl/EventWaitHandleAuditRule.cs +++ b/mcs/class/corlib/System.Security.AccessControl/EventWaitHandleAuditRule.cs @@ -33,39 +33,19 @@ namespace System.Security.AccessControl { public sealed class EventWaitHandleAuditRule : AuditRule { - EventWaitHandleRights rights; - public EventWaitHandleAuditRule (IdentityReference identity, EventWaitHandleRights eventRights, AuditFlags flags) - : base (identity, 0, false, InheritanceFlags.None, PropagationFlags.None, flags) + : base (identity, (int)eventRights, false, InheritanceFlags.None, PropagationFlags.None, flags) { if (eventRights < EventWaitHandleRights.Modify || eventRights > EventWaitHandleRights.FullControl) { throw new ArgumentOutOfRangeException ("eventRights"); } - if (flags < AuditFlags.None || - flags > AuditFlags.Failure) { - throw new ArgumentOutOfRangeException ("flags"); - } - if (identity == null) { - throw new ArgumentNullException ("identity"); - } - if (eventRights == 0) { - throw new ArgumentNullException ("eventRights"); - } - if (flags == AuditFlags.None) { - throw new ArgumentException ("flags"); - } - if (!(identity is SecurityIdentifier)) { - throw new ArgumentException ("identity"); - } - - this.rights = eventRights; } public EventWaitHandleRights EventWaitHandleRights { - get { return rights; } + get { return (EventWaitHandleRights)AccessMask; } } } } diff --git a/mcs/class/corlib/System.Security.AccessControl/EventWaitHandleSecurity.cs b/mcs/class/corlib/System.Security.AccessControl/EventWaitHandleSecurity.cs index 7b6a048774b..385ce25ba07 100644 --- a/mcs/class/corlib/System.Security.AccessControl/EventWaitHandleSecurity.cs +++ b/mcs/class/corlib/System.Security.AccessControl/EventWaitHandleSecurity.cs @@ -4,8 +4,10 @@ // Authors: // Dick Porter <dick@ximian.com> // Atsushi Enomoto <atsushi@ximian.com> +// James Bellinger <jfb@zer7.com> // // Copyright (C) 2005-2007 Novell, Inc (http://www.novell.com) +// Copyright (C) 2012 James Bellinger // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -34,8 +36,8 @@ namespace System.Security.AccessControl public sealed class EventWaitHandleSecurity : NativeObjectSecurity { public EventWaitHandleSecurity () + : base (false, ResourceType.KernelObject) { - throw new NotImplementedException (); } public override Type AccessRightType { @@ -50,84 +52,73 @@ namespace System.Security.AccessControl get { return typeof (EventWaitHandleAuditRule); } } - // AccessRule - - public override AccessRule AccessRuleFactory (IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type) + public override AccessRule AccessRuleFactory (IdentityReference identityReference, int accessMask, + bool isInherited, InheritanceFlags inheritanceFlags, + PropagationFlags propagationFlags, AccessControlType type) { return new EventWaitHandleAccessRule (identityReference, (EventWaitHandleRights) accessMask, type); } - [MonoTODO] public void AddAccessRule (EventWaitHandleAccessRule rule) { - throw new NotImplementedException (); + AddAccessRule ((AccessRule)rule); } - [MonoTODO] public bool RemoveAccessRule (EventWaitHandleAccessRule rule) { - throw new NotImplementedException (); + return RemoveAccessRule ((AccessRule)rule); } - [MonoTODO] public void RemoveAccessRuleAll (EventWaitHandleAccessRule rule) { - throw new NotImplementedException (); + RemoveAccessRuleAll ((AccessRule)rule); } - [MonoTODO] public void RemoveAccessRuleSpecific (EventWaitHandleAccessRule rule) { - throw new NotImplementedException (); + RemoveAccessRuleSpecific ((AccessRule)rule); } - [MonoTODO] public void ResetAccessRule (EventWaitHandleAccessRule rule) { - throw new NotImplementedException (); + ResetAccessRule ((AccessRule)rule); } - [MonoTODO] public void SetAccessRule (EventWaitHandleAccessRule rule) { - throw new NotImplementedException (); + SetAccessRule ((AccessRule)rule); } - // AuditRule - - public override AuditRule AuditRuleFactory (IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags flags) + public override AuditRule AuditRuleFactory (IdentityReference identityReference, int accessMask, + bool isInherited, InheritanceFlags inheritanceFlags, + PropagationFlags propagationFlags, AuditFlags flags) { return new EventWaitHandleAuditRule (identityReference, (EventWaitHandleRights) accessMask, flags); } - [MonoTODO] public void AddAuditRule (EventWaitHandleAuditRule rule) { - throw new NotImplementedException (); + AddAuditRule ((AuditRule)rule); } - [MonoTODO] public bool RemoveAuditRule (EventWaitHandleAuditRule rule) { - throw new NotImplementedException (); + return RemoveAuditRule((AuditRule)rule); } - [MonoTODO] public void RemoveAuditRuleAll (EventWaitHandleAuditRule rule) { - throw new NotImplementedException (); + RemoveAuditRuleAll((AuditRule)rule); } - [MonoTODO] public void RemoveAuditRuleSpecific (EventWaitHandleAuditRule rule) { - throw new NotImplementedException (); + RemoveAuditRuleSpecific((AuditRule)rule); } - [MonoTODO] public void SetAuditRule (EventWaitHandleAuditRule rule) { - throw new NotImplementedException (); + SetAuditRule((AuditRule)rule); } } } diff --git a/mcs/class/corlib/System.Security.AccessControl/FileSecurity.cs b/mcs/class/corlib/System.Security.AccessControl/FileSecurity.cs index 9adb7c89986..046d34225e4 100644 --- a/mcs/class/corlib/System.Security.AccessControl/FileSecurity.cs +++ b/mcs/class/corlib/System.Security.AccessControl/FileSecurity.cs @@ -26,19 +26,27 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // -namespace System.Security.AccessControl { - public sealed class FileSecurity : FileSystemSecurity { +using System.Runtime.InteropServices; + +namespace System.Security.AccessControl +{ + public sealed class FileSecurity : FileSystemSecurity +{ public FileSecurity () : base (false) { - throw new PlatformNotSupportedException (); } public FileSecurity (string fileName, AccessControlSections includeSections) : base (false, fileName, includeSections) { - throw new PlatformNotSupportedException (); + } + + internal FileSecurity (SafeHandle handle, + AccessControlSections includeSections) + : base (false, handle, includeSections) + { } } } diff --git a/mcs/class/corlib/System.Security.AccessControl/FileSystemAccessRule.cs b/mcs/class/corlib/System.Security.AccessControl/FileSystemAccessRule.cs index 9d94b86066c..7a369805379 100644 --- a/mcs/class/corlib/System.Security.AccessControl/FileSystemAccessRule.cs +++ b/mcs/class/corlib/System.Security.AccessControl/FileSystemAccessRule.cs @@ -33,8 +33,6 @@ namespace System.Security.AccessControl { public sealed class FileSystemAccessRule : AccessRule { - FileSystemRights rights; - public FileSystemAccessRule (IdentityReference identity, FileSystemRights fileSystemRights, AccessControlType type) @@ -45,7 +43,7 @@ namespace System.Security.AccessControl public FileSystemAccessRule (string identity, FileSystemRights fileSystemRights, AccessControlType type) - : this (new SecurityIdentifier (identity), fileSystemRights, InheritanceFlags.None, PropagationFlags.None, type) + : this (new NTAccount (identity), fileSystemRights, InheritanceFlags.None, PropagationFlags.None, type) { } @@ -54,9 +52,18 @@ namespace System.Security.AccessControl InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type) - : base (identity, (int) fileSystemRights, false, inheritanceFlags, propagationFlags, type) + : this (identity, fileSystemRights, false, inheritanceFlags, propagationFlags, type) + { + } + + internal FileSystemAccessRule (IdentityReference identity, + FileSystemRights fileSystemRights, + bool isInherited, + InheritanceFlags inheritanceFlags, + PropagationFlags propagationFlags, + AccessControlType type) + : base (identity, (int) fileSystemRights, isInherited, inheritanceFlags, propagationFlags, type) { - this.rights = fileSystemRights; } public FileSystemAccessRule (string identity, @@ -64,12 +71,12 @@ namespace System.Security.AccessControl InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type) - : this (new SecurityIdentifier (identity), fileSystemRights, inheritanceFlags, propagationFlags, type) + : this (new NTAccount (identity), fileSystemRights, inheritanceFlags, propagationFlags, type) { } public FileSystemRights FileSystemRights { - get { return rights; } + get { return (FileSystemRights)AccessMask; } } } } diff --git a/mcs/class/corlib/System.Security.AccessControl/FileSystemAuditRule.cs b/mcs/class/corlib/System.Security.AccessControl/FileSystemAuditRule.cs index f1ce74b1746..ff29ab2eb76 100644 --- a/mcs/class/corlib/System.Security.AccessControl/FileSystemAuditRule.cs +++ b/mcs/class/corlib/System.Security.AccessControl/FileSystemAuditRule.cs @@ -34,8 +34,6 @@ namespace System.Security.AccessControl { public sealed class FileSystemAuditRule : AuditRule { - FileSystemRights rights; - public FileSystemAuditRule (IdentityReference identity, FileSystemRights fileSystemRights, AuditFlags flags) @@ -46,7 +44,7 @@ namespace System.Security.AccessControl public FileSystemAuditRule (string identity, FileSystemRights fileSystemRights, AuditFlags flags) - : this (new SecurityIdentifier (identity), fileSystemRights, flags) + : this (new NTAccount (identity), fileSystemRights, flags) { } @@ -55,9 +53,18 @@ namespace System.Security.AccessControl InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags flags) - : base (identity, 0, false, inheritanceFlags, propagationFlags, flags) + : this (identity, fileSystemRights, false, inheritanceFlags, propagationFlags, flags) + { + } + + internal FileSystemAuditRule (IdentityReference identity, + FileSystemRights fileSystemRights, + bool isInherited, + InheritanceFlags inheritanceFlags, + PropagationFlags propagationFlags, + AuditFlags flags) + : base (identity, (int)fileSystemRights, isInherited, inheritanceFlags, propagationFlags, flags) { - this.rights = fileSystemRights; } public FileSystemAuditRule (string identity, @@ -65,12 +72,12 @@ namespace System.Security.AccessControl InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags flags) - : this (new SecurityIdentifier (identity), fileSystemRights, inheritanceFlags, propagationFlags, flags) + : this (new NTAccount (identity), fileSystemRights, inheritanceFlags, propagationFlags, flags) { } public FileSystemRights FileSystemRights { - get { return rights; } + get { return (FileSystemRights)AccessMask; } } } } diff --git a/mcs/class/corlib/System.Security.AccessControl/FileSystemSecurity.cs b/mcs/class/corlib/System.Security.AccessControl/FileSystemSecurity.cs index fede72a192c..bd21bc009a6 100644 --- a/mcs/class/corlib/System.Security.AccessControl/FileSystemSecurity.cs +++ b/mcs/class/corlib/System.Security.AccessControl/FileSystemSecurity.cs @@ -4,8 +4,10 @@ // Authors: // Dick Porter <dick@ximian.com> // Atsushi Enomoto <atsushi@ximian.com> +// James Bellinger <jfb@zer7.com> // // Copyright (C) 2006-2007 Novell, Inc (http://www.novell.com) +// Copyright (C) 2012 James Bellinger // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -27,12 +29,13 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +using System.Runtime.InteropServices; using System.Security.Principal; -namespace System.Security.AccessControl { - - public abstract class FileSystemSecurity : NativeObjectSecurity { - +namespace System.Security.AccessControl +{ + public abstract class FileSystemSecurity : NativeObjectSecurity + { internal FileSystemSecurity (bool isContainer) : base (isContainer, ResourceType.FileObject) { @@ -43,6 +46,11 @@ namespace System.Security.AccessControl { { } + internal FileSystemSecurity (bool isContainer, SafeHandle handle, AccessControlSections includeSections) + : base (isContainer, ResourceType.FileObject, handle, includeSections) + { + } + public override Type AccessRightType { get { return typeof (FileSystemRights); } } @@ -54,89 +62,76 @@ namespace System.Security.AccessControl { public override Type AuditRuleType { get { return typeof (FileSystemAuditRule); } } - - // AccessRule - - [MonoTODO] - public override sealed AccessRule AccessRuleFactory (IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type) + + public override sealed AccessRule AccessRuleFactory (IdentityReference identityReference, int accessMask, + bool isInherited, InheritanceFlags inheritanceFlags, + PropagationFlags propagationFlags, AccessControlType type) { - // FIXME: isInherited is unused - return new FileSystemAccessRule (identityReference, (FileSystemRights) accessMask, inheritanceFlags, propagationFlags, type); + return new FileSystemAccessRule (identityReference, (FileSystemRights) accessMask, isInherited, + inheritanceFlags, propagationFlags, type); } - [MonoTODO] public void AddAccessRule (FileSystemAccessRule rule) { - throw new NotImplementedException (); + AddAccessRule ((AccessRule)rule); } - [MonoTODO] public bool RemoveAccessRule (FileSystemAccessRule rule) { - throw new NotImplementedException (); + return RemoveAccessRule ((AccessRule)rule); } - [MonoTODO] public void RemoveAccessRuleAll (FileSystemAccessRule rule) { - throw new NotImplementedException (); + RemoveAccessRuleAll ((AccessRule)rule); } - [MonoTODO] public void RemoveAccessRuleSpecific (FileSystemAccessRule rule) { - throw new NotImplementedException (); + RemoveAccessRuleSpecific ((AccessRule)rule); } - [MonoTODO] public void ResetAccessRule (FileSystemAccessRule rule) { - throw new NotImplementedException (); + ResetAccessRule ((AccessRule)rule); } - [MonoTODO] public void SetAccessRule (FileSystemAccessRule rule) { - throw new NotImplementedException (); + SetAccessRule ((AccessRule)rule); } - // AuditRule - - [MonoTODO] - public override sealed AuditRule AuditRuleFactory (IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags flags) + public override sealed AuditRule AuditRuleFactory (IdentityReference identityReference, int accessMask, + bool isInherited, InheritanceFlags inheritanceFlags, + PropagationFlags propagationFlags, AuditFlags flags) { - // FIXME: isInherited is unused - return new FileSystemAuditRule (identityReference, (FileSystemRights) accessMask, inheritanceFlags, propagationFlags, flags); + return new FileSystemAuditRule (identityReference, (FileSystemRights) accessMask, isInherited, + inheritanceFlags, propagationFlags, flags); } - [MonoTODO] public void AddAuditRule (FileSystemAuditRule rule) { - throw new NotImplementedException (); + AddAuditRule ((AuditRule)rule); } - [MonoTODO] public bool RemoveAuditRule (FileSystemAuditRule rule) { - throw new NotImplementedException (); + return RemoveAuditRule((AuditRule)rule); } - [MonoTODO] public void RemoveAuditRuleAll (FileSystemAuditRule rule) { - throw new NotImplementedException (); + RemoveAuditRuleAll((AuditRule)rule); } - [MonoTODO] public void RemoveAuditRuleSpecific (FileSystemAuditRule rule) { - throw new NotImplementedException (); + RemoveAuditRuleSpecific((AuditRule)rule); } - [MonoTODO] public void SetAuditRule (FileSystemAuditRule rule) { - throw new NotImplementedException (); + SetAuditRule((AuditRule)rule); } } } diff --git a/mcs/class/corlib/System.Security.AccessControl/GenericSecurityDescriptor.cs b/mcs/class/corlib/System.Security.AccessControl/GenericSecurityDescriptor.cs index 83e2170bfc5..f126670ecf2 100644 --- a/mcs/class/corlib/System.Security.AccessControl/GenericSecurityDescriptor.cs +++ b/mcs/class/corlib/System.Security.AccessControl/GenericSecurityDescriptor.cs @@ -45,7 +45,7 @@ namespace System.Security.AccessControl { len += Owner.BinaryLength; if (Group != null) len += Group.BinaryLength; - if (DaclPresent) + if (DaclPresent && !DaclIsUnmodifiedAefa) len += InternalDacl.BinaryLength; if (SaclPresent) len += InternalSacl.BinaryLength; @@ -77,7 +77,15 @@ namespace System.Security.AccessControl { public void GetBinaryForm (byte[] binaryForm, int offset) { + if (null == binaryForm) + throw new ArgumentNullException ("binaryForm"); + + int binaryLength = BinaryLength; + if (offset < 0 || offset > binaryForm.Length - binaryLength) + throw new ArgumentOutOfRangeException ("offset"); + ControlFlags controlFlags = ControlFlags; + if (DaclIsUnmodifiedAefa) { controlFlags &= ~ControlFlags.DiscretionaryAclPresent; } binaryForm[offset + 0x00] = Revision; binaryForm[offset + 0x01] = InternalReservedField; WriteUShort ((ushort)controlFlags, binaryForm, @@ -112,7 +120,7 @@ namespace System.Security.AccessControl { } GenericAcl discAcl = InternalDacl; - if (DaclPresent) { + if (DaclPresent && !DaclIsUnmodifiedAefa) { WriteInt (pos, binaryForm, offset + 0x10); discAcl.GetBinaryForm (binaryForm, offset + pos); pos += InternalDacl.BinaryLength; @@ -140,7 +148,7 @@ namespace System.Security.AccessControl { } if ((includeSections & AccessControlSections.Access) != 0 - && InternalDacl != null) { + && DaclPresent && !DaclIsUnmodifiedAefa) { result.AppendFormat ( CultureInfo.InvariantCulture, "D:{0}", @@ -149,7 +157,7 @@ namespace System.Security.AccessControl { } if ((includeSections & AccessControlSections.Audit) != 0 - && InternalSacl != null) { + && SaclPresent) { result.AppendFormat ( CultureInfo.InvariantCulture, "S:{0}", @@ -165,27 +173,32 @@ namespace System.Security.AccessControl { return true; } - private bool DaclPresent { + // See CommonSecurityDescriptor constructor regarding this persistence detail. + internal virtual bool DaclIsUnmodifiedAefa { + get { return false; } + } + + bool DaclPresent { get { return InternalDacl != null && (ControlFlags & ControlFlags.DiscretionaryAclPresent) != 0; } } - - private bool SaclPresent { + + bool SaclPresent { get { return InternalSacl != null && (ControlFlags & ControlFlags.SystemAclPresent) != 0; } } - - private void WriteUShort (ushort val, byte[] buffer, int offset) + + void WriteUShort (ushort val, byte[] buffer, int offset) { buffer[offset] = (byte)val; buffer[offset + 1] = (byte)(val >> 8); } - private void WriteInt (int val, byte[] buffer, int offset) + void WriteInt (int val, byte[] buffer, int offset) { buffer[offset] = (byte)val; buffer[offset + 1] = (byte)(val >> 8); diff --git a/mcs/class/corlib/System.Security.AccessControl/MutexAccessRule.cs b/mcs/class/corlib/System.Security.AccessControl/MutexAccessRule.cs index b61852705c4..96d49a318d0 100644 --- a/mcs/class/corlib/System.Security.AccessControl/MutexAccessRule.cs +++ b/mcs/class/corlib/System.Security.AccessControl/MutexAccessRule.cs @@ -45,7 +45,7 @@ namespace System.Security.AccessControl public MutexAccessRule (string identity, MutexRights eventRights, AccessControlType type) - : this (new SecurityIdentifier (identity), eventRights, type) + : this (new NTAccount (identity), eventRights, type) { } diff --git a/mcs/class/corlib/System.Security.AccessControl/MutexAuditRule.cs b/mcs/class/corlib/System.Security.AccessControl/MutexAuditRule.cs index 475417b946e..16656bec2b7 100644 --- a/mcs/class/corlib/System.Security.AccessControl/MutexAuditRule.cs +++ b/mcs/class/corlib/System.Security.AccessControl/MutexAuditRule.cs @@ -33,18 +33,15 @@ namespace System.Security.AccessControl { public sealed class MutexAuditRule : AuditRule { - MutexRights rights; - public MutexAuditRule (IdentityReference identity, MutexRights eventRights, AuditFlags flags) - : base (identity, 0, false, InheritanceFlags.None, PropagationFlags.None, flags) + : base (identity, (int)eventRights, false, InheritanceFlags.None, PropagationFlags.None, flags) { - this.rights = eventRights; } public MutexRights MutexRights { - get { return rights; } + get { return (MutexRights)AccessMask; } } } } diff --git a/mcs/class/corlib/System.Security.AccessControl/MutexSecurity.cs b/mcs/class/corlib/System.Security.AccessControl/MutexSecurity.cs index 1d9b81649c7..3dbfecd869a 100644 --- a/mcs/class/corlib/System.Security.AccessControl/MutexSecurity.cs +++ b/mcs/class/corlib/System.Security.AccessControl/MutexSecurity.cs @@ -4,8 +4,10 @@ // Authors: // Dick Porter <dick@ximian.com> // Atsushi Enomoto <atsushi@ximian.com> +// James Bellinger <jfb@zer7.com> // // Copyright (C) 2005-2007 Novell, Inc (http://www.novell.com) +// Copyright (C) 2012 James Bellinger // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -34,11 +36,13 @@ namespace System.Security.AccessControl public sealed class MutexSecurity : NativeObjectSecurity { public MutexSecurity () + : base (false, ResourceType.KernelObject) { } public MutexSecurity (string name, AccessControlSections includeSections) + : base (false, ResourceType.KernelObject, name, includeSections) { } @@ -54,84 +58,73 @@ namespace System.Security.AccessControl get { return typeof (MutexAuditRule); } } - // AccessRule - - public override AccessRule AccessRuleFactory (IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type) + public override AccessRule AccessRuleFactory (IdentityReference identityReference, int accessMask, + bool isInherited, InheritanceFlags inheritanceFlags, + PropagationFlags propagationFlags, AccessControlType type) { return new MutexAccessRule (identityReference, (MutexRights) accessMask, type); } - [MonoTODO] public void AddAccessRule (MutexAccessRule rule) { - throw new NotImplementedException (); + AddAccessRule ((AccessRule)rule); } - - [MonoTODO] + public bool RemoveAccessRule (MutexAccessRule rule) { - throw new NotImplementedException (); + return RemoveAccessRule ((AccessRule)rule); } - [MonoTODO] public void RemoveAccessRuleAll (MutexAccessRule rule) { - throw new NotImplementedException (); + RemoveAccessRuleAll ((AccessRule)rule); } - [MonoTODO] public void RemoveAccessRuleSpecific (MutexAccessRule rule) { - throw new NotImplementedException (); + RemoveAccessRuleSpecific ((AccessRule)rule); } - [MonoTODO] public void ResetAccessRule (MutexAccessRule rule) { - throw new NotImplementedException (); + ResetAccessRule ((AccessRule)rule); } - [MonoTODO] public void SetAccessRule (MutexAccessRule rule) { - throw new NotImplementedException (); + SetAccessRule ((AccessRule)rule); } - - // AuditRule - - public override AuditRule AuditRuleFactory (IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags flags) + + public override AuditRule AuditRuleFactory (IdentityReference identityReference, int accessMask, + bool isInherited, InheritanceFlags inheritanceFlags, + PropagationFlags propagationFlags, AuditFlags flags) { return new MutexAuditRule (identityReference, (MutexRights) accessMask, flags); } - [MonoTODO] public void AddAuditRule (MutexAuditRule rule) { - throw new NotImplementedException (); + AddAuditRule ((AuditRule)rule); } - [MonoTODO] public bool RemoveAuditRule (MutexAuditRule rule) { - throw new NotImplementedException (); + return RemoveAuditRule((AuditRule)rule); } - [MonoTODO] public void RemoveAuditRuleAll (MutexAuditRule rule) { - throw new NotImplementedException (); + RemoveAuditRuleAll((AuditRule)rule); } - [MonoTODO] public void RemoveAuditRuleSpecific (MutexAuditRule rule) { - throw new NotImplementedException (); + RemoveAuditRuleSpecific((AuditRule)rule); } - [MonoTODO] public void SetAuditRule (MutexAuditRule rule) { - throw new NotImplementedException (); + SetAuditRule((AuditRule)rule); } } } diff --git a/mcs/class/corlib/System.Security.AccessControl/NativeObjectSecurity.cs b/mcs/class/corlib/System.Security.AccessControl/NativeObjectSecurity.cs index f73e37638ca..d978c07f51b 100644 --- a/mcs/class/corlib/System.Security.AccessControl/NativeObjectSecurity.cs +++ b/mcs/class/corlib/System.Security.AccessControl/NativeObjectSecurity.cs @@ -1,10 +1,12 @@ // // System.Security.AccessControl.NativeObjectSecurity implementation // -// Author: +// Authors: // Dick Porter <dick@ximian.com> +// James Bellinger <jfb@zer7.com> // // Copyright (C) 2005, 2006 Novell, Inc (http://www.novell.com) +// Copyright (C) 2012 James Bellinger // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -26,23 +28,31 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +using System; +using System.IO; using System.Runtime.InteropServices; +using System.Security.Principal; -namespace System.Security.AccessControl { - - public abstract class NativeObjectSecurity : CommonObjectSecurity { - - protected internal delegate Exception ExceptionFromErrorCode (int errorCode, string name, SafeHandle handle, object context); +namespace System.Security.AccessControl +{ + public abstract class NativeObjectSecurity : CommonObjectSecurity + { + ExceptionFromErrorCode exception_from_error_code; + ResourceType resource_type; - internal NativeObjectSecurity () - : base (false) + protected internal delegate Exception ExceptionFromErrorCode (int errorCode, + string name, SafeHandle handle, + object context); + + internal NativeObjectSecurity (CommonSecurityDescriptor securityDescriptor, ResourceType resourceType) + : base (securityDescriptor) { - /* Give it a 0-param constructor */ + resource_type = resourceType; } - + protected NativeObjectSecurity (bool isContainer, ResourceType resourceType) - : base (isContainer) + : this (isContainer, resourceType, null, null) { } @@ -50,15 +60,17 @@ namespace System.Security.AccessControl { ResourceType resourceType, ExceptionFromErrorCode exceptionFromErrorCode, object exceptionContext) - : this (isContainer, resourceType) + : base (isContainer) { + exception_from_error_code = exceptionFromErrorCode; + resource_type = resourceType; } protected NativeObjectSecurity (bool isContainer, ResourceType resourceType, SafeHandle handle, AccessControlSections includeSections) - : this (isContainer, resourceType) + : this (isContainer, resourceType, handle, includeSections, null, null) { } @@ -66,7 +78,7 @@ namespace System.Security.AccessControl { ResourceType resourceType, string name, AccessControlSections includeSections) - : this (isContainer, resourceType) + : this (isContainer, resourceType, name, includeSections, null, null) { } @@ -76,8 +88,11 @@ namespace System.Security.AccessControl { AccessControlSections includeSections, ExceptionFromErrorCode exceptionFromErrorCode, object exceptionContext) - : this (isContainer, resourceType, handle, includeSections) + : this (isContainer, resourceType, exceptionFromErrorCode, exceptionContext) { + RaiseExceptionOnFailure (InternalGet (handle, includeSections), + null, handle, exceptionContext); + ClearAccessControlSectionsModified (); } protected NativeObjectSecurity (bool isContainer, @@ -86,35 +101,294 @@ namespace System.Security.AccessControl { AccessControlSections includeSections, ExceptionFromErrorCode exceptionFromErrorCode, object exceptionContext) - : this (isContainer, resourceType, name, includeSections) + : this (isContainer, resourceType, exceptionFromErrorCode, exceptionContext) { + RaiseExceptionOnFailure (InternalGet (name, includeSections), + name, null, exceptionContext); + ClearAccessControlSectionsModified (); + } + + void ClearAccessControlSectionsModified () + { + WriteLock (); + try { + AccessControlSectionsModified = AccessControlSections.None; + } finally { + WriteUnlock (); + } } protected override sealed void Persist (SafeHandle handle, AccessControlSections includeSections) { - throw new NotImplementedException (); + Persist (handle, includeSections, null); } protected override sealed void Persist (string name, AccessControlSections includeSections) { - throw new NotImplementedException (); + Persist (name, includeSections, null); + } + + internal void PersistModifications (SafeHandle handle) + { + WriteLock(); + try { + Persist (handle, AccessControlSectionsModified, null); + } finally { + WriteUnlock (); + } } protected void Persist (SafeHandle handle, AccessControlSections includeSections, object exceptionContext) { - throw new NotImplementedException (); + WriteLock (); + try { + RaiseExceptionOnFailure (InternalSet (handle, includeSections), null, handle, exceptionContext); + AccessControlSectionsModified &= ~includeSections; + } finally { + WriteUnlock (); + } + } + + internal void PersistModifications (string name) + { + WriteLock(); + try { + Persist (name, AccessControlSectionsModified, null); + } finally { + WriteUnlock (); + } } protected void Persist (string name, AccessControlSections includeSections, object exceptionContext) { - throw new NotImplementedException (); + if (null == name) + throw new ArgumentNullException ("name"); + + WriteLock (); + try { + RaiseExceptionOnFailure (InternalSet (name, includeSections), name, null, exceptionContext); + AccessControlSectionsModified &= ~includeSections; + } finally { + WriteUnlock (); + } + } + + static Exception DefaultExceptionFromErrorCode (int errorCode, + string name, SafeHandle handle, + object context) + { + switch (errorCode) + { + case 2: return new FileNotFoundException (); + case 3: return new DirectoryNotFoundException (); + case 5: return new UnauthorizedAccessException (); + case 1314: return new PrivilegeNotHeldException (); // happens with audit rules + default: return new InvalidOperationException ("OS error code " + errorCode.ToString()); + } + } + + void RaiseExceptionOnFailure (int errorCode, string name, SafeHandle handle, object context) + { + if (errorCode == 0) return; + throw (exception_from_error_code ?? DefaultExceptionFromErrorCode)(errorCode, name, handle, context); + } + + // InternalGet/InternalSet are virtual so that non-Windows platforms which do not share an + // API between files, mutexes, etc. can override in the subclass and do their own thing. + internal virtual int InternalGet (SafeHandle handle, + AccessControlSections includeSections) + { + if (Environment.OSVersion.Platform != PlatformID.Win32NT) + throw new PlatformNotSupportedException (); + + return InternalGetHelper (delegate (SecurityInfos securityInfos, + out IntPtr owner, out IntPtr group, + out IntPtr dacl, out IntPtr sacl, out IntPtr descriptor) + { + return GetSecurityInfo (handle, ResourceType, securityInfos, + out owner, out group, + out dacl, out sacl, out descriptor); + }, includeSections); + } + + internal virtual int InternalGet (string name, + AccessControlSections includeSections) + { + if (Environment.OSVersion.Platform != PlatformID.Win32NT) + throw new PlatformNotSupportedException (); + + return InternalGetHelper (delegate (SecurityInfos securityInfos, + out IntPtr owner, out IntPtr group, + out IntPtr dacl, out IntPtr sacl, out IntPtr descriptor) + { + return GetNamedSecurityInfo (name, ResourceType, securityInfos, + out owner, out group, + out dacl, out sacl, out descriptor); + }, includeSections); + } + + internal virtual int InternalSet (SafeHandle handle, + AccessControlSections includeSections) + { + if (Environment.OSVersion.Platform != PlatformID.Win32NT) + throw new PlatformNotSupportedException (); + + return InternalSetHelper ((securityInfos, owner, group, dacl, sacl) => + SetSecurityInfo (handle, ResourceType, securityInfos, owner, group, dacl, sacl), + includeSections); + } + + internal virtual int InternalSet (string name, + AccessControlSections includeSections) + { + if (Environment.OSVersion.Platform != PlatformID.Win32NT) + throw new PlatformNotSupportedException (); + + return InternalSetHelper ((securityInfos, owner, group, dacl, sacl) => + SetNamedSecurityInfo (name, ResourceType, securityInfos, owner, group, dacl, sacl), + includeSections); + } + + internal ResourceType ResourceType { + get { return resource_type; } + } + + #region Win32 Details + int InternalGetHelper (GetSecurityInfoNativeCall nativeCall, + AccessControlSections includeSections) + { + if (Environment.OSVersion.Platform != PlatformID.Win32NT) + throw new PlatformNotSupportedException (); + + bool getOwner = 0 != (includeSections & AccessControlSections.Owner); + bool getGroup = 0 != (includeSections & AccessControlSections.Group); + bool getDacl = 0 != (includeSections & AccessControlSections.Access); + bool getSacl = 0 != (includeSections & AccessControlSections.Audit); + + SecurityInfos securityInfos = 0; + if (getOwner) securityInfos |= SecurityInfos.Owner; + if (getGroup) securityInfos |= SecurityInfos.Group; + if (getDacl ) securityInfos |= SecurityInfos.DiscretionaryAcl; + if (getSacl ) securityInfos |= SecurityInfos.SystemAcl; + + IntPtr owner, group, dacl, sacl, descriptor; + int result = nativeCall (securityInfos, + out owner, out group, out dacl, out sacl, out descriptor); + if (0 != result) return result; + + try { + int binaryLength = 0; + if (IsValidSecurityDescriptor (descriptor)) + binaryLength = GetSecurityDescriptorLength (descriptor); + + byte[] binaryForm = new byte[binaryLength]; + Marshal.Copy (descriptor, binaryForm, 0, binaryLength); + SetSecurityDescriptorBinaryForm (binaryForm, includeSections); + } finally { + LocalFree (descriptor); + } + return 0; + } + + int InternalSetHelper (SetSecurityInfoNativeCall nativeCall, + AccessControlSections includeSections) + { + SecurityInfos securityInfos = 0; + byte[] owner = null, group = null, dacl = null, sacl = null; + + if (0 != (includeSections & AccessControlSections.Owner)) { + securityInfos |= SecurityInfos.Owner; + SecurityIdentifier ownerSid = (SecurityIdentifier)GetOwner (typeof (SecurityIdentifier)); + if (null != ownerSid) { + owner = new byte[ownerSid.BinaryLength]; + ownerSid.GetBinaryForm (owner, 0); + } + } + + if (0 != (includeSections & AccessControlSections.Group)) { + securityInfos |= SecurityInfos.Group; + SecurityIdentifier groupSid = (SecurityIdentifier)GetGroup (typeof (SecurityIdentifier)); + if (null != groupSid) { + group = new byte[groupSid.BinaryLength]; + groupSid.GetBinaryForm (group, 0); + } + } + + if (0 != (includeSections & AccessControlSections.Access)) { + securityInfos |= SecurityInfos.DiscretionaryAcl; + if (AreAccessRulesProtected) + securityInfos |= unchecked((SecurityInfos)0x80000000); + else + securityInfos |= (SecurityInfos)0x20000000; + dacl = new byte[descriptor.DiscretionaryAcl.BinaryLength]; + descriptor.DiscretionaryAcl.GetBinaryForm (dacl, 0); + } + + if (0 != (includeSections & AccessControlSections.Audit)) { + if (null != descriptor.SystemAcl) { + securityInfos |= SecurityInfos.SystemAcl; + if (AreAuditRulesProtected) + securityInfos |= (SecurityInfos)0x40000000; + else + securityInfos |= (SecurityInfos)0x10000000; + sacl = new byte[descriptor.SystemAcl.BinaryLength]; + descriptor.SystemAcl.GetBinaryForm (sacl, 0); + } + } + + return nativeCall (securityInfos, owner, group, dacl, sacl); + } + #endregion + + #region Win32 P/Invokes + delegate int GetSecurityInfoNativeCall (SecurityInfos securityInfos, + out IntPtr owner, out IntPtr group, out IntPtr dacl, out IntPtr sacl, + out IntPtr descriptor); + + [DllImport ("advapi32.dll", CharSet=CharSet.Unicode, EntryPoint="GetSecurityInfo")] + static extern int GetSecurityInfo (SafeHandle handle, ResourceType resourceType, SecurityInfos securityInfos, + out IntPtr owner, out IntPtr group, out IntPtr dacl, out IntPtr sacl, + out IntPtr descriptor); + + [DllImport ("advapi32.dll", CharSet=CharSet.Unicode, EntryPoint="GetNamedSecurityInfo")] + static extern int GetNamedSecurityInfo (string name, ResourceType resourceType, SecurityInfos securityInfos, + out IntPtr owner, out IntPtr group, out IntPtr dacl, out IntPtr sacl, + out IntPtr descriptor); + + [DllImport ("kernel32.dll", EntryPoint="LocalFree")] + static extern IntPtr LocalFree (IntPtr handle); + + delegate int SetSecurityInfoNativeCall (SecurityInfos securityInfos, + byte[] owner, byte[] group, byte[] dacl, byte[] sacl); + + [DllImport ("advapi32.dll", CharSet=CharSet.Unicode, EntryPoint="SetSecurityInfo")] + static extern int SetSecurityInfo (SafeHandle handle, ResourceType resourceType, SecurityInfos securityInfos, + byte[] owner, byte[] group, byte[] dacl, byte[] sacl); + + [DllImport ("advapi32.dll", CharSet=CharSet.Unicode, EntryPoint="SetNamedSecurityInfo")] + static extern int SetNamedSecurityInfo (string name, ResourceType resourceType, SecurityInfos securityInfos, + byte[] owner, byte[] group, byte[] dacl, byte[] sacl); + + [DllImport ("advapi32.dll", CharSet=CharSet.Unicode, EntryPoint="GetSecurityDescriptorLength")] + static extern int GetSecurityDescriptorLength (IntPtr descriptor); + + [DllImport ("advapi32.dll", CharSet=CharSet.Unicode, EntryPoint="IsValidSecurityDescriptor")] + [return: MarshalAs (UnmanagedType.Bool)] + static extern bool IsValidSecurityDescriptor (IntPtr descriptor); + + struct SecurityDescriptor + { + public byte Revision, Size; + public ushort ControlFlags; + public IntPtr Owner, Group, Sacl, Dacl; } + #endregion } } diff --git a/mcs/class/corlib/System.Security.AccessControl/ObjectSecurity.cs b/mcs/class/corlib/System.Security.AccessControl/ObjectSecurity.cs index e47ea8ae827..ea0c2301f60 100644 --- a/mcs/class/corlib/System.Security.AccessControl/ObjectSecurity.cs +++ b/mcs/class/corlib/System.Security.AccessControl/ObjectSecurity.cs @@ -4,8 +4,10 @@ // Authors: // Dick Porter <dick@ximian.com> // Atsushi Enomoto <atsushi@ximian.com> +// James Bellinger <jfb@zer7.com> // // Copyright (C) 2005-2007 Novell, Inc (http://www.novell.com) +// Copyright (C) 2012 James Bellinger // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -27,27 +29,34 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +using System.Collections.Generic; using System.Security.Principal; using System.Runtime.InteropServices; +using System.Threading; namespace System.Security.AccessControl { public abstract class ObjectSecurity { - internal ObjectSecurity () + internal ObjectSecurity (CommonSecurityDescriptor securityDescriptor) { - /* Give it a 0-param constructor */ + if (securityDescriptor == null) + throw new ArgumentNullException ("securityDescriptor"); + + descriptor = securityDescriptor; + rw_lock = new ReaderWriterLock (); } protected ObjectSecurity (bool isContainer, bool isDS) + : this (new CommonSecurityDescriptor + (isContainer, isDS, ControlFlags.None, null, null, null, + new DiscretionaryAcl (isContainer, isDS, 0))) { - is_container = isContainer; - is_ds = isDS; } - - bool is_container, is_ds; - bool access_rules_modified, audit_rules_modified; - bool group_modified, owner_modified; + + internal CommonSecurityDescriptor descriptor; + AccessControlSections sections_modified; + ReaderWriterLock rw_lock; public abstract Type AccessRightType { get; } @@ -55,218 +64,422 @@ namespace System.Security.AccessControl public abstract Type AuditRuleType { get; } - [MonoTODO] - public bool AreAccessRulesCanonical - { + public bool AreAccessRulesCanonical { get { - throw new NotImplementedException (); + ReadLock (); + try { + return descriptor.IsDiscretionaryAclCanonical; + } finally { + ReadUnlock (); + } } } - [MonoTODO] - public bool AreAccessRulesProtected - { + public bool AreAccessRulesProtected { get { - throw new NotImplementedException (); + ReadLock (); + try { + return 0 != (descriptor.ControlFlags & ControlFlags.DiscretionaryAclProtected); + } finally { + ReadUnlock (); + } } } - [MonoTODO] - public bool AreAuditRulesCanonical - { + public bool AreAuditRulesCanonical { get { - throw new NotImplementedException (); + ReadLock (); + try { + return descriptor.IsSystemAclCanonical; + } finally { + ReadUnlock (); + } } } - [MonoTODO] - public bool AreAuditRulesProtected - { + public bool AreAuditRulesProtected { get { - throw new NotImplementedException (); + ReadLock (); + try { + return 0 != (descriptor.ControlFlags & ControlFlags.SystemAclProtected); + } finally { + ReadUnlock (); + } } } + internal AccessControlSections AccessControlSectionsModified { + get { Reading (); return sections_modified; } + set { Writing (); sections_modified = value; } + } + protected bool AccessRulesModified { - get { return access_rules_modified; } - set { access_rules_modified = value; } + get { return AreAccessControlSectionsModified (AccessControlSections.Access); } + set { SetAccessControlSectionsModified (AccessControlSections.Access, value); } } protected bool AuditRulesModified { - get { return audit_rules_modified; } - set { audit_rules_modified = value; } + get { return AreAccessControlSectionsModified (AccessControlSections.Audit); } + set { SetAccessControlSectionsModified (AccessControlSections.Audit, value); } } protected bool GroupModified { - get { return group_modified; } - set { group_modified = value; } + get { return AreAccessControlSectionsModified (AccessControlSections.Group); } + set { SetAccessControlSectionsModified (AccessControlSections.Group, value); } } protected bool IsContainer { - get { return is_container; } + get { return descriptor.IsContainer; } } protected bool IsDS { - get { return is_ds; } + get { return descriptor.IsDS; } } protected bool OwnerModified { - get { return owner_modified; } - set { owner_modified = value; } + get { return AreAccessControlSectionsModified (AccessControlSections.Owner); } + set { SetAccessControlSectionsModified (AccessControlSections.Owner, value); } } - - public abstract AccessRule AccessRuleFactory (IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type); - public abstract AuditRule AuditRuleFactory (IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags flags); + public abstract AccessRule AccessRuleFactory (IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type); - [MonoTODO] + public abstract AuditRule AuditRuleFactory (IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags flags); + public IdentityReference GetGroup (Type targetType) { - throw new NotImplementedException (); + ReadLock (); + try { + if (descriptor.Group == null) + return null; + + return descriptor.Group.Translate (targetType); + } finally { + ReadUnlock (); + } } - [MonoTODO] public IdentityReference GetOwner (Type targetType) { - throw new NotImplementedException (); + ReadLock (); + try { + if (descriptor.Owner == null) + return null; + + return descriptor.Owner.Translate (targetType); + } finally { + ReadUnlock (); + } } - [MonoTODO] public byte[] GetSecurityDescriptorBinaryForm () { - throw new NotImplementedException (); + ReadLock (); + try { + byte[] binaryForm = new byte[descriptor.BinaryLength]; + descriptor.GetBinaryForm (binaryForm, 0); + return binaryForm; + } finally { + ReadUnlock (); + } } - [MonoTODO] public string GetSecurityDescriptorSddlForm (AccessControlSections includeSections) { - throw new NotImplementedException (); + ReadLock (); + try { + return descriptor.GetSddlForm (includeSections); + } finally { + ReadUnlock (); + } } - - [MonoTODO] + public static bool IsSddlConversionSupported () { - throw new NotImplementedException (); + return GenericSecurityDescriptor.IsSddlConversionSupported (); } - [MonoTODO] public virtual bool ModifyAccessRule (AccessControlModification modification, AccessRule rule, out bool modified) { - throw new NotImplementedException (); + if (rule == null) + throw new ArgumentNullException ("rule"); + + if (!AccessRuleType.IsAssignableFrom (rule.GetType())) + throw new ArgumentException ("rule"); + + return ModifyAccess (modification, rule, out modified); } - [MonoTODO] public virtual bool ModifyAuditRule (AccessControlModification modification, AuditRule rule, out bool modified) { - throw new NotImplementedException (); + if (rule == null) + throw new ArgumentNullException ("rule"); + + if (!AuditRuleType.IsAssignableFrom (rule.GetType())) + throw new ArgumentException ("rule"); + + return ModifyAudit (modification, rule, out modified); } - [MonoTODO] public virtual void PurgeAccessRules (IdentityReference identity) { - throw new NotImplementedException (); + if (null == identity) + throw new ArgumentNullException ("identity"); + + WriteLock (); + try { + descriptor.PurgeAccessControl (SidFromIR (identity)); + } finally { + WriteUnlock (); + } } - [MonoTODO] public virtual void PurgeAuditRules (IdentityReference identity) { - throw new NotImplementedException (); + if (null == identity) + throw new ArgumentNullException ("identity"); + + WriteLock (); + try { + descriptor.PurgeAudit (SidFromIR (identity)); + } finally { + WriteUnlock (); + } } - [MonoTODO] public void SetAccessRuleProtection (bool isProtected, bool preserveInheritance) { - throw new NotImplementedException (); + WriteLock (); + try { + descriptor.SetDiscretionaryAclProtection (isProtected, preserveInheritance); + } finally { + WriteUnlock(); + } } - [MonoTODO] public void SetAuditRuleProtection (bool isProtected, bool preserveInheritance) { - throw new NotImplementedException (); + WriteLock (); + try { + descriptor.SetSystemAclProtection (isProtected, preserveInheritance); + } finally { + WriteUnlock (); + } } - [MonoTODO] public void SetGroup (IdentityReference identity) { - throw new NotImplementedException (); + WriteLock (); + try { + descriptor.Group = SidFromIR (identity); + GroupModified = true; + } finally { + WriteUnlock (); + } } - [MonoTODO] public void SetOwner (IdentityReference identity) { - throw new NotImplementedException (); + WriteLock (); + try { + descriptor.Owner = SidFromIR (identity); + OwnerModified = true; + } finally { + WriteUnlock (); + } } - [MonoTODO] public void SetSecurityDescriptorBinaryForm (byte[] binaryForm) { - throw new NotImplementedException (); + SetSecurityDescriptorBinaryForm (binaryForm, AccessControlSections.All); } - [MonoTODO] public void SetSecurityDescriptorBinaryForm (byte[] binaryForm, AccessControlSections includeSections) { - throw new NotImplementedException (); + CopySddlForm (new CommonSecurityDescriptor (IsContainer, IsDS, binaryForm, 0), includeSections); } - [MonoTODO] public void SetSecurityDescriptorSddlForm (string sddlForm) { - throw new NotImplementedException (); + SetSecurityDescriptorSddlForm (sddlForm, AccessControlSections.All); } - [MonoTODO] public void SetSecurityDescriptorSddlForm (string sddlForm, AccessControlSections includeSections) { - throw new NotImplementedException (); + CopySddlForm (new CommonSecurityDescriptor (IsContainer, IsDS, sddlForm), includeSections); + } + + void CopySddlForm (CommonSecurityDescriptor sourceDescriptor, AccessControlSections includeSections) + { + WriteLock (); + try { + AccessControlSectionsModified |= includeSections; + if (0 != (includeSections & AccessControlSections.Audit)) + descriptor.SystemAcl = sourceDescriptor.SystemAcl; + if (0 != (includeSections & AccessControlSections.Access)) + descriptor.DiscretionaryAcl = sourceDescriptor.DiscretionaryAcl; + if (0 != (includeSections & AccessControlSections.Owner)) + descriptor.Owner = sourceDescriptor.Owner; + if (0 != (includeSections & AccessControlSections.Group)) + descriptor.Group = sourceDescriptor.Group; + } finally { + WriteUnlock (); + } } protected abstract bool ModifyAccess (AccessControlModification modification, AccessRule rule, out bool modified); protected abstract bool ModifyAudit (AccessControlModification modification, AuditRule rule, out bool modified); - [MonoTODO] + // For MoMA. NotImplementedException is correct for this base class. + Exception GetNotImplementedException () + { + return new NotImplementedException (); + } + protected virtual void Persist (SafeHandle handle, AccessControlSections includeSections) { - throw new NotImplementedException (); + throw GetNotImplementedException (); } - [MonoTODO] protected virtual void Persist (string name, AccessControlSections includeSections) { - throw new NotImplementedException (); + throw GetNotImplementedException (); } - + [MonoTODO] protected virtual void Persist (bool enableOwnershipPrivilege, string name, AccessControlSections includeSections) { throw new NotImplementedException (); } - [MonoTODO] + void Reading () + { + if (!rw_lock.IsReaderLockHeld && !rw_lock.IsWriterLockHeld) + throw new InvalidOperationException ("Either a read or a write lock must be held."); + } + protected void ReadLock () { - throw new NotImplementedException (); + rw_lock.AcquireReaderLock (Timeout.Infinite); } - [MonoTODO] protected void ReadUnlock () { - throw new NotImplementedException (); + rw_lock.ReleaseReaderLock (); + } + + void Writing () + { + if (!rw_lock.IsWriterLockHeld) + throw new InvalidOperationException ("Write lock must be held."); } - [MonoTODO] protected void WriteLock () { - throw new NotImplementedException (); + rw_lock.AcquireWriterLock (Timeout.Infinite); } - [MonoTODO] protected void WriteUnlock () { - throw new NotImplementedException (); + rw_lock.ReleaseWriterLock (); + } + + internal AuthorizationRuleCollection InternalGetAccessRules (bool includeExplicit, + bool includeInherited, + Type targetType) + { + List<AuthorizationRule> rules = new List<AuthorizationRule> (); + + ReadLock (); + try { + foreach (GenericAce genericAce in descriptor.DiscretionaryAcl) { + QualifiedAce ace = genericAce as QualifiedAce; + if (null == ace) continue; + if (ace.IsInherited && !includeInherited) continue; + if (!ace.IsInherited && !includeExplicit) continue; + + AccessControlType type; + if (AceQualifier.AccessAllowed == ace.AceQualifier) + type = AccessControlType.Allow; + else if (AceQualifier.AccessDenied == ace.AceQualifier) + type = AccessControlType.Deny; + else + continue; + + AccessRule rule = InternalAccessRuleFactory (ace, targetType, type); + rules.Add (rule); + } + } finally { + ReadUnlock (); + } + + return new AuthorizationRuleCollection (rules.ToArray ()); + } + + internal virtual AccessRule InternalAccessRuleFactory (QualifiedAce ace, Type targetType, + AccessControlType type) + { + return AccessRuleFactory (ace.SecurityIdentifier.Translate (targetType), + ace.AccessMask, ace.IsInherited, + ace.InheritanceFlags, ace.PropagationFlags, type); + } + + internal AuthorizationRuleCollection InternalGetAuditRules (bool includeExplicit, + bool includeInherited, + Type targetType) + { + List<AuthorizationRule> rules = new List<AuthorizationRule> (); + + ReadLock (); + try { + if (null != descriptor.SystemAcl) { + foreach (GenericAce genericAce in descriptor.SystemAcl) { + QualifiedAce ace = genericAce as QualifiedAce; + if (null == ace) continue; + if (ace.IsInherited && !includeInherited) continue; + if (!ace.IsInherited && !includeExplicit) continue; + + if (AceQualifier.SystemAudit != ace.AceQualifier) continue; + + AuditRule rule = InternalAuditRuleFactory (ace, targetType); + rules.Add (rule); + } + } + } finally { + ReadUnlock (); + } + + return new AuthorizationRuleCollection (rules.ToArray ()); + } + + internal virtual AuditRule InternalAuditRuleFactory (QualifiedAce ace, Type targetType) + { + return AuditRuleFactory (ace.SecurityIdentifier.Translate (targetType), + ace.AccessMask, ace.IsInherited, + ace.InheritanceFlags, ace.PropagationFlags, ace.AuditFlags); + } + + internal static SecurityIdentifier SidFromIR (IdentityReference identity) + { + if (null == identity) + throw new ArgumentNullException ("identity"); + + return (SecurityIdentifier)identity.Translate (typeof (SecurityIdentifier)); + } + + bool AreAccessControlSectionsModified (AccessControlSections mask) + { + return 0 != (AccessControlSectionsModified & mask); + } + + void SetAccessControlSectionsModified(AccessControlSections mask, bool modified) + { + if (modified) + AccessControlSectionsModified |= mask; + else + AccessControlSectionsModified &= ~mask; } } } diff --git a/mcs/class/corlib/System.Security.AccessControl/ObjectSecurity_T.cs b/mcs/class/corlib/System.Security.AccessControl/ObjectSecurity_T.cs index 2f002577ada..5977c7066df 100644 --- a/mcs/class/corlib/System.Security.AccessControl/ObjectSecurity_T.cs +++ b/mcs/class/corlib/System.Security.AccessControl/ObjectSecurity_T.cs @@ -1,7 +1,12 @@ // // System.Security.AccessControl.ObjectSecurity<T> // +// Authors: +// ? +// James Bellinger <jfb@zer7.com> +// // Copyright (C) 2009 Novell, Inc (http://www.novell.com) +// Copyright (C) 2012 James Bellinger // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -32,11 +37,6 @@ namespace System.Security.AccessControl { public abstract class ObjectSecurity<T> : NativeObjectSecurity where T : struct { - internal ObjectSecurity () - { - - } - protected ObjectSecurity (bool isContainer, ResourceType resourceType) : base (isContainer, resourceType) @@ -87,32 +87,105 @@ namespace System.Security.AccessControl } public override Type AccessRightType { - get { - return typeof(T); - } + get { return typeof (T); } } public override Type AccessRuleType { - get { - return typeof (AccessRule<T>); - } + get { return typeof (AccessRule<T>); } } public override Type AuditRuleType { - get { - return typeof (AuditRule<T>); - } + get { return typeof (AuditRule<T>); } } - public override AccessRule AccessRuleFactory(IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type) + public override AccessRule AccessRuleFactory(IdentityReference identityReference, int accessMask, + bool isInherited, InheritanceFlags inheritanceFlags, + PropagationFlags propagationFlags, AccessControlType type) { return new AccessRule<T> (identityReference, accessMask, isInherited, inheritanceFlags, propagationFlags, type); } - public override AuditRule AuditRuleFactory(IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags flags) + public void AddAccessRule (AccessRule<T> rule) + { + AddAccessRule ((AccessRule)rule); + } + + public bool RemoveAccessRule (AccessRule<T> rule) + { + return RemoveAccessRule ((AccessRule)rule); + } + + public void RemoveAccessRuleAll (AccessRule<T> rule) + { + RemoveAccessRuleAll ((AccessRule)rule); + } + + public void RemoveAccessRuleSpecific (AccessRule<T> rule) + { + RemoveAccessRuleSpecific ((AccessRule)rule); + } + + public void ResetAccessRule (AccessRule<T> rule) + { + ResetAccessRule ((AccessRule)rule); + } + + public void SetAccessRule (AccessRule<T> rule) + { + SetAccessRule ((AccessRule)rule); + } + + public override AuditRule AuditRuleFactory(IdentityReference identityReference, int accessMask, + bool isInherited, InheritanceFlags inheritanceFlags, + PropagationFlags propagationFlags, AuditFlags flags) { return new AuditRule<T> (identityReference, accessMask, isInherited, inheritanceFlags, propagationFlags, flags); } + + public void AddAuditRule (AuditRule<T> rule) + { + AddAuditRule ((AuditRule)rule); + } + + public bool RemoveAuditRule (AuditRule<T> rule) + { + return RemoveAuditRule((AuditRule)rule); + } + + public void RemoveAuditRuleAll (AuditRule<T> rule) + { + RemoveAuditRuleAll((AuditRule)rule); + } + + public void RemoveAuditRuleSpecific (AuditRule<T> rule) + { + RemoveAuditRuleSpecific((AuditRule)rule); + } + + public void SetAuditRule (AuditRule<T> rule) + { + SetAuditRule((AuditRule)rule); + } + + protected void Persist (SafeHandle handle) + { + WriteLock (); + try { + Persist (handle, AccessControlSectionsModified); + } finally { + WriteUnlock (); + } + } + + protected void Persist (string name) + { + WriteLock (); + try { + Persist (name, AccessControlSectionsModified); + } finally { + WriteUnlock (); + } + } } } diff --git a/mcs/class/corlib/System.Security.AccessControl/RegistryAccessRule.cs b/mcs/class/corlib/System.Security.AccessControl/RegistryAccessRule.cs index fdb1859ed0c..bc9917be80d 100644 --- a/mcs/class/corlib/System.Security.AccessControl/RegistryAccessRule.cs +++ b/mcs/class/corlib/System.Security.AccessControl/RegistryAccessRule.cs @@ -33,8 +33,6 @@ namespace System.Security.AccessControl { public sealed class RegistryAccessRule : AccessRule { - RegistryRights rights; - public RegistryAccessRule (IdentityReference identity, RegistryRights registryRights, AccessControlType type) @@ -56,7 +54,6 @@ namespace System.Security.AccessControl AccessControlType type) : base (identity, (int)registryRights, false, inheritanceFlags, propagationFlags, type) { - this.rights = registryRights; } public RegistryAccessRule (string identity, @@ -69,7 +66,7 @@ namespace System.Security.AccessControl } public RegistryRights RegistryRights { - get { return rights; } + get { return (RegistryRights)AccessMask; } } } } diff --git a/mcs/class/corlib/System.Security.AccessControl/RegistryAuditRule.cs b/mcs/class/corlib/System.Security.AccessControl/RegistryAuditRule.cs index 73edde38d40..17c4ee41a59 100644 --- a/mcs/class/corlib/System.Security.AccessControl/RegistryAuditRule.cs +++ b/mcs/class/corlib/System.Security.AccessControl/RegistryAuditRule.cs @@ -33,16 +33,13 @@ namespace System.Security.AccessControl { public sealed class RegistryAuditRule : AuditRule { - RegistryRights rights; - public RegistryAuditRule (IdentityReference identity, RegistryRights registryRights, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags flags) - : base (identity, 0, false, inheritanceFlags, propagationFlags, flags) + : base (identity, (int)registryRights, false, inheritanceFlags, propagationFlags, flags) { - this.rights = registryRights; } public RegistryAuditRule (string identity, @@ -50,12 +47,12 @@ namespace System.Security.AccessControl InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags flags) - : this (new SecurityIdentifier (identity), registryRights, inheritanceFlags, propagationFlags, flags) + : this (new NTAccount (identity), registryRights, inheritanceFlags, propagationFlags, flags) { } public RegistryRights RegistryRights { - get { return rights; } + get { return (RegistryRights)AccessMask; } } } } diff --git a/mcs/class/corlib/System.Security.AccessControl/RegistrySecurity.cs b/mcs/class/corlib/System.Security.AccessControl/RegistrySecurity.cs index 4ef5bce36e6..64e336e0248 100644 --- a/mcs/class/corlib/System.Security.AccessControl/RegistrySecurity.cs +++ b/mcs/class/corlib/System.Security.AccessControl/RegistrySecurity.cs @@ -4,8 +4,10 @@ // Authors: // Dick Porter <dick@ximian.com> // Atsushi Enomoto <atsushi@ximian.com> +// James Bellinger <jfb@zer7.com> // // Copyright (C) 2006-2007 Novell, Inc (http://www.novell.com) +// Copyright (C) 2012 James Bellinger // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -29,9 +31,12 @@ using System.Security.Principal; -namespace System.Security.AccessControl { - public sealed class RegistrySecurity : NativeObjectSecurity { +namespace System.Security.AccessControl +{ + public sealed class RegistrySecurity : NativeObjectSecurity + { public RegistrySecurity () + : base (false, ResourceType.RegistryKey) { } @@ -47,71 +52,75 @@ namespace System.Security.AccessControl { get { return typeof (RegistryAuditRule); } } - public override AccessRule AccessRuleFactory (IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type) + public override AccessRule AccessRuleFactory (IdentityReference identityReference, int accessMask, + bool isInherited, InheritanceFlags inheritanceFlags, + PropagationFlags propagationFlags, AccessControlType type) { - // FIXME: isInherited is unused - return new RegistryAccessRule (identityReference, (RegistryRights) accessMask, inheritanceFlags, propagationFlags, type); + return new RegistryAccessRule (identityReference, (RegistryRights) accessMask, + inheritanceFlags, propagationFlags, type); } public void AddAccessRule (RegistryAccessRule rule) { - throw new NotImplementedException (); + AddAccessRule ((AccessRule)rule); } - public void AddAuditRule (RegistryAuditRule rule) + public bool RemoveAccessRule (RegistryAccessRule rule) { - throw new NotImplementedException (); + return RemoveAccessRule ((AccessRule)rule); } - public override AuditRule AuditRuleFactory (IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags flags) + public void RemoveAccessRuleAll (RegistryAccessRule rule) { - // FIXME: isInherited is unused - return new RegistryAuditRule (identityReference, (RegistryRights) accessMask, inheritanceFlags, propagationFlags, flags); + RemoveAccessRuleAll ((AccessRule)rule); } - public bool RemoveAccessRule (RegistryAccessRule rule) + public void RemoveAccessRuleSpecific (RegistryAccessRule rule) { - throw new NotImplementedException (); + RemoveAccessRuleSpecific ((AccessRule)rule); } - public void RemoveAccessRuleAll (RegistryAccessRule rule) + public void ResetAccessRule (RegistryAccessRule rule) { - throw new NotImplementedException (); + ResetAccessRule ((AccessRule)rule); } - public void RemoveAccessRuleSpecific (RegistryAccessRule rule) + public void SetAccessRule (RegistryAccessRule rule) { - throw new NotImplementedException (); + SetAccessRule ((AccessRule)rule); } - public bool RemoveAuditRule (RegistryAuditRule rule) + public override AuditRule AuditRuleFactory (IdentityReference identityReference, int accessMask, + bool isInherited, InheritanceFlags inheritanceFlags, + PropagationFlags propagationFlags, AuditFlags flags) { - throw new NotImplementedException (); + return new RegistryAuditRule (identityReference, (RegistryRights) accessMask, + inheritanceFlags, propagationFlags, flags); } - public void RemoveAuditRuleAll (RegistryAuditRule rule) + public void AddAuditRule (RegistryAuditRule rule) { - throw new NotImplementedException (); + AddAuditRule ((AuditRule)rule); } - public void RemoveAuditRuleSpecific (RegistryAuditRule rule) + public bool RemoveAuditRule (RegistryAuditRule rule) { - throw new NotImplementedException (); + return RemoveAuditRule((AuditRule)rule); } - public void ResetAccessRule (RegistryAccessRule rule) + public void RemoveAuditRuleAll (RegistryAuditRule rule) { - throw new NotImplementedException (); + RemoveAuditRuleAll((AuditRule)rule); } - public void SetAccessRule (RegistryAccessRule rule) + public void RemoveAuditRuleSpecific (RegistryAuditRule rule) { - throw new NotImplementedException (); + RemoveAuditRuleSpecific((AuditRule)rule); } public void SetAuditRule (RegistryAuditRule rule) { - throw new NotImplementedException (); + SetAuditRule((AuditRule)rule); } } } diff --git a/mcs/class/corlib/System.Security.AccessControl/ResourceType.cs b/mcs/class/corlib/System.Security.AccessControl/ResourceType.cs index 3231271edbb..426a0831947 100644 --- a/mcs/class/corlib/System.Security.AccessControl/ResourceType.cs +++ b/mcs/class/corlib/System.Security.AccessControl/ResourceType.cs @@ -27,8 +27,11 @@ // -namespace System.Security.AccessControl { - public enum ResourceType { +namespace System.Security.AccessControl +{ + // These directly correspond to Win32 SE_OBJECT_TYPE. + public enum ResourceType + { Unknown = 0, FileObject = 1, Service = 2, diff --git a/mcs/class/corlib/System.Security.AccessControl/SystemAcl.cs b/mcs/class/corlib/System.Security.AccessControl/SystemAcl.cs index 5005bedda40..3d41d02c6ca 100644 --- a/mcs/class/corlib/System.Security.AccessControl/SystemAcl.cs +++ b/mcs/class/corlib/System.Security.AccessControl/SystemAcl.cs @@ -72,6 +72,7 @@ namespace System.Security.AccessControl objectFlags, objectType, inheritedObjectType); } + [MonoTODO] public bool RemoveAudit (AuditFlags auditFlags, SecurityIdentifier sid, int accessMask, @@ -81,6 +82,7 @@ namespace System.Security.AccessControl throw new NotImplementedException (); } + [MonoTODO] public bool RemoveAudit (AuditFlags auditFlags, SecurityIdentifier sid, int accessMask, |