From bfcd1b520fd79b893e721ba916ae5e1656407d2f Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 16 Aug 2017 02:43:41 -0400 Subject: merge common implementations and server implementations --- .../IO/SharpCifs/Smb/ACE.cs | 287 +++++++++++++++++++++ 1 file changed, 287 insertions(+) create mode 100644 Emby.Server.Implementations/IO/SharpCifs/Smb/ACE.cs (limited to 'Emby.Server.Implementations/IO/SharpCifs/Smb/ACE.cs') 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 0000000000..73b742cfb6 --- /dev/null +++ b/Emby.Server.Implementations/IO/SharpCifs/Smb/ACE.cs @@ -0,0 +1,287 @@ +// This code is derived from jcifs smb client library +// Ported by J. Arturo +// +// 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 +{ + /// + /// An Access Control Entry (ACE) is an element in a security descriptor + /// such as those associated with files and directories. + /// + /// + /// 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. + ///

+ /// 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). + ///

+ /// 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 any 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 all 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. + ///

+ /// For example, if user WNET\alice tries to open a file + /// with desired access bits 0x00000003 (FILE_READ_DATA | + /// FILE_WRITE_DATA) and the target file has the following security + /// descriptor ACEs: + ///

+	/// Allow WNET\alice     0x001200A9  Direct
+	/// Allow Administrators 0x001F01FF  Inherited
+	/// Allow SYSTEM         0x001F01FF  Inherited
+	/// 
+ /// the access check would fail because the direct ACE has an access mask + /// of 0x001200A9 which doesn't have the + /// FILE_WRITE_DATA bit on (bit 0x00000002). Actually, this isn't quite correct. If + /// WNET\alice is in the local Administrators group the access check + /// will succeed because the inherited ACE allows local Administrators + /// both FILE_READ_DATA and FILE_WRITE_DATA access. + ///
+ 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 + /// Returns true if this ACE is an allow ACE and false if it is a deny ACE. + /// Returns true if this ACE is an allow ACE and false if it is a deny ACE. + public virtual bool IsAllow() + { + return Allow; + } + + /// Returns true if this ACE is an inherited ACE and false if it is a direct ACE. + /// + /// + /// Returns true if this ACE is an inherited ACE and false if it is a direct ACE. + ///

+ /// Note: For reasons not fully understood, FLAGS_INHERITED 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. + /// + public virtual bool IsInherited() + { + return (Flags & FlagsInherited) != 0; + } + + ///

Returns the flags for this ACE. + /// + /// Returns the flags for this ACE. The isInherited() + /// method checks the FLAGS_INHERITED bit in these flags. + /// + public virtual int GetFlags() + { + return Flags; + } + + /// + /// Returns the 'Apply To' text for inheritance of ACEs on + /// directories such as 'This folder, subfolder and files'. + /// + /// + /// 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'. + /// + 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"; + } + + /// Returns the access mask accociated with this ACE. + /// + /// Returns the access mask accociated with this ACE. Use the + /// constants for FILE_READ_DATA, FILE_WRITE_DATA, + /// READ_CONTROL, GENERIC_ALL, etc with bitwise + /// operators to determine which bits of the mask are on or off. + /// + public virtual int GetAccessMask() + { + return Access; + } + + /// Return the SID associated with this ACE. + /// Return the SID associated with this ACE. + 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(' '); + } + } + + /// Return a string represeting this ACE. + /// + /// Return a string represeting this ACE. + ///

+ /// Note: This function should probably be changed to return SDDL + /// fragments but currently it does not. + /// + 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(); + } + } +} -- cgit v1.2.3