diff --git a/SMBLibrary/NTFileStore/Adapter/NTFileSystemAdapter.cs b/SMBLibrary/NTFileStore/Adapter/NTFileSystemAdapter.cs index 4488558..1307379 100644 --- a/SMBLibrary/NTFileStore/Adapter/NTFileSystemAdapter.cs +++ b/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, SecurityContext securityContext) + public NTStatus CreateFile(out object handle, out FileStatus fileStatus, string path, AccessMask desiredAccess, FileAttributes fileAttributes, ShareAccess shareAccess, CreateDisposition createDisposition, CreateOptions createOptions, SecurityContext securityContext) { handle = null; fileStatus = FileStatus.FILE_DOES_NOT_EXIST; diff --git a/SMBLibrary/NTFileStore/INTFileStore.cs b/SMBLibrary/NTFileStore/INTFileStore.cs index dc3a7e6..db2f339 100644 --- a/SMBLibrary/NTFileStore/INTFileStore.cs +++ b/SMBLibrary/NTFileStore/INTFileStore.cs @@ -16,7 +16,7 @@ namespace SMBLibrary /// public interface INTFileStore { - NTStatus CreateFile(out object handle, out FileStatus fileStatus, string path, AccessMask desiredAccess, ShareAccess shareAccess, CreateDisposition createDisposition, CreateOptions createOptions, SecurityContext securityContext); + NTStatus CreateFile(out object handle, out FileStatus fileStatus, string path, AccessMask desiredAccess, FileAttributes fileAttributes, ShareAccess shareAccess, CreateDisposition createDisposition, CreateOptions createOptions, SecurityContext securityContext); NTStatus CloseFile(object handle); diff --git a/SMBLibrary/NTFileStore/NTFileStoreHelper.cs b/SMBLibrary/NTFileStore/NTFileStoreHelper.cs index fbbf4ba..76f0ad7 100644 --- a/SMBLibrary/NTFileStore/NTFileStoreHelper.cs +++ b/SMBLibrary/NTFileStore/NTFileStoreHelper.cs @@ -103,7 +103,7 @@ namespace SMBLibrary { 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, securityContext); + NTStatus openStatus = fileStore.CreateFile(out handle, out fileStatus, path, FileAccessMask.FILE_READ_ATTRIBUTES, 0, ShareAccess.FILE_SHARE_READ | ShareAccess.FILE_SHARE_WRITE, CreateDisposition.FILE_OPEN, 0, securityContext); if (openStatus != NTStatus.STATUS_SUCCESS) { return null; diff --git a/SMBLibrary/NTFileStore/NamedPipeStore.cs b/SMBLibrary/NTFileStore/NamedPipeStore.cs index 80b7dda..11029b5 100644 --- a/SMBLibrary/NTFileStore/NamedPipeStore.cs +++ b/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, SecurityContext securityContext) + public NTStatus CreateFile(out object handle, out FileStatus fileStatus, string path, AccessMask desiredAccess, FileAttributes fileAttributes, 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), diff --git a/SMBLibrary/Server/SMB1/NTCreateHelper.cs b/SMBLibrary/Server/SMB1/NTCreateHelper.cs index 3340d8b..b2bfaf7 100644 --- a/SMBLibrary/Server/SMB1/NTCreateHelper.cs +++ b/SMBLibrary/Server/SMB1/NTCreateHelper.cs @@ -39,7 +39,8 @@ 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, session.SecurityContext); + FileAttributes fileAttributes = ToFileAttributes(request.ExtFileAttributes); + NTStatus createStatus = share.FileStore.CreateFile(out handle, out fileStatus, path, request.DesiredAccess, fileAttributes, request.ShareAccess, request.CreateDisposition, request.CreateOptions, session.SecurityContext); if (createStatus != NTStatus.STATUS_SUCCESS) { state.LogToServer(Severity.Verbose, "Create: Opening '{0}{1}' failed. NTStatus: {2}.", share.Name, path, createStatus); @@ -191,5 +192,19 @@ namespace SMBLibrary.Server.SMB1 return CreateDisposition.FILE_OPEN; } } + + private static FileAttributes ToFileAttributes(ExtendedFileAttributes extendedFileAttributes) + { + // We only return flags that can be used with NtCreateFile + FileAttributes fileAttributes = FileAttributes.ReadOnly | + FileAttributes.Hidden | + FileAttributes.System | + FileAttributes.Archive | + FileAttributes.Normal | + FileAttributes.Temporary | + FileAttributes.Offline | + FileAttributes.Encrypted; + return (fileAttributes & (FileAttributes)extendedFileAttributes); + } } } diff --git a/SMBLibrary/Server/SMB1/OpenAndXHelper.cs b/SMBLibrary/Server/SMB1/OpenAndXHelper.cs index 65a90c5..adc08cc 100644 --- a/SMBLibrary/Server/SMB1/OpenAndXHelper.cs +++ b/SMBLibrary/Server/SMB1/OpenAndXHelper.cs @@ -56,7 +56,7 @@ namespace SMBLibrary.Server.SMB1 object handle; FileStatus fileStatus; - header.Status = share.FileStore.CreateFile(out handle, out fileStatus, path, desiredAccess, shareAccess, createDisposition, createOptions, session.SecurityContext); + header.Status = share.FileStore.CreateFile(out handle, out fileStatus, path, desiredAccess, 0, shareAccess, createDisposition, createOptions, session.SecurityContext); if (header.Status != NTStatus.STATUS_SUCCESS) { state.LogToServer(Severity.Verbose, "OpenAndX: Opening '{0}{1}' failed. NTStatus: {2}.", share.Name, path, header.Status); diff --git a/SMBLibrary/Server/SMB1/SMB1FileStoreHelper.Query.cs b/SMBLibrary/Server/SMB1/SMB1FileStoreHelper.Query.cs index 3944731..75e09fc 100644 --- a/SMBLibrary/Server/SMB1/SMB1FileStoreHelper.Query.cs +++ b/SMBLibrary/Server/SMB1/SMB1FileStoreHelper.Query.cs @@ -18,7 +18,7 @@ namespace SMBLibrary.Server.SMB1 { 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, securityContext); + NTStatus openStatus = fileStore.CreateFile(out handle, out fileStatus, path, FileAccessMask.FILE_READ_ATTRIBUTES, 0, ShareAccess.FILE_SHARE_READ | ShareAccess.FILE_SHARE_WRITE, CreateDisposition.FILE_OPEN, 0, securityContext); if (openStatus != NTStatus.STATUS_SUCCESS) { result = null; diff --git a/SMBLibrary/Server/SMB1/SMB1FileStoreHelper.QueryDirectory.cs b/SMBLibrary/Server/SMB1/SMB1FileStoreHelper.QueryDirectory.cs index b11a499..d2f11b7 100644 --- a/SMBLibrary/Server/SMB1/SMB1FileStoreHelper.QueryDirectory.cs +++ b/SMBLibrary/Server/SMB1/SMB1FileStoreHelper.QueryDirectory.cs @@ -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, securityContext); + NTStatus createStatus = fileStore.CreateFile(out handle, out fileStatus, path, DirectoryAccessMask.FILE_LIST_DIRECTORY | DirectoryAccessMask.FILE_TRAVERSE, 0, ShareAccess.FILE_SHARE_READ | ShareAccess.FILE_SHARE_WRITE, CreateDisposition.FILE_OPEN, CreateOptions.FILE_DIRECTORY_FILE, securityContext); if (createStatus != NTStatus.STATUS_SUCCESS) { result = null; diff --git a/SMBLibrary/Server/SMB1/SMB1FileStoreHelper.cs b/SMBLibrary/Server/SMB1/SMB1FileStoreHelper.cs index 140a2c1..77f2f12 100644 --- a/SMBLibrary/Server/SMB1/SMB1FileStoreHelper.cs +++ b/SMBLibrary/Server/SMB1/SMB1FileStoreHelper.cs @@ -18,7 +18,7 @@ namespace SMBLibrary.Server.SMB1 { 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, securityContext); + NTStatus createStatus = fileStore.CreateFile(out handle, out fileStatus, path, DirectoryAccessMask.FILE_ADD_SUBDIRECTORY, 0, ShareAccess.FILE_SHARE_READ | ShareAccess.FILE_SHARE_WRITE, CreateDisposition.FILE_CREATE, CreateOptions.FILE_DIRECTORY_FILE, securityContext); if (createStatus != NTStatus.STATUS_SUCCESS) { return createStatus; @@ -41,7 +41,7 @@ namespace SMBLibrary.Server.SMB1 { object handle; FileStatus fileStatus; - NTStatus openStatus = fileStore.CreateFile(out handle, out fileStatus, path, DirectoryAccessMask.DELETE, 0, CreateDisposition.FILE_OPEN, createOptions, securityContext); + NTStatus openStatus = fileStore.CreateFile(out handle, out fileStatus, path, DirectoryAccessMask.DELETE, 0, 0, CreateDisposition.FILE_OPEN, createOptions, securityContext); if (openStatus != NTStatus.STATUS_SUCCESS) { return openStatus; @@ -68,7 +68,7 @@ namespace SMBLibrary.Server.SMB1 { createOptions = CreateOptions.FILE_NON_DIRECTORY_FILE; } - NTStatus openStatus = fileStore.CreateFile(out handle, out fileStatus, oldName, DirectoryAccessMask.DELETE, 0, CreateDisposition.FILE_OPEN, createOptions, securityContext); + NTStatus openStatus = fileStore.CreateFile(out handle, out fileStatus, oldName, DirectoryAccessMask.DELETE, 0, 0, CreateDisposition.FILE_OPEN, createOptions, securityContext); if (openStatus != NTStatus.STATUS_SUCCESS) { return openStatus; @@ -89,7 +89,7 @@ namespace SMBLibrary.Server.SMB1 { 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, securityContext); + NTStatus openStatus = fileStore.CreateFile(out handle, out fileStatus, path, (AccessMask)0, 0, ShareAccess.FILE_SHARE_READ | ShareAccess.FILE_SHARE_WRITE, CreateDisposition.FILE_OPEN, CreateOptions.FILE_DIRECTORY_FILE, securityContext); if (openStatus != NTStatus.STATUS_SUCCESS) { return openStatus; @@ -103,7 +103,7 @@ namespace SMBLibrary.Server.SMB1 { 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, securityContext); + NTStatus openStatus = fileStore.CreateFile(out handle, out fileStatus, path, FileAccessMask.FILE_READ_ATTRIBUTES, 0, ShareAccess.FILE_SHARE_READ | ShareAccess.FILE_SHARE_WRITE, CreateDisposition.FILE_OPEN, 0, securityContext); if (openStatus != NTStatus.STATUS_SUCCESS) { fileInfo = null; @@ -118,7 +118,7 @@ namespace SMBLibrary.Server.SMB1 { 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, securityContext); + NTStatus openStatus = fileStore.CreateFile(out handle, out fileStatus, path, FileAccessMask.FILE_WRITE_ATTRIBUTES, (FileAttributes)0, ShareAccess.FILE_SHARE_READ | ShareAccess.FILE_SHARE_WRITE, CreateDisposition.FILE_OPEN, 0, securityContext); if (openStatus != NTStatus.STATUS_SUCCESS) { return openStatus; diff --git a/SMBLibrary/Server/SMB2/CreateHelper.cs b/SMBLibrary/Server/SMB2/CreateHelper.cs index fd951e1..952d248 100644 --- a/SMBLibrary/Server/SMB2/CreateHelper.cs +++ b/SMBLibrary/Server/SMB2/CreateHelper.cs @@ -35,7 +35,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, session.SecurityContext); + NTStatus createStatus = share.FileStore.CreateFile(out handle, out fileStatus, path, request.DesiredAccess, request.FileAttributes, request.ShareAccess, request.CreateDisposition, request.CreateOptions, session.SecurityContext); if (createStatus != NTStatus.STATUS_SUCCESS) { state.LogToServer(Severity.Verbose, "Create: Opening '{0}{1}' failed. NTStatus: {2}.", share.Name, path, createStatus);