Prechádzať zdrojové kódy

Added a SecurityContext class which will be passes to the underlying object store

Tal Aloni 8 rokov pred
rodič
commit
4842c17f78
27 zmenil súbory, kde vykonal 158 pridanie a 89 odobranie
  1. 1 1
      SMBLibrary/NTFileStore/Adapter/NTFileSystemAdapter.cs
  2. 1 1
      SMBLibrary/NTFileStore/INTFileStore.cs
  3. 2 2
      SMBLibrary/NTFileStore/NTFileStoreHelper.cs
  4. 1 1
      SMBLibrary/NTFileStore/NamedPipeStore.cs
  5. 1 0
      SMBLibrary/SMBLibrary.csproj
  6. 4 4
      SMBLibrary/Server/ConnectionState/SMB1ConnectionState.cs
  7. 12 4
      SMBLibrary/Server/ConnectionState/SMB1Session.cs
  8. 2 2
      SMBLibrary/Server/ConnectionState/SMB2ConnectionState.cs
  9. 12 4
      SMBLibrary/Server/ConnectionState/SMB2Session.cs
  10. 50 0
      SMBLibrary/Server/ConnectionState/SecurityContext.cs
  11. 16 16
      SMBLibrary/Server/SMB1/FileStoreResponseHelper.cs
  12. 2 2
      SMBLibrary/Server/SMB1/NTCreateHelper.cs
  13. 2 2
      SMBLibrary/Server/SMB1/OpenAndXHelper.cs
  14. 4 4
      SMBLibrary/Server/SMB1/ReadWriteResponseHelper.cs
  15. 2 2
      SMBLibrary/Server/SMB1/SMB1FileStoreHelper.Query.cs
  16. 2 2
      SMBLibrary/Server/SMB1/SMB1FileStoreHelper.QueryDirectory.cs
  17. 16 16
      SMBLibrary/Server/SMB1/SMB1FileStoreHelper.cs
  18. 4 4
      SMBLibrary/Server/SMB1/SessionSetupHelper.cs
  19. 5 5
      SMBLibrary/Server/SMB1/Transaction2SubcommandHelper.cs
  20. 1 1
      SMBLibrary/Server/SMB1/TreeConnectHelper.cs
  21. 2 2
      SMBLibrary/Server/SMB2/CreateHelper.cs
  22. 1 1
      SMBLibrary/Server/SMB2/QueryDirectoryHelper.cs
  23. 2 2
      SMBLibrary/Server/SMB2/QueryInfoHelper.cs
  24. 2 2
      SMBLibrary/Server/SMB2/SessionSetupHelper.cs
  25. 1 1
      SMBLibrary/Server/SMB2/SetInfoHelper.cs
  26. 1 1
      SMBLibrary/Server/SMB2/TreeConnectHelper.cs
  27. 9 7
      SMBLibrary/Server/Shares/FileSystemShare.cs

+ 1 - 1
SMBLibrary/NTFileStore/Adapter/NTFileSystemAdapter.cs

@@ -25,7 +25,7 @@ namespace SMBLibrary
             m_fileSystem = fileSystem;
         }
 
-        public NTStatus CreateFile(out object handle, out FileStatus fileStatus, string path, AccessMask desiredAccess, ShareAccess shareAccess, CreateDisposition createDisposition, CreateOptions createOptions)
+        public NTStatus CreateFile(out object handle, out FileStatus fileStatus, string path, AccessMask desiredAccess, ShareAccess shareAccess, CreateDisposition createDisposition, CreateOptions createOptions, SecurityContext securityContext)
         {
             handle = null;
             fileStatus = FileStatus.FILE_DOES_NOT_EXIST;

+ 1 - 1
SMBLibrary/NTFileStore/INTFileStore.cs

@@ -16,7 +16,7 @@ namespace SMBLibrary
     /// </summary>
     public interface INTFileStore
     {
-        NTStatus CreateFile(out object handle, out FileStatus fileStatus, string path, AccessMask desiredAccess, ShareAccess shareAccess, CreateDisposition createDisposition, CreateOptions createOptions);
+        NTStatus CreateFile(out object handle, out FileStatus fileStatus, string path, AccessMask desiredAccess, ShareAccess shareAccess, CreateDisposition createDisposition, CreateOptions createOptions, SecurityContext securityContext);
 
         NTStatus CloseFile(object handle);
 

+ 2 - 2
SMBLibrary/NTFileStore/NTFileStoreHelper.cs

@@ -99,11 +99,11 @@ namespace SMBLibrary
             return result;
         }
 
-        public static FileNetworkOpenInformation GetNetworkOpenInformation(INTFileStore fileStore, string path)
+        public static FileNetworkOpenInformation GetNetworkOpenInformation(INTFileStore fileStore, string path, SecurityContext securityContext)
         {
             object handle;
             FileStatus fileStatus;
-            NTStatus openStatus = fileStore.CreateFile(out handle, out fileStatus, path, FileAccessMask.FILE_READ_ATTRIBUTES, ShareAccess.FILE_SHARE_READ | ShareAccess.FILE_SHARE_WRITE, CreateDisposition.FILE_OPEN, 0);
+            NTStatus openStatus = fileStore.CreateFile(out handle, out fileStatus, path, FileAccessMask.FILE_READ_ATTRIBUTES, ShareAccess.FILE_SHARE_READ | ShareAccess.FILE_SHARE_WRITE, CreateDisposition.FILE_OPEN, 0, securityContext);
             if (openStatus != NTStatus.STATUS_SUCCESS)
             {
                 return null;

+ 1 - 1
SMBLibrary/NTFileStore/NamedPipeStore.cs

@@ -22,7 +22,7 @@ namespace SMBLibrary
             m_services = services;
         }
 
-        public NTStatus CreateFile(out object handle, out FileStatus fileStatus, string path, AccessMask desiredAccess, ShareAccess shareAccess, CreateDisposition createDisposition, CreateOptions createOptions)
+        public NTStatus CreateFile(out object handle, out FileStatus fileStatus, string path, AccessMask desiredAccess, ShareAccess shareAccess, CreateDisposition createDisposition, CreateOptions createOptions, SecurityContext securityContext)
         {
             fileStatus = FileStatus.FILE_DOES_NOT_EXIST;
             // It is possible to have a named pipe that does not use RPC (e.g. MS-WSP),

+ 1 - 0
SMBLibrary/SMBLibrary.csproj

@@ -176,6 +176,7 @@
     <Compile Include="Server\ConnectionState\OpenFileObject.cs" />
     <Compile Include="Server\ConnectionState\OpenSearch.cs" />
     <Compile Include="Server\ConnectionState\ProcessStateObject.cs" />
+    <Compile Include="Server\ConnectionState\SecurityContext.cs" />
     <Compile Include="Server\ConnectionState\SMB1ConnectionState.cs" />
     <Compile Include="Server\ConnectionState\SMB1Session.cs" />
     <Compile Include="Server\ConnectionState\SMB2ConnectionState.cs" />

+ 4 - 4
SMBLibrary/Server/ConnectionState/SMB1ConnectionState.cs

@@ -52,20 +52,20 @@ namespace SMBLibrary.Server
             return null;
         }
 
-        public SMB1Session CreateSession(ushort userID, string userName)
+        public SMB1Session CreateSession(ushort userID, string userName, string machineName)
         {
-            SMB1Session session = new SMB1Session(this, userID, userName);
+            SMB1Session session = new SMB1Session(this, userID, userName, machineName);
             m_sessions.Add(userID, session);
             return session;
         }
 
         /// <returns>null if all UserID values have already been allocated</returns>
-        public SMB1Session CreateSession(string userName)
+        public SMB1Session CreateSession(string userName, string machineName)
         {
             ushort? userID = AllocateUserID();
             if (userID.HasValue)
             {
-                return CreateSession(userID.Value, userName);
+                return CreateSession(userID.Value, userName, machineName);
             }
             return null;
         }

+ 12 - 4
SMBLibrary/Server/ConnectionState/SMB1Session.cs

@@ -17,7 +17,7 @@ namespace SMBLibrary.Server
 
         private SMB1ConnectionState m_connection;
         private ushort m_userID;
-        private string m_userName;
+        private SecurityContext m_securityContext;
 
         // Key is TID
         private Dictionary<ushort, ISMBShare> m_connectedTrees = new Dictionary<ushort, ISMBShare>();
@@ -29,11 +29,11 @@ namespace SMBLibrary.Server
         private Dictionary<ushort, OpenSearch> m_openSearches = new Dictionary<ushort, OpenSearch>();
         private ushort m_nextSearchHandle = 1;
 
-        public SMB1Session(SMB1ConnectionState connection, ushort userID, string userName)
+        public SMB1Session(SMB1ConnectionState connection, ushort userID, string userName, string machineName)
         {
             m_connection = connection;
             m_userID = userID;
-            m_userName = userName;
+            m_securityContext = new SecurityContext(userName, machineName, connection.ClientEndPoint);
         }
 
         public ushort? AddConnectedTree(ISMBShare share)
@@ -141,11 +141,19 @@ namespace SMBLibrary.Server
             }
         }
 
