2
0

ACE.cs 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. // This code is derived from jcifs smb client library <jcifs at samba dot org>
  2. // Ported by J. Arturo <webmaster at komodosoft dot net>
  3. //
  4. // This library is free software; you can redistribute it and/or
  5. // modify it under the terms of the GNU Lesser General Public
  6. // License as published by the Free Software Foundation; either
  7. // version 2.1 of the License, or (at your option) any later version.
  8. //
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. // Lesser General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Lesser General Public
  15. // License along with this library; if not, write to the Free Software
  16. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17. using System.Text;
  18. using SharpCifs.Util;
  19. namespace SharpCifs.Smb
  20. {
  21. /// <summary>
  22. /// An Access Control Entry (ACE) is an element in a security descriptor
  23. /// such as those associated with files and directories.
  24. /// </summary>
  25. /// <remarks>
  26. /// An Access Control Entry (ACE) is an element in a security descriptor
  27. /// such as those associated with files and directories. The Windows OS
  28. /// determines which users have the necessary permissions to access objects
  29. /// based on these entries.
  30. /// <p>
  31. /// To fully understand the information exposed by this class a description
  32. /// of the access check algorithm used by Windows is required. The following
  33. /// is a basic description of the algorithm. For a more complete description
  34. /// we recommend reading the section on Access Control in Keith Brown's
  35. /// "The .NET Developer's Guide to Windows Security" (which is also
  36. /// available online).
  37. /// <p>
  38. /// Direct ACEs are evaluated first in order. The SID of the user performing
  39. /// the operation and the desired access bits are compared to the SID
  40. /// and access mask of each ACE. If the SID matches, the allow/deny flags
  41. /// and access mask are considered. If the ACE is a "deny"
  42. /// ACE and <i>any</i> of the desired access bits match bits in the access
  43. /// mask of the ACE, the whole access check fails. If the ACE is an "allow"
  44. /// ACE and <i>all</i> of the bits in the desired access bits match bits in
  45. /// the access mask of the ACE, the access check is successful. Otherwise,
  46. /// more ACEs are evaluated until all desired access bits (combined)
  47. /// are "allowed". If all of the desired access bits are not "allowed"
  48. /// the then same process is repeated for inherited ACEs.
  49. /// <p>
  50. /// For example, if user <tt>WNET\alice</tt> tries to open a file
  51. /// with desired access bits <tt>0x00000003</tt> (<tt>FILE_READ_DATA |
  52. /// FILE_WRITE_DATA</tt>) and the target file has the following security
  53. /// descriptor ACEs:
  54. /// <pre>
  55. /// Allow WNET\alice 0x001200A9 Direct
  56. /// Allow Administrators 0x001F01FF Inherited
  57. /// Allow SYSTEM 0x001F01FF Inherited
  58. /// </pre>
  59. /// the access check would fail because the direct ACE has an access mask
  60. /// of <tt>0x001200A9</tt> which doesn't have the
  61. /// <tt>FILE_WRITE_DATA</tt> bit on (bit <tt>0x00000002</tt>). Actually, this isn't quite correct. If
  62. /// <tt>WNET\alice</tt> is in the local <tt>Administrators</tt> group the access check
  63. /// will succeed because the inherited ACE allows local <tt>Administrators</tt>
  64. /// both <tt>FILE_READ_DATA</tt> and <tt>FILE_WRITE_DATA</tt> access.
  65. /// </remarks>
  66. public class Ace
  67. {
  68. public const int FileReadData = unchecked(0x00000001);
  69. public const int FileWriteData = unchecked(0x00000002);
  70. public const int FileAppendData = unchecked(0x00000004);
  71. public const int FileReadEa = unchecked(0x00000008);
  72. public const int FileWriteEa = unchecked(0x00000010);
  73. public const int FileExecute = unchecked(0x00000020);
  74. public const int FileDelete = unchecked(0x00000040);
  75. public const int FileReadAttributes = unchecked(0x00000080);
  76. public const int FileWriteAttributes = unchecked(0x00000100);
  77. public const int Delete = unchecked(0x00010000);
  78. public const int ReadControl = unchecked(0x00020000);
  79. public const int WriteDac = unchecked(0x00040000);
  80. public const int WriteOwner = unchecked(0x00080000);
  81. public const int Synchronize = unchecked(0x00100000);
  82. public const int GenericAll = unchecked(0x10000000);
  83. public const int GenericExecute = unchecked(0x20000000);
  84. public const int GenericWrite = unchecked(0x40000000);
  85. public const int GenericRead = unchecked((int)(0x80000000));
  86. public const int FlagsObjectInherit = unchecked(0x01);
  87. public const int FlagsContainerInherit = unchecked(0x02);
  88. public const int FlagsNoPropagate = unchecked(0x04);
  89. public const int FlagsInheritOnly = unchecked(0x08);
  90. public const int FlagsInherited = unchecked(0x10);
  91. internal bool Allow;
  92. internal int Flags;
  93. internal int Access;
  94. internal Sid Sid;
  95. // 1
  96. // 2
  97. // 3
  98. // 4
  99. // 5
  100. // 6
  101. // 7
  102. // 8
  103. // 9
  104. // 16
  105. // 17
  106. // 18
  107. // 19
  108. // 20
  109. // 28
  110. // 29
  111. // 30
  112. // 31
  113. /// <summary>Returns true if this ACE is an allow ACE and false if it is a deny ACE.</summary>
  114. /// <remarks>Returns true if this ACE is an allow ACE and false if it is a deny ACE.</remarks>
  115. public virtual bool IsAllow()
  116. {
  117. return Allow;
  118. }
  119. /// <summary>Returns true if this ACE is an inherited ACE and false if it is a direct ACE.
  120. /// </summary>
  121. /// <remarks>
  122. /// Returns true if this ACE is an inherited ACE and false if it is a direct ACE.
  123. /// <p>
  124. /// Note: For reasons not fully understood, <tt>FLAGS_INHERITED</tt> may
  125. /// not be set within all security descriptors even though the ACE was in
  126. /// face inherited. If an inherited ACE is added to a parent the Windows
  127. /// ACL editor will rebuild all children ACEs and set this flag accordingly.
  128. /// </remarks>
  129. public virtual bool IsInherited()
  130. {
  131. return (Flags & FlagsInherited) != 0;
  132. }
  133. /// <summary>Returns the flags for this ACE.</summary>
  134. /// <remarks>
  135. /// Returns the flags for this ACE. The </tt>isInherited()</tt>
  136. /// method checks the <tt>FLAGS_INHERITED</tt> bit in these flags.
  137. /// </remarks>
  138. public virtual int GetFlags()
  139. {
  140. return Flags;
  141. }
  142. /// <summary>
  143. /// Returns the 'Apply To' text for inheritance of ACEs on
  144. /// directories such as 'This folder, subfolder and files'.
  145. /// </summary>
  146. /// <remarks>
  147. /// Returns the 'Apply To' text for inheritance of ACEs on
  148. /// directories such as 'This folder, subfolder and files'. For
  149. /// files the text is always 'This object only'.
  150. /// </remarks>
  151. public virtual string GetApplyToText()
  152. {
  153. switch (Flags & (FlagsObjectInherit | FlagsContainerInherit | FlagsInheritOnly
  154. ))
  155. {
  156. case unchecked(0x00):
  157. {
  158. return "This folder only";
  159. }
  160. case unchecked(0x03):
  161. {
  162. return "This folder, subfolders and files";
  163. }
  164. case unchecked(0x0B):
  165. {
  166. return "Subfolders and files only";
  167. }
  168. case unchecked(0x02):
  169. {
  170. return "This folder and subfolders";
  171. }
  172. case unchecked(0x0A):
  173. {
  174. return "Subfolders only";
  175. }
  176. case unchecked(0x01):
  177. {
  178. return "This folder and files";
  179. }
  180. case unchecked(0x09):
  181. {
  182. return "Files only";
  183. }
  184. }
  185. return "Invalid";
  186. }
  187. /// <summary>Returns the access mask accociated with this ACE.</summary>
  188. /// <remarks>
  189. /// Returns the access mask accociated with this ACE. Use the
  190. /// constants for <tt>FILE_READ_DATA</tt>, <tt>FILE_WRITE_DATA</tt>,
  191. /// <tt>READ_CONTROL</tt>, <tt>GENERIC_ALL</tt>, etc with bitwise
  192. /// operators to determine which bits of the mask are on or off.
  193. /// </remarks>
  194. public virtual int GetAccessMask()
  195. {
  196. return Access;
  197. }
  198. /// <summary>Return the SID associated with this ACE.</summary>
  199. /// <remarks>Return the SID associated with this ACE.</remarks>
  200. public virtual Sid GetSid()
  201. {
  202. return Sid;
  203. }
  204. internal virtual int Decode(byte[] buf, int bi)
  205. {
  206. Allow = buf[bi++] == unchecked(unchecked(0x00));
  207. Flags = buf[bi++] & unchecked(0xFF);
  208. int size = ServerMessageBlock.ReadInt2(buf, bi);
  209. bi += 2;
  210. Access = ServerMessageBlock.ReadInt4(buf, bi);
  211. bi += 4;
  212. Sid = new Sid(buf, bi);
  213. return size;
  214. }
  215. internal virtual void AppendCol(StringBuilder sb, string str, int width)
  216. {
  217. sb.Append(str);
  218. int count = width - str.Length;
  219. for (int i = 0; i < count; i++)
  220. {
  221. sb.Append(' ');
  222. }
  223. }
  224. /// <summary>Return a string represeting this ACE.</summary>
  225. /// <remarks>
  226. /// Return a string represeting this ACE.
  227. /// <p>
  228. /// Note: This function should probably be changed to return SDDL
  229. /// fragments but currently it does not.
  230. /// </remarks>
  231. public override string ToString()
  232. {
  233. int count;
  234. int i;
  235. string str;
  236. StringBuilder sb = new StringBuilder();
  237. sb.Append(IsAllow() ? "Allow " : "Deny ");
  238. AppendCol(sb, Sid.ToDisplayString(), 25);
  239. sb.Append(" 0x").Append(Hexdump.ToHexString(Access, 8)).Append(' ');
  240. sb.Append(IsInherited() ? "Inherited " : "Direct ");
  241. AppendCol(sb, GetApplyToText(), 34);
  242. return sb.ToString();
  243. }
  244. }
  245. }