2 // System.Security.AccessControl.CommonSecurityDescriptor implementation
5 // Dick Porter <dick@ximian.com>
6 // James Bellinger <jfb@zer7.com>
8 // Copyright (C) 2006 Novell, Inc (http://www.novell.com)
9 // Copyright (C) 2012 James Bellinger
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 using System.Security.Principal;
34 namespace System.Security.AccessControl
36 public sealed class CommonSecurityDescriptor : GenericSecurityDescriptor
41 SecurityIdentifier owner;
42 SecurityIdentifier group;
44 DiscretionaryAcl discretionary_acl;
46 public CommonSecurityDescriptor (bool isContainer, bool isDS, RawSecurityDescriptor rawSecurityDescriptor)
48 Init (isContainer, isDS, rawSecurityDescriptor);
51 public CommonSecurityDescriptor (bool isContainer, bool isDS, string sddlForm)
53 Init (isContainer, isDS, new RawSecurityDescriptor (sddlForm));
56 public CommonSecurityDescriptor (bool isContainer, bool isDS, byte[] binaryForm, int offset)
58 Init (isContainer, isDS, new RawSecurityDescriptor (binaryForm, offset));
61 public CommonSecurityDescriptor (bool isContainer, bool isDS,
63 SecurityIdentifier owner,
64 SecurityIdentifier group,
66 DiscretionaryAcl discretionaryAcl)
68 Init (isContainer, isDS, flags, owner, group, systemAcl, discretionaryAcl);
71 void Init (bool isContainer, bool isDS, RawSecurityDescriptor rawSecurityDescriptor)
73 if (null == rawSecurityDescriptor)
74 throw new ArgumentNullException ("rawSecurityDescriptor");
76 SystemAcl sacl = null;
77 if (null != rawSecurityDescriptor.SystemAcl)
78 sacl = new SystemAcl (isContainer, isDS, rawSecurityDescriptor.SystemAcl);
80 DiscretionaryAcl dacl = null;
81 if (null != rawSecurityDescriptor.DiscretionaryAcl)
82 dacl = new DiscretionaryAcl (isContainer, isDS, rawSecurityDescriptor.DiscretionaryAcl);
84 Init (isContainer, isDS,
85 rawSecurityDescriptor.ControlFlags,
86 rawSecurityDescriptor.Owner,
87 rawSecurityDescriptor.Group,
91 void Init (bool isContainer, bool isDS,
93 SecurityIdentifier owner,
94 SecurityIdentifier group,
96 DiscretionaryAcl discretionaryAcl)
98 this.flags = flags & ~ControlFlags.SystemAclPresent;
99 this.is_container = isContainer;
104 SystemAcl = systemAcl;
105 DiscretionaryAcl = discretionaryAcl;
108 public override ControlFlags ControlFlags {
110 ControlFlags realFlags = flags;
112 realFlags |= ControlFlags.DiscretionaryAclPresent;
113 realFlags |= ControlFlags.SelfRelative;
114 if (SystemAcl != null)
115 realFlags |= ControlFlags.SystemAclPresent;
121 public DiscretionaryAcl DiscretionaryAcl {
122 get { return discretionary_acl; }
125 value = new DiscretionaryAcl (IsContainer, IsDS, 1);
126 value.AddAccess (AccessControlType.Allow, new SecurityIdentifier ("WD"), -1,
127 IsContainer ? InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit
128 : InheritanceFlags.None, PropagationFlags.None);
132 CheckAclConsistency (value);
133 discretionary_acl = value;
137 internal override GenericAcl InternalDacl {
138 get { return DiscretionaryAcl; }
141 public override SecurityIdentifier Group {
142 get { return group; }
143 set { group = value; }
146 public bool IsContainer {
147 get { return is_container; }
150 public bool IsDiscretionaryAclCanonical {
151 get { return DiscretionaryAcl.IsCanonical; }
155 get { return is_ds; }
158 public bool IsSystemAclCanonical {
159 get { return SystemAcl == null || SystemAcl.IsCanonical; }
162 public override SecurityIdentifier Owner {
163 get { return owner; }
164 set { owner = value; }
167 public SystemAcl SystemAcl {
168 get { return system_acl; }
171 CheckAclConsistency (value);
177 internal override GenericAcl InternalSacl {
178 get { return SystemAcl; }
181 public void PurgeAccessControl (SecurityIdentifier sid)
183 DiscretionaryAcl.Purge (sid);
186 public void PurgeAudit (SecurityIdentifier sid)
188 if (SystemAcl != null)
189 SystemAcl.Purge (sid);
192 public void SetDiscretionaryAclProtection (bool isProtected,
193 bool preserveInheritance)
195 DiscretionaryAcl.IsAefa = false;
198 flags &= ~ControlFlags.DiscretionaryAclProtected;
202 flags |= ControlFlags.DiscretionaryAclProtected;
203 if (!preserveInheritance)
204 DiscretionaryAcl.RemoveInheritedAces ();
207 public void SetSystemAclProtection (bool isProtected,
208 bool preserveInheritance)
211 flags &= ~ControlFlags.SystemAclProtected;
215 flags |= ControlFlags.SystemAclProtected;
216 if (!preserveInheritance && SystemAcl != null)
217 SystemAcl.RemoveInheritedAces ();
220 public void AddDiscretionaryAcl (byte revision, int trusted)
222 DiscretionaryAcl = new DiscretionaryAcl (IsContainer, IsDS, revision, trusted);
223 flags |= ControlFlags.DiscretionaryAclPresent;
226 public void AddSystemAcl(byte revision, int trusted)
228 SystemAcl = new SystemAcl (IsContainer, IsDS, revision, trusted);
229 flags |= ControlFlags.SystemAclPresent;
232 void CheckAclConsistency (CommonAcl acl)
234 if (IsContainer != acl.IsContainer)
235 throw new ArgumentException ("IsContainer must match between descriptor and ACL.");
237 if (IsDS != acl.IsDS)
238 throw new ArgumentException ("IsDS must match between descriptor and ACL.");
241 internal override bool DaclIsUnmodifiedAefa {
242 get { return DiscretionaryAcl.IsAefa; }