+        public SecurityContext SecurityContext
+        {
+            get
+            {
+                return m_securityContext;
+            }
+        }
+
         public string UserName
         {
             get
             {
-                return m_userName;
+                return m_securityContext.UserName;
             }
         }
     }

+ 2 - 2
SMBLibrary/Server/ConnectionState/SMB2ConnectionState.cs

@@ -44,9 +44,9 @@ namespace SMBLibrary.Server
             return null;
         }
 
-        public SMB2Session CreateSession(ulong sessionID, string userName)
+        public SMB2Session CreateSession(ulong sessionID, string userName, string machineName)
         {
-            SMB2Session session = new SMB2Session(this, sessionID, userName);
+            SMB2Session session = new SMB2Session(this, sessionID, userName, machineName);
             m_sessions.Add(sessionID, session);
             return session;
         }

+ 12 - 4
SMBLibrary/Server/ConnectionState/SMB2Session.cs

@@ -16,7 +16,7 @@ namespace SMBLibrary.Server
     {
         private SMB2ConnectionState m_connection;
         private ulong m_sessionID;
-        private string m_userName;
+        private SecurityContext m_securityContext;
 
         // Key is TreeID
         private Dictionary<uint, ISMBShare> m_connectedTrees = new Dictionary<uint, ISMBShare>();
@@ -28,11 +28,11 @@ namespace SMBLibrary.Server
         // Key is the persistent portion of the FileID
         private Dictionary<ulong, OpenSearch> m_openSearches = new Dictionary<ulong, OpenSearch>();
 
-        public SMB2Session(SMB2ConnectionState connecton, ulong sessionID, string userName)
+        public SMB2Session(SMB2ConnectionState connecton, ulong sessionID, string userName, string machineName)
         {
             m_connection = connecton;
             m_sessionID = sessionID;
-            m_userName = userName;
+            m_securityContext = new SecurityContext(userName, machineName, connecton.ClientEndPoint);
         }
 
         private uint? AllocateTreeID()
@@ -138,11 +138,19 @@ namespace SMBLibrary.Server
             m_openSearches.Remove(fileID);
         }
 
+        public SecurityContext SecurityContext
+        {
+            get
+            {
+                return m_securityContext;
+            }
+        }
+
         public string UserName
         {
             get
             {
-                return m_userName;
+                return m_securityContext.UserName;
             }
         }
     }

+ 50 - 0
SMBLibrary/Server/ConnectionState/SecurityContext.cs

@@ -0,0 +1,50 @@
+/* Copyright (C) 2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
+ * 
+ * You can redistribute this program and/or modify it under the terms of
+ * the GNU Lesser Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ */
+using System;
+using System.Collections.Generic;
+using System.Net;
+
+namespace SMBLibrary
+{
+    public class SecurityContext
+    {
+        private string m_userName;
+        private string m_machineName;
+        private IPEndPoint m_clientEndPoint;
+
+        public SecurityContext(string userName, string machineName, IPEndPoint clientEndPoint)
+        {
+            m_userName = userName;
+            m_machineName = machineName;
+            m_clientEndPoint = clientEndPoint;
+        }
+
+        public string UserName
+        {
+            get
+            {
+                return m_userName;
+            }
+        }
+
+        public string MachineName
+        {
+            get
+            {
+                return m_machineName;
+            }
+        }
+
+        public IPEndPoint ClientEndPoint
+        {
+            get
+            {
+                return m_clientEndPoint;
+            }
+        }
+    }
+}

