ObjectAce.cs 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. //
  2. // System.Security.AccessControl.ObjectAce implementation
  3. //
  4. // Authors:
  5. // Dick Porter <[email protected]>
  6. // Atsushi Enomoto <[email protected]>
  7. // Kenneth Bell
  8. // James Bellinger <[email protected]>
  9. //
  10. // Copyright (C) 2006-2007 Novell, Inc (http://www.novell.com)
  11. // Copyright (C) 2012 James Bellinger
  12. //
  13. // Permission is hereby granted, free of charge, to any person obtaining
  14. // a copy of this software and associated documentation files (the
  15. // "Software"), to deal in the Software without restriction, including
  16. // without limitation the rights to use, copy, modify, merge, publish,
  17. // distribute, sublicense, and/or sell copies of the Software, and to
  18. // permit persons to whom the Software is furnished to do so, subject to
  19. // the following conditions:
  20. //
  21. // The above copyright notice and this permission notice shall be
  22. // included in all copies or substantial portions of the Software.
  23. //
  24. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  25. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  26. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  27. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  28. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  29. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  30. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  31. //
  32. using System.Security.Principal;
  33. using System.Globalization;
  34. namespace System.Security.AccessControl
  35. {
  36. public sealed class ObjectAce : QualifiedAce
  37. {
  38. private Guid object_ace_type;
  39. private Guid inherited_object_type;
  40. private ObjectAceFlags object_ace_flags;
  41. public ObjectAce (AceFlags aceFlags, AceQualifier qualifier,
  42. int accessMask, SecurityIdentifier sid,
  43. ObjectAceFlags flags, Guid type,
  44. Guid inheritedType, bool isCallback,
  45. byte[] opaque)
  46. : base (ConvertType(qualifier, isCallback), aceFlags, opaque)
  47. {
  48. AccessMask = accessMask;
  49. SecurityIdentifier = sid;
  50. ObjectAceFlags = flags;
  51. ObjectAceType = type;
  52. InheritedObjectAceType = inheritedType;
  53. }
  54. internal ObjectAce (AceType type, AceFlags flags, int accessMask,
  55. SecurityIdentifier sid, ObjectAceFlags objFlags,
  56. Guid objType, Guid inheritedType, byte[] opaque)
  57. : base(type, flags, opaque)
  58. {
  59. AccessMask = accessMask;
  60. SecurityIdentifier = sid;
  61. ObjectAceFlags = objFlags;
  62. ObjectAceType = objType;
  63. InheritedObjectAceType = inheritedType;
  64. }
  65. internal ObjectAce(byte[] binaryForm, int offset)
  66. : base(binaryForm, offset)
  67. {
  68. int len = ReadUShort(binaryForm, offset + 2);
  69. int lenMinimum = 12 + SecurityIdentifier.MinBinaryLength;
  70. if (offset > binaryForm.Length - len)
  71. throw new ArgumentException("Invalid ACE - truncated", "binaryForm");
  72. if (len < lenMinimum)
  73. throw new ArgumentException("Invalid ACE", "binaryForm");
  74. AccessMask = ReadInt(binaryForm, offset + 4);
  75. ObjectAceFlags = (ObjectAceFlags)ReadInt(binaryForm, offset + 8);
  76. if (ObjectAceTypePresent) lenMinimum += 16;
  77. if (InheritedObjectAceTypePresent) lenMinimum += 16;
  78. if (len < lenMinimum)
  79. throw new ArgumentException("Invalid ACE", "binaryForm");
  80. int pos = 12;
  81. if (ObjectAceTypePresent) {
  82. ObjectAceType = ReadGuid(binaryForm, offset + pos); pos += 16;
  83. }
  84. if (InheritedObjectAceTypePresent) {
  85. InheritedObjectAceType = ReadGuid(binaryForm, offset + pos); pos += 16;
  86. }
  87. SecurityIdentifier = new SecurityIdentifier(binaryForm, offset + pos);
  88. pos += SecurityIdentifier.BinaryLength;
  89. int opaqueLen = len - pos;
  90. if (opaqueLen > 0) {
  91. byte[] opaque = new byte[opaqueLen];
  92. Array.Copy(binaryForm, offset + pos, opaque, 0, opaqueLen);
  93. SetOpaque (opaque);
  94. }
  95. }
  96. public override int BinaryLength
  97. {
  98. get {
  99. int length = 12 + SecurityIdentifier.BinaryLength + OpaqueLength;
  100. if (ObjectAceTypePresent) length += 16;
  101. if (InheritedObjectAceTypePresent) length += 16;
  102. return length;
  103. }
  104. }
  105. public Guid InheritedObjectAceType {
  106. get { return inherited_object_type; }
  107. set { inherited_object_type = value; }
  108. }
  109. bool InheritedObjectAceTypePresent {
  110. get { return 0 != (ObjectAceFlags & ObjectAceFlags.InheritedObjectAceTypePresent); }
  111. }
  112. public ObjectAceFlags ObjectAceFlags {
  113. get { return object_ace_flags; }
  114. set { object_ace_flags = value; }
  115. }
  116. public Guid ObjectAceType {
  117. get { return object_ace_type; }
  118. set { object_ace_type = value; }
  119. }
  120. bool ObjectAceTypePresent {
  121. get { return 0 != (ObjectAceFlags & ObjectAceFlags.ObjectAceTypePresent); }
  122. }
  123. public override void GetBinaryForm (byte[] binaryForm, int offset)
  124. {
  125. int len = BinaryLength;
  126. binaryForm[offset++] = (byte)this.AceType;
  127. binaryForm[offset++] = (byte)this.AceFlags;
  128. WriteUShort ((ushort)len, binaryForm, offset); offset += 2;
  129. WriteInt (AccessMask, binaryForm, offset); offset += 4;
  130. WriteInt ((int)ObjectAceFlags, binaryForm, offset); offset += 4;
  131. if (0 != (ObjectAceFlags & ObjectAceFlags.ObjectAceTypePresent)) {
  132. WriteGuid (ObjectAceType, binaryForm, offset); offset += 16;
  133. }
  134. if (0 != (ObjectAceFlags & ObjectAceFlags.InheritedObjectAceTypePresent)) {
  135. WriteGuid (InheritedObjectAceType, binaryForm, offset); offset += 16;
  136. }
  137. SecurityIdentifier.GetBinaryForm (binaryForm, offset);
  138. offset += SecurityIdentifier.BinaryLength;
  139. byte[] opaque = GetOpaque ();
  140. if (opaque != null) {
  141. Array.Copy (opaque, 0, binaryForm, offset, opaque.Length);
  142. offset += opaque.Length;
  143. }
  144. }
  145. public static int MaxOpaqueLength (bool isCallback)
  146. {
  147. // Varies by platform?
  148. return 65423;
  149. }
  150. internal override string GetSddlForm()
  151. {
  152. if (OpaqueLength != 0)
  153. throw new NotImplementedException (
  154. "Unable to convert conditional ACEs to SDDL");
  155. string objType = "";
  156. if ((ObjectAceFlags & ObjectAceFlags.ObjectAceTypePresent) != 0)
  157. objType = object_ace_type.ToString("D");
  158. string inhObjType = "";
  159. if ((ObjectAceFlags & ObjectAceFlags.InheritedObjectAceTypePresent) != 0)
  160. inhObjType = inherited_object_type.ToString("D");
  161. return string.Format (CultureInfo.InvariantCulture,
  162. "({0};{1};{2};{3};{4};{5})",
  163. GetSddlAceType (AceType),
  164. GetSddlAceFlags (AceFlags),
  165. GetSddlAccessRights (AccessMask),
  166. objType,
  167. inhObjType,
  168. SecurityIdentifier.GetSddlForm ());
  169. }
  170. private static AceType ConvertType(AceQualifier qualifier, bool isCallback)
  171. {
  172. switch(qualifier)
  173. {
  174. case AceQualifier.AccessAllowed:
  175. if (isCallback)
  176. return AceType.AccessAllowedCallbackObject;
  177. else
  178. return AceType.AccessAllowedObject;
  179. case AceQualifier.AccessDenied:
  180. if (isCallback)
  181. return AceType.AccessDeniedCallbackObject;
  182. else
  183. return AceType.AccessDeniedObject;
  184. case AceQualifier.SystemAlarm:
  185. if (isCallback)
  186. return AceType.SystemAlarmCallbackObject;
  187. else
  188. return AceType.SystemAlarmObject;
  189. case AceQualifier.SystemAudit:
  190. if (isCallback)
  191. return AceType.SystemAuditCallbackObject;
  192. else
  193. return AceType.SystemAuditObject;
  194. default:
  195. throw new ArgumentException("Unrecognized ACE qualifier: " + qualifier, "qualifier");
  196. }
  197. }
  198. private void WriteGuid (Guid val, byte[] buffer,
  199. int offset)
  200. {
  201. byte[] guidData = val.ToByteArray();
  202. Array.Copy(guidData, 0, buffer, offset, 16);
  203. }
  204. private Guid ReadGuid(byte[] buffer, int offset)
  205. {
  206. byte[] temp = new byte[16];
  207. Array.Copy(buffer, offset, temp, 0, 16);
  208. return new Guid(temp);
  209. }
  210. }
  211. }