aboutsummaryrefslogtreecommitdiff
path: root/Emby.Server.Implementations/IO/SharpCifs/Smb/ACE.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Emby.Server.Implementations/IO/SharpCifs/Smb/ACE.cs')
-rw-r--r--Emby.Server.Implementations/IO/SharpCifs/Smb/ACE.cs287
1 files changed, 287 insertions, 0 deletions
diff --git a/Emby.Server.Implementations/IO/SharpCifs/Smb/ACE.cs b/Emby.Server.Implementations/IO/SharpCifs/Smb/ACE.cs
new file mode 100644
index 000000000..73b742cfb
--- /dev/null
+++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/ACE.cs
@@ -0,0 +1,287 @@
+// This code is derived from jcifs smb client library <jcifs at samba dot org>
+// Ported by J. Arturo <webmaster at komodosoft dot net>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+using System.Text;
+using SharpCifs.Util;
+
+namespace SharpCifs.Smb
+{
+ /// <summary>
+ /// An Access Control Entry (ACE) is an element in a security descriptor
+ /// such as those associated with files and directories.
+ /// </summary>
+ /// <remarks>
+ /// An Access Control Entry (ACE) is an element in a security descriptor
+ /// such as those associated with files and directories. The Windows OS
+ /// determines which users have the necessary permissions to access objects
+ /// based on these entries.
+ /// <p>
+ /// To fully understand the information exposed by this class a description
+ /// of the access check algorithm used by Windows is required. The following
+ /// is a basic description of the algorithm. For a more complete description
+ /// we recommend reading the section on Access Control in Keith Brown's
+ /// "The .NET Developer's Guide to Windows Security" (which is also
+ /// available online).
+ /// <p>
+ /// Direct ACEs are evaluated first in order. The SID of the user performing
+ /// the operation and the desired access bits are compared to the SID
+ /// and access mask of each ACE. If the SID matches, the allow/deny flags
+ /// and access mask are considered. If the ACE is a "deny"
+ /// ACE and <i>any</i> of the desired access bits match bits in the access
+ /// mask of the ACE, the whole access check fails. If the ACE is an "allow"
+ /// ACE and <i>all</i> of the bits in the desired access bits match bits in
+ /// the access mask of the ACE, the access check is successful. Otherwise,
+ /// more ACEs are evaluated until all desired access bits (combined)
+ /// are "allowed". If all of the desired access bits are not "allowed"
+ /// the then same process is repeated for inherited ACEs.
+ /// <p>
+ /// For example, if user <tt>WNET\alice</tt> tries to open a file
+ /// with desired access bits <tt>0x00000003</tt> (<tt>FILE_READ_DATA |
+ /// FILE_WRITE_DATA</tt>) and the target file has the following security
+ /// descriptor ACEs:
+ /// <pre>
+ /// Allow WNET\alice 0x001200A9 Direct
+ /// Allow Administrators 0x001F01FF Inherited
+ /// Allow SYSTEM 0x001F01FF Inherited
+ /// </pre>
+ /// the access check would fail because the direct ACE has an access mask
+ /// of <tt>0x001200A9</tt> which doesn't have the
+ /// <tt>FILE_WRITE_DATA</tt> bit on (bit <tt>0x00000002</tt>). Actually, this isn't quite correct. If
+ /// <tt>WNET\alice</tt> is in the local <tt>Administrators</tt> group the access check
+ /// will succeed because the inherited ACE allows local <tt>Administrators</tt>
+ /// both <tt>FILE_READ_DATA</tt> and <tt>FILE_WRITE_DATA</tt> access.
+ /// </remarks>
+ public class Ace
+ {
+ public const int FileReadData = unchecked(0x00000001);
+
+ public const int FileWriteData = unchecked(0x00000002);
+
+ public const int FileAppendData = unchecked(0x00000004);
+
+ public const int FileReadEa = unchecked(0x00000008);
+
+ public const int FileWriteEa = unchecked(0x00000010);
+
+ public const int FileExecute = unchecked(0x00000020);
+
+ public const int FileDelete = unchecked(0x00000040);
+
+ public const int FileReadAttributes = unchecked(0x00000080);
+
+ public const int FileWriteAttributes = unchecked(0x00000100);
+
+ public const int Delete = unchecked(0x00010000);
+
+ public const int ReadControl = unchecked(0x00020000);
+
+ public const int WriteDac = unchecked(0x00040000);
+
+ public const int WriteOwner = unchecked(0x00080000);
+
+ public const int Synchronize = unchecked(0x00100000);
+
+ public const int GenericAll = unchecked(0x10000000);
+
+ public const int GenericExecute = unchecked(0x20000000);
+
+ public const int GenericWrite = unchecked(0x40000000);
+
+ public const int GenericRead = unchecked((int)(0x80000000));
+
+ public const int FlagsObjectInherit = unchecked(0x01);
+
+ public const int FlagsContainerInherit = unchecked(0x02);
+
+ public const int FlagsNoPropagate = unchecked(0x04);
+
+ public const int FlagsInheritOnly = unchecked(0x08);
+
+ public const int FlagsInherited = unchecked(0x10);
+
+ internal bool Allow;
+
+ internal int Flags;
+
+ internal int Access;
+
+ internal Sid Sid;
+
+ // 1
+ // 2
+ // 3
+ // 4
+ // 5
+ // 6
+ // 7
+ // 8
+ // 9
+ // 16
+ // 17
+ // 18
+ // 19
+ // 20
+ // 28
+ // 29
+ // 30
+ // 31
+ /// <summary>Returns true if this ACE is an allow ACE and false if it is a deny ACE.</summary>
+ /// <remarks>Returns true if this ACE is an allow ACE and false if it is a deny ACE.</remarks>
+ public virtual bool IsAllow()
+ {
+ return Allow;
+ }
+
+ /// <summary>Returns true if this ACE is an inherited ACE and false if it is a direct ACE.
+ /// </summary>
+ /// <remarks>
+ /// Returns true if this ACE is an inherited ACE and false if it is a direct ACE.
+ /// <p>
+ /// Note: For reasons not fully understood, <tt>FLAGS_INHERITED</tt> may
+ /// not be set within all security descriptors even though the ACE was in
+ /// face inherited. If an inherited ACE is added to a parent the Windows
+ /// ACL editor will rebuild all children ACEs and set this flag accordingly.
+ /// </remarks>
+ public virtual bool IsInherited()
+ {
+ return (Flags & FlagsInherited) != 0;
+ }
+
+ /// <summary>Returns the flags for this ACE.</summary>
+ /// <remarks>
+ /// Returns the flags for this ACE. The </tt>isInherited()</tt>
+ /// method checks the <tt>FLAGS_INHERITED</tt> bit in these flags.
+ /// </remarks>
+ public virtual int GetFlags()
+ {
+ return Flags;
+ }
+
+ /// <summary>
+ /// Returns the 'Apply To' text for inheritance of ACEs on
+ /// directories such as 'This folder, subfolder and files'.
+ /// </summary>
+ /// <remarks>
+ /// Returns the 'Apply To' text for inheritance of ACEs on
+ /// directories such as 'This folder, subfolder and files'. For
+ /// files the text is always 'This object only'.
+ /// </remarks>
+ public virtual string GetApplyToText()
+ {
+ switch (Flags & (FlagsObjectInherit | FlagsContainerInherit | FlagsInheritOnly
+ ))
+ {
+ case unchecked(0x00):
+ {
+ return "This folder only";
+ }
+
+ case unchecked(0x03):
+ {
+ return "This folder, subfolders and files";
+ }
+
+ case unchecked(0x0B):
+ {
+ return "Subfolders and files only";
+ }
+
+ case unchecked(0x02):
+ {
+ return "This folder and subfolders";
+ }
+
+ case unchecked(0x0A):
+ {
+ return "Subfolders only";
+ }
+
+ case unchecked(0x01):
+ {
+ return "This folder and files";
+ }
+
+ case unchecked(0x09):
+ {
+ return "Files only";
+ }
+ }
+ return "Invalid";
+ }
+
+ /// <summary>Returns the access mask accociated with this ACE.</summary>
+ /// <remarks>
+ /// Returns the access mask accociated with this ACE. Use the
+ /// constants for <tt>FILE_READ_DATA</tt>, <tt>FILE_WRITE_DATA</tt>,
+ /// <tt>READ_CONTROL</tt>, <tt>GENERIC_ALL</tt>, etc with bitwise
+ /// operators to determine which bits of the mask are on or off.
+ /// </remarks>
+ public virtual int GetAccessMask()
+ {
+ return Access;
+ }
+
+ /// <summary>Return the SID associated with this ACE.</summary>
+ /// <remarks>Return the SID associated with this ACE.</remarks>
+ public virtual Sid GetSid()
+ {
+ return Sid;
+ }
+
+ internal virtual int Decode(byte[] buf, int bi)
+ {
+ Allow = buf[bi++] == unchecked(unchecked(0x00));
+ Flags = buf[bi++] & unchecked(0xFF);
+ int size = ServerMessageBlock.ReadInt2(buf, bi);
+ bi += 2;
+ Access = ServerMessageBlock.ReadInt4(buf, bi);
+ bi += 4;
+ Sid = new Sid(buf, bi);
+ return size;
+ }
+
+ internal virtual void AppendCol(StringBuilder sb, string str, int width)
+ {
+ sb.Append(str);
+ int count = width - str.Length;
+ for (int i = 0; i < count; i++)
+ {
+ sb.Append(' ');
+ }
+ }
+
+ /// <summary>Return a string represeting this ACE.</summary>
+ /// <remarks>
+ /// Return a string represeting this ACE.
+ /// <p>
+ /// Note: This function should probably be changed to return SDDL
+ /// fragments but currently it does not.
+ /// </remarks>
+ public override string ToString()
+ {
+ int count;
+ int i;
+ string str;
+ StringBuilder sb = new StringBuilder();
+ sb.Append(IsAllow() ? "Allow " : "Deny ");
+ AppendCol(sb, Sid.ToDisplayString(), 25);
+ sb.Append(" 0x").Append(Hexdump.ToHexString(Access, 8)).Append(' ');
+ sb.Append(IsInherited() ? "Inherited " : "Direct ");
+ AppendCol(sb, GetApplyToText(), 34);
+ return sb.ToString();
+ }
+ }
+}