Server: Pass SetFileSystemInformation requests to the underlying object store

This commit is contained in:
Tal Aloni 2017-10-01 17:42:15 +03:00
parent c1210d57bc
commit 0f754ee55c
3 changed files with 90 additions and 1 deletions

View file

@ -174,6 +174,56 @@ namespace SMBLibrary.Server.SMB1
return response;
}
internal static Transaction2SetFSInformationResponse GetSubcommandResponse(SMB1Header header, Transaction2SetFSInformationRequest subcommand, ISMBShare share, SMB1ConnectionState state)
{
SMB1Session session = state.GetSession(header.UID);
if (share is FileSystemShare)
{
if (!((FileSystemShare)share).HasWriteAccess(session.SecurityContext, @"\"))
{
state.LogToServer(Severity.Verbose, "SetFileSystemInformation on '{0}' failed. User '{1}' was denied access.", share.Name, session.UserName);
header.Status = NTStatus.STATUS_ACCESS_DENIED;
return null;
}
}
if (!subcommand.IsPassthroughInformationLevel)
{
state.LogToServer(Severity.Verbose, "SetFileSystemInformation on '{0}' failed. Not a pass-through information level.", share.Name);
header.Status = NTStatus.STATUS_NOT_SUPPORTED;
return null;
}
FileSystemInformation fileSystemInfo;
try
{
fileSystemInfo = FileSystemInformation.GetFileSystemInformation(subcommand.InformationBytes, 0, subcommand.FileSystemInformationClass);
}
catch (UnsupportedInformationLevelException)
{
state.LogToServer(Severity.Verbose, "SetFileSystemInformation on '{0}' failed. Information class: {1}, NTStatus: STATUS_OS2_INVALID_LEVEL.", share.Name, subcommand.FileSystemInformationClass);
header.Status = NTStatus.STATUS_OS2_INVALID_LEVEL;
return null;
}
catch (Exception)
{
state.LogToServer(Severity.Verbose, "SetFileSystemInformation on '{0}' failed. Information class: {1}, NTStatus: STATUS_INVALID_PARAMETER.", share.Name, subcommand.FileSystemInformationClass);
header.Status = NTStatus.STATUS_INVALID_PARAMETER;
return null;
}
NTStatus status = share.FileStore.SetFileSystemInformation(fileSystemInfo);
if (status != NTStatus.STATUS_SUCCESS)
{
state.LogToServer(Severity.Verbose, "SetFileSystemInformation on '{0}' failed. Information class: {1}, NTStatus: {2}.", share.Name, subcommand.FileSystemInformationClass, status);
header.Status = status;
return null;
}
state.LogToServer(Severity.Verbose, "SetFileSystemInformation on '{0}' succeeded. Information class: {1}.", share.Name, subcommand.FileSystemInformationClass);
return new Transaction2SetFSInformationResponse();
}
internal static Transaction2QueryPathInformationResponse GetSubcommandResponse(SMB1Header header, Transaction2QueryPathInformationRequest subcommand, ISMBShare share, SMB1ConnectionState state)
{
SMB1Session session = state.GetSession(header.UID);

View file

@ -210,7 +210,7 @@ namespace SMBLibrary.Server.SMB1
}
else if (subcommand is Transaction2SetFSInformationRequest)
{
header.Status = NTStatus.STATUS_NOT_IMPLEMENTED;
subcommandResponse = Transaction2SubcommandHelper.GetSubcommandResponse(header, (Transaction2SetFSInformationRequest)subcommand, share, state);
}
else if (subcommand is Transaction2QueryPathInformationRequest)
{

View file

@ -36,6 +36,17 @@ namespace SMBLibrary.Server.SMB2
}
}
}
else if (request.InfoType == InfoType.FileSystem)
{
if (share is FileSystemShare)
{
if (!((FileSystemShare)share).HasWriteAccess(session.SecurityContext, @"\"))
{
state.LogToServer(Severity.Verbose, "SetFileSystemInformation on '{0}' failed. User '{1}' was denied access.", share.Name, session.UserName);
return new ErrorResponse(request.CommandName, NTStatus.STATUS_ACCESS_DENIED);
}
}
}
if (request.InfoType == InfoType.File)
{
@ -97,6 +108,34 @@ namespace SMBLibrary.Server.SMB2
}
return new SetInfoResponse();
}
else if (request.InfoType == InfoType.FileSystem)
{
FileSystemInformation fileSystemInformation;
try
{
fileSystemInformation = FileSystemInformation.GetFileSystemInformation(request.Buffer, 0, request.FileSystemInformationClass);
}
catch (UnsupportedInformationLevelException)
{
state.LogToServer(Severity.Verbose, "SetFileSystemInformation on '{0}' failed. Information class: {1}, NTStatus: STATUS_INVALID_INFO_CLASS.", share.Name, request.FileSystemInformationClass);
return new ErrorResponse(request.CommandName, NTStatus.STATUS_INVALID_INFO_CLASS);
}
catch (Exception)
{
state.LogToServer(Severity.Verbose, "SetFileSystemInformation on '{0}' failed. Information class: {1}, NTStatus: STATUS_INVALID_PARAMETER.", share.Name, request.FileSystemInformationClass);
return new ErrorResponse(request.CommandName, NTStatus.STATUS_INVALID_PARAMETER);
}
NTStatus status = share.FileStore.SetFileSystemInformation(fileSystemInformation);
if (status != NTStatus.STATUS_SUCCESS)
{
state.LogToServer(Severity.Verbose, "SetFileSystemInformation on '{0}' failed. Information class: {1}, NTStatus: {2}.", share.Name, request.FileSystemInformationClass, status);
return new ErrorResponse(request.CommandName, status);
}
state.LogToServer(Severity.Verbose, "SetFileSystemInformation on '{0}' succeeded. Information class: {1}.", share.Name, request.FileSystemInformationClass);
return new SetInfoResponse();
}
else if (request.InfoType == InfoType.Security)
{
SecurityDescriptor securityDescriptor;