API improvement: FileSystemShare: Added OnAccessRequest event that allows the subscriber to manage read / write permissions

This commit is contained in:
Tal Aloni 2017-02-09 14:22:52 +02:00
parent f9ad9f9b5e
commit fd26380dab
16 changed files with 248 additions and 81 deletions

View file

@ -20,10 +20,10 @@ namespace SMBLibrary.Server
public const int BytesPerSector = 512;
public const int ClusterSize = 4096;
public static NTStatus CreateFile(out FileSystemEntry entry, FileSystemShare share, string userName, string path, CreateDisposition createDisposition, CreateOptions createOptions, AccessMask desiredAccess, ConnectionState state)
public static NTStatus CreateFile(out FileSystemEntry entry, IFileSystem fileSystem, string path, AccessMask desiredAccess, CreateDisposition createDisposition, CreateOptions createOptions, ConnectionState state)
{
bool hasWriteAccess = share.HasWriteAccess(userName);
IFileSystem fileSystem = share.FileSystem;
FileAccess createAccess = ToCreateFileAccess(desiredAccess, createDisposition);
bool requestedWriteAccess = (createAccess & FileAccess.Write) > 0;
bool forceDirectory = (createOptions & CreateOptions.FILE_DIRECTORY_FILE) > 0;
bool forceFile = (createOptions & CreateOptions.FILE_NON_DIRECTORY_FILE) > 0;
@ -82,7 +82,7 @@ namespace SMBLibrary.Server
return NTStatus.STATUS_OBJECT_NAME_COLLISION;
}
if (!hasWriteAccess)
if (!requestedWriteAccess)
{
return NTStatus.STATUS_ACCESS_DENIED;
}
@ -132,7 +132,7 @@ namespace SMBLibrary.Server
return NTStatus.STATUS_OBJECT_PATH_NOT_FOUND;
}
if (!hasWriteAccess)
if (!requestedWriteAccess)
{
return NTStatus.STATUS_ACCESS_DENIED;
}
@ -173,7 +173,7 @@ namespace SMBLibrary.Server
createDisposition == CreateDisposition.FILE_OVERWRITE_IF ||
createDisposition == CreateDisposition.FILE_SUPERSEDE)
{
if (!hasWriteAccess)
if (!requestedWriteAccess)
{
return NTStatus.STATUS_ACCESS_DENIED;
}
@ -208,12 +208,6 @@ namespace SMBLibrary.Server
return NTStatus.STATUS_INVALID_PARAMETER;
}
FileAccess fileAccess = ToFileAccess(desiredAccess.File);
if (!hasWriteAccess && (fileAccess == FileAccess.Write || fileAccess == FileAccess.ReadWrite))
{
return NTStatus.STATUS_ACCESS_DENIED;
}
return NTStatus.STATUS_SUCCESS;
}
@ -395,6 +389,48 @@ namespace SMBLibrary.Server
}
}
public static FileAccess ToCreateFileAccess(AccessMask desiredAccess, CreateDisposition createDisposition)
{
FileAccess result = 0;
if ((desiredAccess.File & FileAccessMask.FILE_READ_DATA) > 0 ||
(desiredAccess.File & FileAccessMask.FILE_READ_EA) > 0 ||
(desiredAccess.File & FileAccessMask.FILE_READ_ATTRIBUTES) > 0 ||
(desiredAccess.File & FileAccessMask.MAXIMUM_ALLOWED) > 0 ||
(desiredAccess.File & FileAccessMask.GENERIC_ALL) > 0 ||
(desiredAccess.File & FileAccessMask.GENERIC_READ) > 0)
{
result |= FileAccess.Read;
}
if ((desiredAccess.File & FileAccessMask.FILE_WRITE_DATA) > 0 ||
(desiredAccess.File & FileAccessMask.FILE_APPEND_DATA) > 0 ||
(desiredAccess.File & FileAccessMask.FILE_WRITE_EA) > 0 ||
(desiredAccess.File & FileAccessMask.FILE_WRITE_ATTRIBUTES) > 0 ||
(desiredAccess.File & FileAccessMask.DELETE) > 0 ||
(desiredAccess.File & FileAccessMask.WRITE_DAC) > 0 ||
(desiredAccess.File & FileAccessMask.WRITE_OWNER) > 0 ||
(desiredAccess.File & FileAccessMask.MAXIMUM_ALLOWED) > 0 ||
(desiredAccess.File & FileAccessMask.GENERIC_ALL) > 0 ||
(desiredAccess.File & FileAccessMask.GENERIC_WRITE) > 0)
{
result |= FileAccess.Write;
}
if ((desiredAccess.Directory & DirectoryAccessMask.FILE_DELETE_CHILD) > 0)
{
result |= FileAccess.Write;
}
if (createDisposition == CreateDisposition.FILE_CREATE ||
createDisposition == CreateDisposition.FILE_SUPERSEDE)
{
result |= FileAccess.Write;
}
return result;
}
public static FileAccess ToFileAccess(FileAccessMask desiredAccess)
{
FileAccess result = 0;

View file

@ -18,7 +18,7 @@ namespace SMBLibrary.Server.SMB1
internal static SMB1Command GetCreateDirectoryResponse(SMB1Header header, CreateDirectoryRequest request, FileSystemShare share, SMB1ConnectionState state)
{
SMB1Session session = state.GetSession(header.UID);
if (!share.HasWriteAccess(session.UserName))
if (!share.HasWriteAccess(session.UserName, request.DirectoryName, state.ClientEndPoint))
{
header.Status = NTStatus.STATUS_ACCESS_DENIED;
return new ErrorResponse(CommandName.SMB_COM_CREATE_DIRECTORY);
@ -48,7 +48,7 @@ namespace SMBLibrary.Server.SMB1
internal static SMB1Command GetDeleteDirectoryResponse(SMB1Header header, DeleteDirectoryRequest request, FileSystemShare share, SMB1ConnectionState state)
{
SMB1Session session = state.GetSession(header.UID);
if (!share.HasWriteAccess(session.UserName))
if (!share.HasWriteAccess(session.UserName, request.DirectoryName, state.ClientEndPoint))
{
header.Status = NTStatus.STATUS_ACCESS_DENIED;
return new ErrorResponse(CommandName.SMB_COM_DELETE_DIRECTORY);
@ -103,7 +103,7 @@ namespace SMBLibrary.Server.SMB1
internal static SMB1Command GetDeleteResponse(SMB1Header header, DeleteRequest request, FileSystemShare share, SMB1ConnectionState state)
{
SMB1Session session = state.GetSession(header.UID);
if (!share.HasWriteAccess(session.UserName))
if (!share.HasWriteAccess(session.UserName, request.FileName, state.ClientEndPoint))
{
header.Status = NTStatus.STATUS_ACCESS_DENIED;
return new ErrorResponse(CommandName.SMB_COM_DELETE);
@ -146,7 +146,12 @@ namespace SMBLibrary.Server.SMB1
internal static SMB1Command GetRenameResponse(SMB1Header header, RenameRequest request, FileSystemShare share, SMB1ConnectionState state)
{
SMB1Session session = state.GetSession(header.UID);
if (!share.HasWriteAccess(session.UserName))
if (!share.HasWriteAccess(session.UserName, request.OldFileName, state.ClientEndPoint))
{
header.Status = NTStatus.STATUS_ACCESS_DENIED;
return new ErrorResponse(CommandName.SMB_COM_RENAME);
}
if (!share.HasWriteAccess(session.UserName, request.NewFileName, state.ClientEndPoint))
{
header.Status = NTStatus.STATUS_ACCESS_DENIED;
return new ErrorResponse(CommandName.SMB_COM_RENAME);
@ -210,7 +215,7 @@ namespace SMBLibrary.Server.SMB1
internal static SMB1Command GetSetInformationResponse(SMB1Header header, SetInformationRequest request, FileSystemShare share, SMB1ConnectionState state)
{
SMB1Session session = state.GetSession(header.UID);
if (!share.HasWriteAccess(session.UserName))
if (!share.HasWriteAccess(session.UserName, request.FileName, state.ClientEndPoint))
{
header.Status = NTStatus.STATUS_ACCESS_DENIED;
return new ErrorResponse(CommandName.SMB_COM_SET_INFORMATION2);
@ -259,7 +264,7 @@ namespace SMBLibrary.Server.SMB1
return new ErrorResponse(CommandName.SMB_COM_SET_INFORMATION2);
}
if (!share.HasWriteAccess(session.UserName))
if (!share.HasWriteAccess(session.UserName, openFile.Path, state.ClientEndPoint))
{
header.Status = NTStatus.STATUS_ACCESS_DENIED;
return new ErrorResponse(CommandName.SMB_COM_SET_INFORMATION2);

View file

@ -48,9 +48,15 @@ namespace SMBLibrary.Server.SMB1
else // FileSystemShare
{
FileSystemShare fileSystemShare = (FileSystemShare)share;
string userName = session.UserName;
FileAccess createAccess = NTFileSystemHelper.ToCreateFileAccess(request.DesiredAccess, request.CreateDisposition);
if (!fileSystemShare.HasAccess(session.UserName, path, createAccess, state.ClientEndPoint))
{
header.Status = NTStatus.STATUS_ACCESS_DENIED;
return new ErrorResponse(request.CommandName);
}
FileSystemEntry entry;
NTStatus createStatus = NTFileSystemHelper.CreateFile(out entry, fileSystemShare, userName, path, request.CreateDisposition, request.CreateOptions, request.DesiredAccess, state);
NTStatus createStatus = NTFileSystemHelper.CreateFile(out entry, fileSystemShare.FileSystem, path, request.DesiredAccess, request.CreateDisposition, request.CreateOptions, state);
if (createStatus != NTStatus.STATUS_SUCCESS)
{
header.Status = createStatus;

View file

@ -48,20 +48,19 @@ namespace SMBLibrary.Server.SMB1
else // FileSystemShare
{
FileSystemShare fileSystemShare = (FileSystemShare)share;
string userName = session.UserName;
bool hasWriteAccess = fileSystemShare.HasWriteAccess(userName);
FileAccess fileAccess = ToFileAccess(request.AccessMode.AccessMode);
if (!fileSystemShare.HasAccess(session.UserName, path, fileAccess, state.ClientEndPoint))
{
header.Status = NTStatus.STATUS_ACCESS_DENIED;
return new ErrorResponse(request.CommandName);
}
IFileSystem fileSystem = fileSystemShare.FileSystem;
OpenResult openResult;
FileSystemEntry entry = fileSystem.GetEntry(path);
if (entry != null)
{
if (!hasWriteAccess && request.AccessMode.AccessMode == AccessMode.Write || request.AccessMode.AccessMode == AccessMode.ReadWrite)
{
header.Status = NTStatus.STATUS_ACCESS_DENIED;
return new ErrorResponse(CommandName.SMB_COM_OPEN_ANDX);
}
if (request.OpenMode.FileExistsOpts == FileExistsOpts.ReturnError)
{
header.Status = NTStatus.STATUS_OBJECT_NAME_COLLISION;
@ -121,7 +120,6 @@ namespace SMBLibrary.Server.SMB1
openResult = OpenResult.NotExistedAndWasCreated;
}
FileAccess fileAccess = ToFileAccess(request.AccessMode.AccessMode);
FileShare fileShare = ToFileShare(request.AccessMode.SharingMode);
Stream stream = null;
if (!entry.IsDirectory)

View file

@ -26,6 +26,16 @@ namespace SMBLibrary.Server.SMB1
header.Status = NTStatus.STATUS_INVALID_HANDLE;
return null;
}
if (share is FileSystemShare)
{
if (!((FileSystemShare)share).HasReadAccess(session.UserName, openFile.Path, state.ClientEndPoint))
{
header.Status = NTStatus.STATUS_ACCESS_DENIED;
return new ErrorResponse(request.CommandName);
}
}
byte[] data;
header.Status = NTFileSystemHelper.ReadFile(out data, openFile, request.ReadOffsetInBytes, request.CountOfBytesToRead, state);
if (header.Status != NTStatus.STATUS_SUCCESS)
@ -48,6 +58,16 @@ namespace SMBLibrary.Server.SMB1
header.Status = NTStatus.STATUS_INVALID_HANDLE;
return null;
}
if (share is FileSystemShare)
{
if (!((FileSystemShare)share).HasReadAccess(session.UserName, openFile.Path, state.ClientEndPoint))
{
header.Status = NTStatus.STATUS_ACCESS_DENIED;
return new ErrorResponse(request.CommandName);
}
}
uint maxCount = request.MaxCount;
if ((share is FileSystemShare) && state.LargeRead)
{
@ -79,6 +99,16 @@ namespace SMBLibrary.Server.SMB1
header.Status = NTStatus.STATUS_INVALID_HANDLE;
return new ErrorResponse(request.CommandName);
}
if (share is FileSystemShare)
{
if (!((FileSystemShare)share).HasWriteAccess(session.UserName, openFile.Path, state.ClientEndPoint))
{
header.Status = NTStatus.STATUS_ACCESS_DENIED;
return new ErrorResponse(request.CommandName);
}
}
int numberOfBytesWritten;
header.Status = NTFileSystemHelper.WriteFile(out numberOfBytesWritten, openFile, request.WriteOffsetInBytes, request.Data, state);
if (header.Status != NTStatus.STATUS_SUCCESS)
@ -99,6 +129,16 @@ namespace SMBLibrary.Server.SMB1
header.Status = NTStatus.STATUS_INVALID_HANDLE;
return new ErrorResponse(request.CommandName);
}
if (share is FileSystemShare)
{
if (!((FileSystemShare)share).HasWriteAccess(session.UserName, openFile.Path, state.ClientEndPoint))
{
header.Status = NTStatus.STATUS_ACCESS_DENIED;
return new ErrorResponse(request.CommandName);
}
}
int numberOfBytesWritten;
header.Status = NTFileSystemHelper.WriteFile(out numberOfBytesWritten, openFile, (long)request.Offset, request.Data, state);
if (header.Status != NTStatus.STATUS_SUCCESS)

View file

@ -116,6 +116,13 @@ namespace SMBLibrary.Server.SMB1
internal static Transaction2QueryFSInformationResponse GetSubcommandResponse(SMB1Header header, Transaction2QueryFSInformationRequest subcommand, FileSystemShare share, SMB1ConnectionState state)
{
SMB1Session session = state.GetSession(header.UID);
if (!share.HasReadAccess(session.UserName, @"\", state.ClientEndPoint))
{
header.Status = NTStatus.STATUS_ACCESS_DENIED;
return null;
}
Transaction2QueryFSInformationResponse response = new Transaction2QueryFSInformationResponse();
QueryFSInformation queryFSInformation;
NTStatus queryStatus = SMB1FileSystemHelper.GetFileSystemInformation(out queryFSInformation, subcommand.InformationLevel, share.FileSystem);
@ -131,8 +138,15 @@ namespace SMBLibrary.Server.SMB1
internal static Transaction2QueryPathInformationResponse GetSubcommandResponse(SMB1Header header, Transaction2QueryPathInformationRequest subcommand, FileSystemShare share, SMB1ConnectionState state)
{
IFileSystem fileSystem = share.FileSystem;
SMB1Session session = state.GetSession(header.UID);
string path = subcommand.FileName;
if (!share.HasReadAccess(session.UserName, path, state.ClientEndPoint))
{
header.Status = NTStatus.STATUS_ACCESS_DENIED;
return null;
}
IFileSystem fileSystem = share.FileSystem;
FileSystemEntry entry = fileSystem.GetEntry(path);
if (entry == null)
{
@ -165,6 +179,12 @@ namespace SMBLibrary.Server.SMB1
header.Status = NTStatus.STATUS_INVALID_HANDLE;
return null;
}
if (!share.HasReadAccess(session.UserName, openFile.Path, state.ClientEndPoint))
{
header.Status = NTStatus.STATUS_ACCESS_DENIED;
return null;
}
FileSystemEntry entry = fileSystem.GetEntry(openFile.Path);
if (entry == null)
@ -195,6 +215,12 @@ namespace SMBLibrary.Server.SMB1
return null;
}
if (!share.HasWriteAccess(session.UserName, openFile.Path, state.ClientEndPoint))
{
header.Status = NTStatus.STATUS_ACCESS_DENIED;
return null;
}
SetInformation information;
try
{
@ -211,12 +237,6 @@ namespace SMBLibrary.Server.SMB1
return null;
}
if (!share.HasWriteAccess(session.UserName))
{
header.Status = NTStatus.STATUS_ACCESS_DENIED;
return null;
}
NTStatus status = SMB1FileSystemHelper.SetFileInformation(share.FileSystem, openFile, information, state);
if (status != NTStatus.STATUS_SUCCESS)
{

View file

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

View file

@ -42,9 +42,14 @@ namespace SMBLibrary.Server.SMB2
else
{
FileSystemShare fileSystemShare = (FileSystemShare)share;
FileAccess createAccess = NTFileSystemHelper.ToCreateFileAccess(request.DesiredAccess, request.CreateDisposition);
if (!fileSystemShare.HasAccess(session.UserName, path, createAccess, state.ClientEndPoint))
{
return new ErrorResponse(request.CommandName, NTStatus.STATUS_ACCESS_DENIED);
}
FileSystemEntry entry;
NTStatus createStatus = NTFileSystemHelper.CreateFile(out entry, (FileSystemShare)share, session.UserName, path, request.CreateDisposition, request.CreateOptions, request.DesiredAccess, state);
NTStatus createStatus = NTFileSystemHelper.CreateFile(out entry, fileSystemShare.FileSystem, path, request.DesiredAccess, request.CreateDisposition, request.CreateOptions, state);
if (createStatus != NTStatus.STATUS_SUCCESS)
{
return new ErrorResponse(request.CommandName, createStatus);

View file

@ -28,6 +28,11 @@ namespace SMBLibrary.Server.SMB2
return new ErrorResponse(request.CommandName, NTStatus.STATUS_FILE_CLOSED);
}
if (!((FileSystemShare)share).HasReadAccess(session.UserName, openFile.Path, state.ClientEndPoint))
{
return new ErrorResponse(request.CommandName, NTStatus.STATUS_ACCESS_DENIED);
}
FileSystemShare fileSystemShare = (FileSystemShare)share;
IFileSystem fileSystem = fileSystemShare.FileSystem;

View file

@ -33,6 +33,10 @@ namespace SMBLibrary.Server.SMB2
}
else // FileSystemShare
{
if (!((FileSystemShare)share).HasReadAccess(session.UserName, openFile.Path, state.ClientEndPoint))
{
return new ErrorResponse(request.CommandName, NTStatus.STATUS_ACCESS_DENIED);
}
IFileSystem fileSystem = ((FileSystemShare)share).FileSystem;
FileSystemEntry entry = fileSystem.GetEntry(openFile.Path);
if (entry == null)
@ -56,6 +60,10 @@ namespace SMBLibrary.Server.SMB2
{
if (share is FileSystemShare)
{
if (!((FileSystemShare)share).HasReadAccess(session.UserName, @"\", state.ClientEndPoint))
{
return new ErrorResponse(request.CommandName, NTStatus.STATUS_ACCESS_DENIED);
}
IFileSystem fileSystem = ((FileSystemShare)share).FileSystem;
FileSystemInformation fileSystemInformation;
NTStatus queryStatus = NTFileSystemHelper.GetFileSystemInformation(out fileSystemInformation, request.FileSystemInformationClass, fileSystem);

View file

@ -28,10 +28,11 @@ namespace SMBLibrary.Server.SMB2
if (share is FileSystemShare)
{
IFileSystem fileSystem = ((FileSystemShare)share).FileSystem;
if (!((FileSystemShare)share).HasWriteAccess(session.UserName))
if (!((FileSystemShare)share).HasWriteAccess(session.UserName, openFile.Path, state.ClientEndPoint))
{
return new ErrorResponse(request.CommandName, NTStatus.STATUS_ACCESS_DENIED);
}
FileInformation information;
try
{
@ -50,6 +51,15 @@ namespace SMBLibrary.Server.SMB2
return new ErrorResponse(request.CommandName, NTStatus.STATUS_INVALID_PARAMETER);
}
if (information is FileRenameInformationType2)
{
string newFileName = ((FileRenameInformationType2)information).FileName;
if (!((FileSystemShare)share).HasWriteAccess(session.UserName, newFileName, state.ClientEndPoint))
{
return new ErrorResponse(request.CommandName, NTStatus.STATUS_ACCESS_DENIED);
}
}
NTStatus status = NTFileSystemHelper.SetFileInformation(fileSystem, openFile, information, state);
if (status != NTStatus.STATUS_SUCCESS)
{

View file

@ -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))
if (!((FileSystemShare)share).HasReadAccess(session.UserName, @"\", state.ClientEndPoint))
{
return new ErrorResponse(request.CommandName, NTStatus.STATUS_ACCESS_DENIED);
}

View file

@ -218,12 +218,6 @@ namespace SMBLibrary.Server
}
else if (command is WriteRequest)
{
string userName = session.UserName;
if (share is FileSystemShare && !((FileSystemShare)share).HasWriteAccess(userName))
{
header.Status = NTStatus.STATUS_ACCESS_DENIED;
return new ErrorResponse(command.CommandName);
}
WriteRequest request = (WriteRequest)command;
return ReadWriteResponseHelper.GetWriteResponse(header, request, share, state);
}
@ -272,12 +266,6 @@ namespace SMBLibrary.Server
}
else if (command is WriteAndXRequest)
{
string userName = session.UserName;
if (share is FileSystemShare && !((FileSystemShare)share).HasWriteAccess(userName))
{
header.Status = NTStatus.STATUS_ACCESS_DENIED;
return new ErrorResponse(command.CommandName);
}
WriteAndXRequest request = (WriteAndXRequest)command;
return ReadWriteResponseHelper.GetWriteResponse(header, request, share, state);
}

View file

@ -6,17 +6,36 @@
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using Utilities;
namespace SMBLibrary.Server
{
public class AccessRequestArgs : EventArgs
{
public string UserName;
public string Path;
public FileAccess RequestedAccess;
public IPEndPoint ClientEndPoint;
public bool Allow = true;
public AccessRequestArgs(string userName, string path, FileAccess requestedAccess, IPEndPoint clientEndPoint)
{
UserName = userName;
Path = path;
RequestedAccess = requestedAccess;
ClientEndPoint = clientEndPoint;
}
}
public class FileSystemShare : ISMBShare
{
private string m_name;
public IFileSystem m_fileSystem;
public List<string> ReadAccess;
public List<string> WriteAccess;
public event EventHandler<AccessRequestArgs> OnAccessRequest;
public FileSystemShare(string shareName, IFileSystem fileSystem)
{
@ -24,31 +43,27 @@ namespace SMBLibrary.Server
m_fileSystem = fileSystem;
}
public bool HasReadAccess(string userName)
public bool HasReadAccess(string userName, string path, IPEndPoint clientEndPoint)
{
return Contains(ReadAccess, userName);
return HasAccess(userName, path, FileAccess.Read, clientEndPoint);
}
public bool HasWriteAccess(string userName)
public bool HasWriteAccess(string userName, string path, IPEndPoint clientEndPoint)
{
return Contains(WriteAccess, userName);
return HasAccess(userName, path, FileAccess.Write, clientEndPoint);
}
public static bool Contains(List<string> list, string value)
public bool HasAccess(string userName, string path, FileAccess requestedAccess, IPEndPoint clientEndPoint)
{
return (IndexOf(list, value) >= 0);
}
public static int IndexOf(List<string> list, string value)
{
for (int index = 0; index < list.Count; index++)
// To be thread-safe we must capture the delegate reference first
EventHandler<AccessRequestArgs> handler = OnAccessRequest;
if (handler != null)
{
if (string.Equals(list[index], value, StringComparison.InvariantCultureIgnoreCase))
{
return index;
}
AccessRequestArgs args = new AccessRequestArgs(userName, path, requestedAccess, clientEndPoint);
handler(this, args);
return args.Allow;
}
return -1;
return true;
}
public string Name

View file

@ -13,11 +13,9 @@ namespace SMBLibrary.Server
{
public class ShareCollection : List<FileSystemShare>
{
public void Add(string shareName, List<string> readAccess, List<string> writeAccess, IFileSystem fileSystem)
public void Add(string shareName, IFileSystem fileSystem)
{
FileSystemShare share = new FileSystemShare(shareName, fileSystem);
share.ReadAccess = readAccess;
share.WriteAccess = writeAccess;
this.Add(share);
}

View file

@ -165,7 +165,23 @@ namespace SMBServer
List<string> readAccess = ReadAccessList(readAccessNode, allUsers);
XmlNode writeAccessNode = shareNode.SelectSingleNode("WriteAccess");
List<string> writeAccess = ReadAccessList(writeAccessNode, allUsers);
shares.Add(shareName, readAccess, writeAccess, new DirectoryFileSystem(sharePath));
FileSystemShare share = new FileSystemShare(shareName, new DirectoryFileSystem(sharePath));
share.OnAccessRequest += delegate(object sender, AccessRequestArgs args)
{
if (args.RequestedAccess == FileAccess.Read)
{
args.Allow = Contains(readAccess, args.UserName);
}
else if (args.RequestedAccess == FileAccess.Write)
{
args.Allow = Contains(writeAccess, args.UserName);
}
else // FileAccess.ReadWrite
{
args.Allow = Contains(readAccess, args.UserName) && Contains(writeAccess, args.UserName);
}
};
shares.Add(share);
}
return shares;
}
@ -207,13 +223,6 @@ namespace SMBServer
}
}
private static XmlDocument GetXmlDocument(string path)
{
XmlDocument doc = new XmlDocument();
doc.Load(path);
return doc;
}
private void Server_OnLogEntry(object sender, LogEntry entry)
{
string timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ");
@ -236,5 +245,29 @@ namespace SMBServer
chkSMB1.Checked = true;
}
}
public static XmlDocument GetXmlDocument(string path)
{
XmlDocument doc = new XmlDocument();
doc.Load(path);
return doc;
}
public static bool Contains(List<string> list, string value)
{
return (IndexOf(list, value) >= 0);
}
public static int IndexOf(List<string> list, string value)
{
for (int index = 0; index < list.Count; index++)
{
if (string.Equals(list[index], value, StringComparison.InvariantCultureIgnoreCase))
{
return index;
}
}
return -1;
}
}
}