CommonSecurityDescriptor.cs 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. //
  2. // System.Security.AccessControl.CommonSecurityDescriptor implementation
  3. //
  4. // Author:
  5. // Dick Porter <[email protected]>
  6. // James Bellinger <[email protected]>
  7. //
  8. // Copyright (C) 2006 Novell, Inc (http://www.novell.com)
  9. // Copyright (C) 2012 James Bellinger
  10. //
  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:
  18. //
  19. // The above copyright notice and this permission notice shall be
  20. // included in all copies or substantial portions of the Software.
  21. //
  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.
  29. //
  30. using System;
  31. using System.Security.Principal;
  32. namespace System.Security.AccessControl
  33. {
  34. public sealed class CommonSecurityDescriptor : GenericSecurityDescriptor
  35. {
  36. bool is_container;
  37. bool is_ds;
  38. ControlFlags flags;
  39. SecurityIdentifier owner;
  40. SecurityIdentifier group;
  41. SystemAcl system_acl;
  42. DiscretionaryAcl discretionary_acl;
  43. public CommonSecurityDescriptor (bool isContainer, bool isDS, RawSecurityDescriptor rawSecurityDescriptor)
  44. {
  45. Init (isContainer, isDS, rawSecurityDescriptor);
  46. }
  47. public CommonSecurityDescriptor (bool isContainer, bool isDS, string sddlForm)
  48. {
  49. Init (isContainer, isDS, new RawSecurityDescriptor (sddlForm));
  50. }
  51. public CommonSecurityDescriptor (bool isContainer, bool isDS, byte[] binaryForm, int offset)
  52. {
  53. Init (isContainer, isDS, new RawSecurityDescriptor (binaryForm, offset));
  54. }
  55. public CommonSecurityDescriptor (bool isContainer, bool isDS,
  56. ControlFlags flags,
  57. SecurityIdentifier owner,
  58. SecurityIdentifier group,
  59. SystemAcl systemAcl,
  60. DiscretionaryAcl discretionaryAcl)
  61. {
  62. Init (isContainer, isDS, flags, owner, group, systemAcl, discretionaryAcl);
  63. }
  64. void Init (bool isContainer, bool isDS, RawSecurityDescriptor rawSecurityDescriptor)
  65. {
  66. if (null == rawSecurityDescriptor)
  67. throw new ArgumentNullException ("rawSecurityDescriptor");
  68. SystemAcl sacl = null;
  69. if (null != rawSecurityDescriptor.SystemAcl)
  70. sacl = new SystemAcl (isContainer, isDS, rawSecurityDescriptor.SystemAcl);
  71. DiscretionaryAcl dacl = null;
  72. if (null != rawSecurityDescriptor.DiscretionaryAcl)
  73. dacl = new DiscretionaryAcl (isContainer, isDS, rawSecurityDescriptor.DiscretionaryAcl);
  74. Init (isContainer, isDS,
  75. rawSecurityDescriptor.ControlFlags,
  76. rawSecurityDescriptor.Owner,
  77. rawSecurityDescriptor.Group,
  78. sacl, dacl);
  79. }
  80. void Init (bool isContainer, bool isDS,
  81. ControlFlags flags,
  82. SecurityIdentifier owner,
  83. SecurityIdentifier group,
  84. SystemAcl systemAcl,
  85. DiscretionaryAcl discretionaryAcl)
  86. {
  87. this.flags = flags & ~ControlFlags.SystemAclPresent;
  88. this.is_container = isContainer;
  89. this.is_ds = isDS;
  90. Owner = owner;
  91. Group = group;
  92. SystemAcl = systemAcl;
  93. DiscretionaryAcl = discretionaryAcl;
  94. }
  95. public override ControlFlags ControlFlags {
  96. get {
  97. ControlFlags realFlags = flags;
  98. realFlags |= ControlFlags.DiscretionaryAclPresent;
  99. realFlags |= ControlFlags.SelfRelative;
  100. if (SystemAcl != null)
  101. realFlags |= ControlFlags.SystemAclPresent;
  102. return realFlags;
  103. }
  104. }
  105. public DiscretionaryAcl DiscretionaryAcl {
  106. get { return discretionary_acl; }
  107. set {
  108. if (value == null) {
  109. value = new DiscretionaryAcl (IsContainer, IsDS, 1);
  110. value.AddAccess (AccessControlType.Allow, new SecurityIdentifier ("WD"), -1,
  111. IsContainer ? InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit
  112. : InheritanceFlags.None, PropagationFlags.None);
  113. value.IsAefa = true;
  114. }
  115. CheckAclConsistency (value);
  116. discretionary_acl = value;
  117. }
  118. }
  119. internal override GenericAcl InternalDacl {
  120. get { return DiscretionaryAcl; }
  121. }
  122. public override SecurityIdentifier Group {
  123. get { return group; }
  124. set { group = value; }
  125. }
  126. public bool IsContainer {
  127. get { return is_container; }
  128. }
  129. public bool IsDiscretionaryAclCanonical {
  130. get { return DiscretionaryAcl.IsCanonical; }
  131. }
  132. public bool IsDS {
  133. get { return is_ds; }
  134. }
  135. public bool IsSystemAclCanonical {
  136. get { return SystemAcl == null || SystemAcl.IsCanonical; }
  137. }
  138. public override SecurityIdentifier Owner {
  139. get { return owner; }
  140. set { owner = value; }
  141. }
  142. public SystemAcl SystemAcl {
  143. get { return system_acl; }
  144. set {
  145. if (value != null)
  146. CheckAclConsistency (value);
  147. system_acl = value;
  148. }
  149. }
  150. internal override GenericAcl InternalSacl {
  151. get { return SystemAcl; }
  152. }
  153. public void PurgeAccessControl (SecurityIdentifier sid)
  154. {
  155. DiscretionaryAcl.Purge (sid);
  156. }
  157. public void PurgeAudit (SecurityIdentifier sid)
  158. {
  159. if (SystemAcl != null)
  160. SystemAcl.Purge (sid);
  161. }
  162. public void SetDiscretionaryAclProtection (bool isProtected,
  163. bool preserveInheritance)
  164. {
  165. DiscretionaryAcl.IsAefa = false;
  166. if (!isProtected) {
  167. flags &= ~ControlFlags.DiscretionaryAclProtected;
  168. return;
  169. }
  170. flags |= ControlFlags.DiscretionaryAclProtected;
  171. if (!preserveInheritance)
  172. DiscretionaryAcl.RemoveInheritedAces ();
  173. }
  174. public void SetSystemAclProtection (bool isProtected,
  175. bool preserveInheritance)
  176. {
  177. if (!isProtected) {
  178. flags &= ~ControlFlags.SystemAclProtected;
  179. return;
  180. }
  181. flags |= ControlFlags.SystemAclProtected;
  182. if (!preserveInheritance && SystemAcl != null)
  183. SystemAcl.RemoveInheritedAces ();
  184. }
  185. public void AddDiscretionaryAcl (byte revision, int trusted)
  186. {
  187. DiscretionaryAcl = new DiscretionaryAcl (IsContainer, IsDS, revision, trusted);
  188. flags |= ControlFlags.DiscretionaryAclPresent;
  189. }
  190. public void AddSystemAcl(byte revision, int trusted)
  191. {
  192. SystemAcl = new SystemAcl (IsContainer, IsDS, revision, trusted);
  193. flags |= ControlFlags.SystemAclPresent;
  194. }
  195. void CheckAclConsistency (CommonAcl acl)
  196. {
  197. if (IsContainer != acl.IsContainer)
  198. throw new ArgumentException ("IsContainer must match between descriptor and ACL.");
  199. if (IsDS != acl.IsDS)
  200. throw new ArgumentException ("IsDS must match between descriptor and ACL.");
  201. }
  202. internal override bool DaclIsUnmodifiedAefa {
  203. get { return DiscretionaryAcl.IsAefa; }
  204. }
  205. }
  206. }