+ 16 - 16
SMBLibrary/Server/SMB1/FileStoreResponseHelper.cs

@@ -20,14 +20,14 @@ namespace SMBLibrary.Server.SMB1
             SMB1Session session = state.GetSession(header.UID);
             if (share is FileSystemShare)
             {
-                if (!((FileSystemShare)share).HasWriteAccess(session.UserName, request.DirectoryName, state.ClientEndPoint))
+                if (!((FileSystemShare)share).HasWriteAccess(session.SecurityContext, request.DirectoryName))
                 {
                     header.Status = NTStatus.STATUS_ACCESS_DENIED;
                     return new ErrorResponse(request.CommandName);
                 }
             }
 
-            header.Status = SMB1FileStoreHelper.CreateDirectory(share.FileStore, request.DirectoryName);
+            header.Status = SMB1FileStoreHelper.CreateDirectory(share.FileStore, request.DirectoryName, session.SecurityContext);
             if (header.Status != NTStatus.STATUS_SUCCESS)
             {
                 return new ErrorResponse(request.CommandName);
@@ -41,14 +41,14 @@ namespace SMBLibrary.Server.SMB1
             SMB1Session session = state.GetSession(header.UID);
             if (share is FileSystemShare)
             {
-                if (!((FileSystemShare)share).HasWriteAccess(session.UserName, request.DirectoryName, state.ClientEndPoint))
+                if (!((FileSystemShare)share).HasWriteAccess(session.SecurityContext, request.DirectoryName))
                 {
                     header.Status = NTStatus.STATUS_ACCESS_DENIED;
                     return new ErrorResponse(request.CommandName);
                 }
             }
 
-            header.Status = SMB1FileStoreHelper.DeleteDirectory(share.FileStore, request.DirectoryName);
+            header.Status = SMB1FileStoreHelper.DeleteDirectory(share.FileStore, request.DirectoryName, session.SecurityContext);
             if (header.Status != NTStatus.STATUS_SUCCESS)
             {
                 return new ErrorResponse(request.CommandName);
@@ -61,7 +61,7 @@ namespace SMBLibrary.Server.SMB1
             SMB1Session session = state.GetSession(header.UID);
             if (share is FileSystemShare)
             {
-                if (!((FileSystemShare)share).HasWriteAccess(session.UserName, request.FileName, state.ClientEndPoint))
+                if (!((FileSystemShare)share).HasWriteAccess(session.SecurityContext, request.FileName))
                 {
                     header.Status = NTStatus.STATUS_ACCESS_DENIED;
                     return new ErrorResponse(request.CommandName);
@@ -69,7 +69,7 @@ namespace SMBLibrary.Server.SMB1
             }
 
             // [MS-CIFS] This command cannot delete directories or volumes.
-            header.Status = SMB1FileStoreHelper.DeleteFile(share.FileStore, request.FileName);
+            header.Status = SMB1FileStoreHelper.DeleteFile(share.FileStore, request.FileName, session.SecurityContext);
             if (header.Status != NTStatus.STATUS_SUCCESS)
             {
                 return new ErrorResponse(request.CommandName);
@@ -82,19 +82,19 @@ namespace SMBLibrary.Server.SMB1
             SMB1Session session = state.GetSession(header.UID);
             if (share is FileSystemShare)
             {
-                if (!((FileSystemShare)share).HasWriteAccess(session.UserName, request.OldFileName, state.ClientEndPoint))
+                if (!((FileSystemShare)share).HasWriteAccess(session.SecurityContext, request.OldFileName))
                 {
                     header.Status = NTStatus.STATUS_ACCESS_DENIED;
                     return new ErrorResponse(request.CommandName);
                 }
-                if (!((FileSystemShare)share).HasWriteAccess(session.UserName, request.NewFileName, state.ClientEndPoint))
+                if (!((FileSystemShare)share).HasWriteAccess(session.SecurityContext, request.NewFileName))
                 {
                     header.Status = NTStatus.STATUS_ACCESS_DENIED;
                     return new ErrorResponse(request.CommandName);
                 }
             }
 
-            header.Status = SMB1FileStoreHelper.Rename(share.FileStore, request.OldFileName, request.NewFileName, request.SearchAttributes);
+            header.Status = SMB1FileStoreHelper.Rename(share.FileStore, request.OldFileName, request.NewFileName, request.SearchAttributes, session.SecurityContext);
             if (header.Status != NTStatus.STATUS_SUCCESS)
             {
                 return new ErrorResponse(request.CommandName);
@@ -107,14 +107,14 @@ namespace SMBLibrary.Server.SMB1
             SMB1Session session = state.GetSession(header.UID);
             if (share is FileSystemShare)
             {
-                if (!((FileSystemShare)share).HasReadAccess(session.UserName, request.DirectoryName, state.ClientEndPoint))
+                if (!((FileSystemShare)share).HasReadAccess(session.SecurityContext, request.DirectoryName))
                 {
                     header.Status = NTStatus.STATUS_ACCESS_DENIED;
                     return new ErrorResponse(request.CommandName);
                 }
             }
 
-            header.Status = SMB1FileStoreHelper.CheckDirectory(share.FileStore, request.DirectoryName);
+            header.Status = SMB1FileStoreHelper.CheckDirectory(share.FileStore, request.DirectoryName, session.SecurityContext);
             if (header.Status != NTStatus.STATUS_SUCCESS)
             {
                 return new ErrorResponse(request.CommandName);
@@ -128,7 +128,7 @@ namespace SMBLibrary.Server.SMB1
             SMB1Session session = state.GetSession(header.UID);
             if (share is FileSystemShare)
             {
-                if (!((FileSystemShare)share).HasReadAccess(session.UserName, request.FileName, state.ClientEndPoint))
+                if (!((FileSystemShare)share).HasReadAccess(session.SecurityContext, request.FileName))
                 {
                     header.Status = NTStatus.STATUS_ACCESS_DENIED;
                     return new ErrorResponse(request.CommandName);
@@ -136,7 +136,7 @@ namespace SMBLibrary.Server.SMB1
             }
 
             FileNetworkOpenInformation fileInfo;
-            header.Status = SMB1FileStoreHelper.QueryInformation(out fileInfo, share.FileStore, request.FileName);
+            header.Status = SMB1FileStoreHelper.QueryInformation(out fileInfo, share.FileStore, request.FileName, session.SecurityContext);
             if (header.Status != NTStatus.STATUS_SUCCESS)
             {
                 return new ErrorResponse(request.CommandName);
@@ -154,14 +154,14 @@ namespace SMBLibrary.Server.SMB1
             SMB1Session session = state.GetSession(header.UID);
             if (share is FileSystemShare)
             {
-                if (!((FileSystemShare)share).HasWriteAccess(session.UserName, request.FileName, state.ClientEndPoint))
+                if (!((FileSystemShare)share).HasWriteAccess(session.SecurityContext, request.FileName))
                 {
                     header.Status = NTStatus.STATUS_ACCESS_DENIED;
                     return new ErrorResponse(request.CommandName);
                 }
             }
 
-            header.Status = SMB1FileStoreHelper.SetInformation(share.FileStore, request.FileName, request.FileAttributes, request.LastWriteTime);
+            header.Status = SMB1FileStoreHelper.SetInformation(share.FileStore, request.FileName, request.FileAttributes, request.LastWriteTime, session.SecurityContext);
             if (header.Status != NTStatus.STATUS_SUCCESS)
             {
                 return new ErrorResponse(request.CommandName);
@@ -182,7 +182,7 @@ namespace SMBLibrary.Server.SMB1
 
             if (share is FileSystemShare)
             {
-                if (!((FileSystemShare)share).HasWriteAccess(session.UserName, openFile.Path, state.ClientEndPoint))
+                if (!((FileSystemShare)share).HasWriteAccess(session.SecurityContext, openFile.Path))
                 {
                     header.Status = NTStatus.STATUS_ACCESS_DENIED;
                     return new ErrorResponse(request.CommandName);

+ 2 - 2
SMBLibrary/Server/SMB1/NTCreateHelper.cs

@@ -24,7 +24,7 @@ namespace SMBLibrary.Server.SMB1
             FileAccess createAccess = NTFileStoreHelper.ToCreateFileAccess(request.DesiredAccess, request.CreateDisposition);
             if (share is FileSystemShare)
             {
-                if (!((FileSystemShare)share).HasAccess(session.UserName, path, createAccess, state.ClientEndPoint))
+                if (!((FileSystemShare)share).HasAccess(session.SecurityContext, path, createAccess))
                 {
                     header.Status = NTStatus.STATUS_ACCESS_DENIED;
                     return new ErrorResponse(request.CommandName);
@@ -33,7 +33,7 @@ namespace SMBLibrary.Server.SMB1
 
             object handle;
             FileStatus fileStatus;
-            NTStatus createStatus = share.FileStore.CreateFile(out handle, out fileStatus, path, request.DesiredAccess, request.ShareAccess, request.CreateDisposition, request.CreateOptions);
+            NTStatus createStatus = share.FileStore.CreateFile(out handle, out fileStatus, path, request.DesiredAccess, request.ShareAccess, request.CreateDisposition, request.CreateOptions, session.SecurityContext);
             if (createStatus != NTStatus.STATUS_SUCCESS)
             {
                 header.Status = createStatus;

+ 2 - 2
SMBLibrary/Server/SMB1/OpenAndXHelper.cs

@@ -41,7 +41,7 @@ namespace SMBLibrary.Server.SMB1
             FileAccess fileAccess = ToFileAccess(request.AccessMode.AccessMode);
             if (share is FileSystemShare)
             {
-                if (!((FileSystemShare)share).HasAccess(session.UserName, path, fileAccess, state.ClientEndPoint))
+                if (!((FileSystemShare)share).HasAccess(session.SecurityContext, path, fileAccess))
                 {
                     header.Status = NTStatus.STATUS_ACCESS_DENIED;
                     return new ErrorResponse(request.CommandName);
@@ -50,7 +50,7 @@ namespace SMBLibrary.Server.SMB1
 
             object handle;
             FileStatus fileStatus;
-            header.Status = share.FileStore.CreateFile(out handle, out fileStatus, path, desiredAccess, shareAccess, createDisposition, createOptions);
+            header.Status = share.FileStore.CreateFile(out handle, out fileStatus, path, desiredAccess, shareAccess, createDisposition, createOptions, session.SecurityContext);
             if (header.Status != NTStatus.STATUS_SUCCESS)
             {
                 return new ErrorResponse(request.CommandName);

+ 4 - 4
SMBLibrary/Server/SMB1/ReadWriteResponseHelper.cs

@@ -29,7 +29,7 @@ namespace SMBLibrary.Server.SMB1
 
             if (share is FileSystemShare)
             {
-                if (!((FileSystemShare)share).HasReadAccess(session.UserName, openFile.Path, state.ClientEndPoint))
+                if (!((FileSystemShare)share).HasReadAccess(session.SecurityContext, openFile.Path))
                 {
                     header.Status = NTStatus.STATUS_ACCESS_DENIED;
                     return new ErrorResponse(request.CommandName);
@@ -61,7 +61,7 @@ namespace SMBLibrary.Server.SMB1
 
             if (share is FileSystemShare)
             {
-                if (!((FileSystemShare)share).HasReadAccess(session.UserName, openFile.Path, state.ClientEndPoint))
+                if (!((FileSystemShare)share).HasReadAccess(session.SecurityContext, openFile.Path))
                 {
                     header.Status = NTStatus.STATUS_ACCESS_DENIED;
                     return new ErrorResponse(request.CommandName);
@@ -102,7 +102,7 @@ namespace SMBLibrary.Server.SMB1
 
             if (share is FileSystemShare)
             {
-                if (!((FileSystemShare)share).HasWriteAccess(session.UserName, openFile.Path, state.ClientEndPoint))
+                if (!((FileSystemShare)share).HasWriteAccess(session.SecurityContext, openFile.Path))
                 {
                     header.Status = NTStatus.STATUS_ACCESS_DENIED;
                     return new ErrorResponse(request.CommandName);
@@ -132,7 +132,7 @@ namespace SMBLibrary.Server.SMB1
 
             if (share is FileSystemShare)
             {
-                if (!((FileSystemShare)share).HasWriteAccess(session.UserName, openFile.Path, state.ClientEndPoint))
+                if (!((FileSystemShare)share).HasWriteAccess(session.SecurityContext, openFile.Path))
                 {
                     header.Status = NTStatus.STATUS_ACCESS_DENIED;
                     return new ErrorResponse(request.CommandName);

+ 2 - 2
SMBLibrary/Server/SMB1/SMB1FileStoreHelper.Query.cs

@@ -14,11 +14,11 @@ namespace SMBLibrary.Server.SMB1
 {
     public partial class SMB1FileStoreHelper
     {
-        public static NTStatus GetFileInformation(out QueryInformation result, INTFileStore fileStore, string path, QueryInformationLevel informationLevel)
+        public static NTStatus GetFileInformation(out QueryInformation result, INTFileStore fileStore, string path, QueryInformationLevel informationLevel, SecurityContext securityContext)
         {
             object handle;
             FileStatus fileStatus;
-            NTStatus openStatus = fileStore.CreateFile(out handle, out fileStatus, path, FileAccessMask.FILE_READ_ATTRIBUTES, ShareAccess.FILE_SHARE_READ | ShareAccess.FILE_SHARE_WRITE, CreateDisposition.FILE_OPEN, 0);
+            NTStatus openStatus = fileStore.CreateFile(out handle, out fileStatus, path, FileAccessMask.FILE_READ_ATTRIBUTES, ShareAccess.FILE_SHARE_READ | ShareAccess.FILE_SHARE_WRITE, CreateDisposition.FILE_OPEN, 0, securityContext);
             if (openStatus != NTStatus.STATUS_SUCCESS)
             {
                 result = null;

+ 2 - 2
SMBLibrary/Server/SMB1/SMB1FileStoreHelper.QueryDirectory.cs

@@ -22,7 +22,7 @@ namespace SMBLibrary.Server.SMB1
         // '\Directory\exefile"*' (cmd.exe will use this syntax when entering an exe without its extension, explorer will use this opening a directory from the run menu)
         /// <param name="fileNamePattern">The filename pattern to search for. This field MAY contain wildcard characters</param>
         /// <exception cref="System.UnauthorizedAccessException"></exception>
-        public static NTStatus QueryDirectory(out List<QueryDirectoryFileInformation> result, INTFileStore fileStore, string fileNamePattern, FileInformationClass fileInformation)
+        public static NTStatus QueryDirectory(out List<QueryDirectoryFileInformation> result, INTFileStore fileStore, string fileNamePattern, FileInformationClass fileInformation, SecurityContext securityContext)
         {
             int separatorIndex = fileNamePattern.LastIndexOf('\\');
             if (separatorIndex >= 0)
@@ -31,7 +31,7 @@ namespace SMBLibrary.Server.SMB1
                 string fileName = fileNamePattern.Substring(separatorIndex + 1);
                 object handle;
                 FileStatus fileStatus;
-                NTStatus createStatus = fileStore.CreateFile(out handle, out fileStatus, path, DirectoryAccessMask.FILE_LIST_DIRECTORY | DirectoryAccessMask.FILE_TRAVERSE, ShareAccess.FILE_SHARE_READ | ShareAccess.FILE_SHARE_WRITE, CreateDisposition.FILE_OPEN, CreateOptions.FILE_DIRECTORY_FILE);
+                NTStatus createStatus = fileStore.CreateFile(out handle, out fileStatus, path, DirectoryAccessMask.FILE_LIST_DIRECTORY | DirectoryAccessMask.FILE_TRAVERSE, ShareAccess.FILE_SHARE_READ | ShareAccess.FILE_SHARE_WRITE, CreateDisposition.FILE_OPEN, CreateOptions.FILE_DIRECTORY_FILE, securityContext);
                 if (createStatus != NTStatus.STATUS_SUCCESS)
                 {
                     result = null;

+ 16 - 16
SMBLibrary/Server/SMB1/SMB1FileStoreHelper.cs

@@ -14,11 +14,11 @@ namespace SMBLibrary.Server.SMB1
 {
     public partial class SMB1FileStoreHelper
     {
-        public static NTStatus CreateDirectory(INTFileStore fileStore, string path)
+        public static NTStatus CreateDirectory(INTFileStore fileStore, string path, SecurityContext securityContext)
         {
             object handle;
             FileStatus fileStatus;
-            NTStatus createStatus = fileStore.CreateFile(out handle, out fileStatus, path, DirectoryAccessMask.FILE_ADD_SUBDIRECTORY, ShareAccess.FILE_SHARE_READ | ShareAccess.FILE_SHARE_WRITE, CreateDisposition.FILE_CREATE, CreateOptions.FILE_DIRECTORY_FILE);
+            NTStatus createStatus = fileStore.CreateFile(out handle, out fileStatus, path, DirectoryAccessMask.FILE_ADD_SUBDIRECTORY, ShareAccess.FILE_SHARE_READ | ShareAccess.FILE_SHARE_WRITE, CreateDisposition.FILE_CREATE, CreateOptions.FILE_DIRECTORY_FILE, securityContext);
             if (createStatus != NTStatus.STATUS_SUCCESS)
             {
                 return createStatus;
@@ -27,21 +27,21 @@ namespace SMBLibrary.Server.SMB1
             return createStatus;
         }
 
-        public static NTStatus DeleteDirectory(INTFileStore fileStore, string path)
+        public static NTStatus DeleteDirectory(INTFileStore fileStore, string path, SecurityContext securityContext)
         {
-            return Delete(fileStore, path, CreateOptions.FILE_DIRECTORY_FILE);
+            return Delete(fileStore, path, CreateOptions.FILE_DIRECTORY_FILE, securityContext);
         }
 
-        public static NTStatus DeleteFile(INTFileStore fileStore, string path)
+        public static NTStatus DeleteFile(INTFileStore fileStore, string path, SecurityContext securityContext)
         {
-            return Delete(fileStore, path, CreateOptions.FILE_NON_DIRECTORY_FILE);
+            return Delete(fileStore, path, CreateOptions.FILE_NON_DIRECTORY_FILE, securityContext);
         }
 
-        public static NTStatus Delete(INTFileStore fileStore, string path, CreateOptions createOptions)
+        public static NTStatus Delete(INTFileStore fileStore, string path, CreateOptions createOptions, SecurityContext securityContext)
         {
             object handle;
             FileStatus fileStatus;
-            NTStatus openStatus = fileStore.CreateFile(out handle, out fileStatus, path, DirectoryAccessMask.DELETE, 0, CreateDisposition.FILE_OPEN, createOptions);
+            NTStatus openStatus = fileStore.CreateFile(out handle, out fileStatus, path, DirectoryAccessMask.DELETE, 0, CreateDisposition.FILE_OPEN, createOptions, securityContext);
             if (openStatus != NTStatus.STATUS_SUCCESS)
             {
                 return openStatus;
@@ -57,7 +57,7 @@ namespace SMBLibrary.Server.SMB1
             return closeStatus;
         }
 
-        public static NTStatus Rename(INTFileStore fileStore, string oldName, string newName, SMBFileAttributes searchAttributes)
+        public static NTStatus Rename(INTFileStore fileStore, string oldName, string newName, SMBFileAttributes searchAttributes, SecurityContext securityContext)
         {
             object handle;
             FileStatus fileStatus;
@@ -70,7 +70,7 @@ namespace SMBLibrary.Server.SMB1
             {
                 createOptions = CreateOptions.FILE_DIRECTORY_FILE;
             }
-            NTStatus openStatus = fileStore.CreateFile(out handle, out fileStatus, oldName, DirectoryAccessMask.DELETE, 0, CreateDisposition.FILE_OPEN, createOptions);
+            NTStatus openStatus = fileStore.CreateFile(out handle, out fileStatus, oldName, DirectoryAccessMask.DELETE, 0, CreateDisposition.FILE_OPEN, createOptions, securityContext);
             if (openStatus != NTStatus.STATUS_SUCCESS)
             {
                 return openStatus;
@@ -87,11 +87,11 @@ namespace SMBLibrary.Server.SMB1
             return closeStatus;
         }
 
-        public static NTStatus CheckDirectory(INTFileStore fileStore, string path)
+        public static NTStatus CheckDirectory(INTFileStore fileStore, string path, SecurityContext securityContext)
         {
             object handle;
             FileStatus fileStatus;
-            NTStatus openStatus = fileStore.CreateFile(out handle, out fileStatus, path, (AccessMask)0, ShareAccess.FILE_SHARE_READ | ShareAccess.FILE_SHARE_WRITE, CreateDisposition.FILE_OPEN, CreateOptions.FILE_DIRECTORY_FILE);
+            NTStatus openStatus = fileStore.CreateFile(out handle, out fileStatus, path, (AccessMask)0, ShareAccess.FILE_SHARE_READ | ShareAccess.FILE_SHARE_WRITE, CreateDisposition.FILE_OPEN, CreateOptions.FILE_DIRECTORY_FILE, securityContext);
             if (openStatus != NTStatus.STATUS_SUCCESS)
             {
                 return openStatus;
@@ -101,11 +101,11 @@ namespace SMBLibrary.Server.SMB1
             return NTStatus.STATUS_SUCCESS;
         }
 
-        public static NTStatus QueryInformation(out FileNetworkOpenInformation fileInfo, INTFileStore fileStore, string path)
+        public static NTStatus QueryInformation(out FileNetworkOpenInformation fileInfo, INTFileStore fileStore, string path, SecurityContext securityContext)
         {
             object handle;
             FileStatus fileStatus;
-            NTStatus openStatus = fileStore.CreateFile(out handle, out fileStatus, path, FileAccessMask.FILE_READ_ATTRIBUTES, ShareAccess.FILE_SHARE_READ | ShareAccess.FILE_SHARE_WRITE, CreateDisposition.FILE_OPEN, 0);
+            NTStatus openStatus = fileStore.CreateFile(out handle, out fileStatus, path, FileAccessMask.FILE_READ_ATTRIBUTES, ShareAccess.FILE_SHARE_READ | ShareAccess.FILE_SHARE_WRITE, CreateDisposition.FILE_OPEN, 0, securityContext);
             if (openStatus != NTStatus.STATUS_SUCCESS)
             {
                 fileInfo = null;
@@ -116,11 +116,11 @@ namespace SMBLibrary.Server.SMB1
             return NTStatus.STATUS_SUCCESS;
         }
 
-        public static NTStatus SetInformation(INTFileStore fileStore, string path, SMBFileAttributes fileAttributes, DateTime? lastWriteTime)
+        public static NTStatus SetInformation(INTFileStore fileStore, string path, SMBFileAttributes fileAttributes, DateTime? lastWriteTime, SecurityContext securityContext)
         {
             object handle;
             FileStatus fileStatus;
-            NTStatus openStatus = fileStore.CreateFile(out handle, out fileStatus, path, FileAccessMask.FILE_WRITE_ATTRIBUTES, ShareAccess.FILE_SHARE_READ | ShareAccess.FILE_SHARE_WRITE, CreateDisposition.FILE_OPEN, 0);
+            NTStatus openStatus = fileStore.CreateFile(out handle, out fileStatus, path, FileAccessMask.FILE_WRITE_ATTRIBUTES, ShareAccess.FILE_SHARE_READ | ShareAccess.FILE_SHARE_WRITE, CreateDisposition.FILE_OPEN, 0, securityContext);
             if (openStatus != NTStatus.STATUS_SUCCESS)
             {
                 return openStatus;

+ 4 - 4
SMBLibrary/Server/SMB1/SessionSetupHelper.cs

@@ -40,7 +40,7 @@ namespace SMBLibrary.Server.SMB1
             if (loginSuccess)
             {
                 state.LogToServer(Severity.Information, "User '{0}' authenticated successfully", message.UserName);
-                SMB1Session session = state.CreateSession(message.UserName);
+                SMB1Session session = state.CreateSession(message.UserName, message.WorkStation);
                 if (session == null)
                 {
                     header.Status = NTStatus.STATUS_TOO_MANY_SESSIONS;
@@ -52,7 +52,7 @@ namespace SMBLibrary.Server.SMB1
             else if (users.FallbackToGuest(message.UserName))
             {
                 state.LogToServer(Severity.Information, "User '{0}' failed authentication. logged in as guest", message.UserName);
-                SMB1Session session = state.CreateSession("Guest");
+                SMB1Session session = state.CreateSession("Guest", message.WorkStation);
                 if (session == null)
                 {
                     header.Status = NTStatus.STATUS_TOO_MANY_SESSIONS;
@@ -145,12 +145,12 @@ namespace SMBLibrary.Server.SMB1
                 if (loginSuccess)
                 {
                     state.LogToServer(Severity.Information, "User '{0}' authenticated successfully", authenticateMessage.UserName);
-                    state.CreateSession(header.UID, authenticateMessage.UserName);
+                    state.CreateSession(header.UID, authenticateMessage.UserName, authenticateMessage.WorkStation);
                 }
                 else if (users.FallbackToGuest(authenticateMessage.UserName))
                 {
                     state.LogToServer(Severity.Information, "User '{0}' failed authentication. logged in as guest", authenticateMessage.UserName);
-                    state.CreateSession(header.UID, "Guest");
+                    state.CreateSession(header.UID, "Guest", authenticateMessage.WorkStation);
                     response.Action = SessionSetupAction.SetupGuest;
                 }
                 else

+ 5 - 5
SMBLibrary/Server/SMB1/Transaction2SubcommandHelper.cs

@@ -32,7 +32,7 @@ namespace SMBLibrary.Server.SMB1
                 return null;
             }
 
-            NTStatus searchStatus = SMB1FileStoreHelper.QueryDirectory(out entries, share.FileStore, fileNamePattern, informationClass);
+            NTStatus searchStatus = SMB1FileStoreHelper.QueryDirectory(out entries, share.FileStore, fileNamePattern, informationClass, session.SecurityContext);
             if (searchStatus != NTStatus.STATUS_SUCCESS)
             {
                 state.LogToServer(Severity.Verbose, "FindFirst2: Searched for '{0}', NTStatus: {1}", fileNamePattern, searchStatus.ToString());
@@ -120,7 +120,7 @@ namespace SMBLibrary.Server.SMB1
             SMB1Session session = state.GetSession(header.UID);
             if (share is FileSystemShare)
             {
-                if (!((FileSystemShare)share).HasReadAccess(session.UserName, @"\", state.ClientEndPoint))
+                if (!((FileSystemShare)share).HasReadAccess(session.SecurityContext, @"\"))
                 {
                     header.Status = NTStatus.STATUS_ACCESS_DENIED;
                     return null;
@@ -146,7 +146,7 @@ namespace SMBLibrary.Server.SMB1
             string path = subcommand.FileName;
             if (share is FileSystemShare)
             {
-                if (!((FileSystemShare)share).HasReadAccess(session.UserName, path, state.ClientEndPoint))
+                if (!((FileSystemShare)share).HasReadAccess(session.SecurityContext, path))
                 {
                     header.Status = NTStatus.STATUS_ACCESS_DENIED;
                     return null;
@@ -178,7 +178,7 @@ namespace SMBLibrary.Server.SMB1
 
             if (share is FileSystemShare)
             {
-                if (!((FileSystemShare)share).HasReadAccess(session.UserName, openFile.Path, state.ClientEndPoint))
+                if (!((FileSystemShare)share).HasReadAccess(session.SecurityContext, openFile.Path))
                 {
                     header.Status = NTStatus.STATUS_ACCESS_DENIED;
                     return null;
@@ -210,7 +210,7 @@ namespace SMBLibrary.Server.SMB1
 
             if (share is FileSystemShare)
             {
-                if (!((FileSystemShare)share).HasWriteAccess(session.UserName, openFile.Path, state.ClientEndPoint))
+                if (!((FileSystemShare)share).HasWriteAccess(session.SecurityContext, openFile.Path))
                 {
                     header.Status = NTStatus.STATUS_ACCESS_DENIED;
                     return null;

+ 1 - 1
SMBLibrary/Server/SMB1/TreeConnectHelper.cs

@@ -36,7 +36,7 @@ namespace SMBLibrary.Server.SMB1
                     return new ErrorResponse(request.CommandName);
                 }
 
-                if (!((FileSystemShare)share).HasReadAccess(session.UserName, @"\", state.ClientEndPoint))
+                if (!((FileSystemShare)share).HasReadAccess(session.SecurityContext, @"\"))
                 {
                     header.Status = NTStatus.STATUS_ACCESS_DENIED;
                     return new ErrorResponse(request.CommandName);

+ 2 - 2
SMBLibrary/Server/SMB2/CreateHelper.cs

@@ -26,7 +26,7 @@ namespace SMBLibrary.Server.SMB2
             FileAccess createAccess = NTFileStoreHelper.ToCreateFileAccess(request.DesiredAccess, request.CreateDisposition);
             if (share is FileSystemShare)
             {
-                if (!((FileSystemShare)share).HasAccess(session.UserName, path, createAccess, state.ClientEndPoint))
+                if (!((FileSystemShare)share).HasAccess(session.SecurityContext, path, createAccess))
                 {
                     return new ErrorResponse(request.CommandName, NTStatus.STATUS_ACCESS_DENIED);
                 }
@@ -34,7 +34,7 @@ namespace SMBLibrary.Server.SMB2
 
             object handle;
             FileStatus fileStatus;
-            NTStatus createStatus = share.FileStore.CreateFile(out handle, out fileStatus, path, request.DesiredAccess, request.ShareAccess, request.CreateDisposition, request.CreateOptions);
+            NTStatus createStatus = share.FileStore.CreateFile(out handle, out fileStatus, path, request.DesiredAccess, request.ShareAccess, request.CreateDisposition, request.CreateOptions, session.SecurityContext);
             if (createStatus != NTStatus.STATUS_SUCCESS)
             {
                 return new ErrorResponse(request.CommandName, createStatus);

+ 1 - 1
SMBLibrary/Server/SMB2/QueryDirectoryHelper.cs

@@ -23,7 +23,7 @@ namespace SMBLibrary.Server.SMB2
                 return new ErrorResponse(request.CommandName, NTStatus.STATUS_FILE_CLOSED);
             }
 
-            if (!((FileSystemShare)share).HasReadAccess(session.UserName, openFile.Path, state.ClientEndPoint))
+            if (!((FileSystemShare)share).HasReadAccess(session.SecurityContext, openFile.Path))
             {
                 return new ErrorResponse(request.CommandName, NTStatus.STATUS_ACCESS_DENIED);
             }

+ 2 - 2
SMBLibrary/Server/SMB2/QueryInfoHelper.cs

@@ -27,7 +27,7 @@ namespace SMBLibrary.Server.SMB2
 
                 if (share is FileSystemShare)
                 {
-                    if (!((FileSystemShare)share).HasReadAccess(session.UserName, openFile.Path, state.ClientEndPoint))
+                    if (!((FileSystemShare)share).HasReadAccess(session.SecurityContext, openFile.Path))
                     {
                         return new ErrorResponse(request.CommandName, NTStatus.STATUS_ACCESS_DENIED);
                     }
@@ -49,7 +49,7 @@ namespace SMBLibrary.Server.SMB2
             {
                 if (share is FileSystemShare)
                 {
-                    if (!((FileSystemShare)share).HasReadAccess(session.UserName, @"\", state.ClientEndPoint))
+                    if (!((FileSystemShare)share).HasReadAccess(session.SecurityContext, @"\"))
                     {
                         return new ErrorResponse(request.CommandName, NTStatus.STATUS_ACCESS_DENIED);
                     }

+ 2 - 2
SMBLibrary/Server/SMB2/SessionSetupHelper.cs

@@ -76,12 +76,12 @@ namespace SMBLibrary.Server.SMB2
                 if (loginSuccess)
                 {
                     state.LogToServer(Severity.Information, "User '{0}' authenticated successfully", authenticateMessage.UserName);
-                    state.CreateSession(request.Header.SessionID, authenticateMessage.UserName);
+                    state.CreateSession(request.Header.SessionID, authenticateMessage.UserName, authenticateMessage.WorkStation);
                 }
                 else if (users.FallbackToGuest(authenticateMessage.UserName))
                 {
                     state.LogToServer(Severity.Information, "User '{0}' failed authentication. logged in as guest", authenticateMessage.UserName);
-                    state.CreateSession(request.Header.SessionID, "Guest");
+                    state.CreateSession(request.Header.SessionID, "Guest", authenticateMessage.WorkStation);
                     response.SessionFlags = SessionFlags.IsGuest;
                 }
                 else

+ 1 - 1
SMBLibrary/Server/SMB2/SetInfoHelper.cs

@@ -27,7 +27,7 @@ namespace SMBLibrary.Server.SMB2
 
                 if (share is FileSystemShare)
                 {
-                    if (!((FileSystemShare)share).HasWriteAccess(session.UserName, openFile.Path, state.ClientEndPoint))
+                    if (!((FileSystemShare)share).HasWriteAccess(session.SecurityContext, openFile.Path))
                     {
                         return new ErrorResponse(request.CommandName, NTStatus.STATUS_ACCESS_DENIED);
                     }

+ 1 - 1
SMBLibrary/Server/SMB2/TreeConnectHelper.cs

@@ -37,7 +37,7 @@ namespace SMBLibrary.Server.SMB2
                     return new ErrorResponse(request.CommandName, NTStatus.STATUS_OBJECT_PATH_NOT_FOUND);
                 }
 
-                if (!((FileSystemShare)share).HasReadAccess(session.UserName, @"\", state.ClientEndPoint))
+                if (!((FileSystemShare)share).HasReadAccess(session.SecurityContext, @"\"))
                 {
                     return new ErrorResponse(request.CommandName, NTStatus.STATUS_ACCESS_DENIED);
                 }

+ 9 - 7
SMBLibrary/Server/Shares/FileSystemShare.cs

@@ -18,14 +18,16 @@ namespace SMBLibrary.Server
         public string UserName;
         public string Path;
         public FileAccess RequestedAccess;
+        public string MachineName;
         public IPEndPoint ClientEndPoint;
         public bool Allow = true;
 
-        public AccessRequestArgs(string userName, string path, FileAccess requestedAccess, IPEndPoint clientEndPoint)
+        public AccessRequestArgs(string userName, string path, FileAccess requestedAccess, string machineName, IPEndPoint clientEndPoint)
         {
             UserName = userName;
             Path = path;
             RequestedAccess = requestedAccess;
+            MachineName = machineName;
             ClientEndPoint = clientEndPoint;
         }
     }
@@ -49,23 +51,23 @@ namespace SMBLibrary.Server
             m_fileSystem = new NTFileSystemAdapter(fileSystem);
         }
 
-        public bool HasReadAccess(string userName, string path, IPEndPoint clientEndPoint)
+        public bool HasReadAccess(SecurityContext securityContext, string path)
         {
-            return HasAccess(userName, path, FileAccess.Read, clientEndPoint);
+            return HasAccess(securityContext, path, FileAccess.Read);
         }
 
-        public bool HasWriteAccess(string userName, string path, IPEndPoint clientEndPoint)
+        public bool HasWriteAccess(SecurityContext securityContext, string path)
         {
-            return HasAccess(userName, path, FileAccess.Write, clientEndPoint);
+            return HasAccess(securityContext, path, FileAccess.Write);
         }
 
-        public bool HasAccess(string userName, string path, FileAccess requestedAccess, IPEndPoint clientEndPoint)
+        public bool HasAccess(SecurityContext securityContext, string path, FileAccess requestedAccess)
         {
             // To be thread-safe we must capture the delegate reference first
             EventHandler<AccessRequestArgs> handler = OnAccessRequest;
             if (handler != null)
             {
-                AccessRequestArgs args = new AccessRequestArgs(userName, path, requestedAccess, clientEndPoint);
+                AccessRequestArgs args = new AccessRequestArgs(securityContext.UserName, path, requestedAccess, securityContext.MachineName, securityContext.ClientEndPoint);
                 handler(this, args);
                 return args.Allow;
             }