mirror of
https://github.com/TalAloni/SMBLibrary.git
synced 2025-07-21 16:55:54 +02:00
Server: Pass GetSecurityInformation and SetSecurityInformation requests to the underlying object store
This commit is contained in:
parent
204c912074
commit
a17d827076
3 changed files with 127 additions and 4 deletions
|
@ -98,7 +98,7 @@ namespace SMBLibrary.Server.SMB1
|
|||
}
|
||||
else if (subcommand is NTTransactSetSecurityDescriptorRequest)
|
||||
{
|
||||
header.Status = NTStatus.STATUS_NOT_IMPLEMENTED;
|
||||
subcommandResponse = GetSubcommandResponse(header, (NTTransactSetSecurityDescriptorRequest)subcommand, share, state);
|
||||
}
|
||||
else if (subcommand is NTTransactNotifyChangeRequest)
|
||||
{
|
||||
|
@ -110,7 +110,7 @@ namespace SMBLibrary.Server.SMB1
|
|||
}
|
||||
else if (subcommand is NTTransactQuerySecurityDescriptorRequest)
|
||||
{
|
||||
header.Status = NTStatus.STATUS_NOT_IMPLEMENTED;
|
||||
subcommandResponse = GetSubcommandResponse(header, maxDataCount, (NTTransactQuerySecurityDescriptorRequest)subcommand, share, state);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -164,6 +164,64 @@ namespace SMBLibrary.Server.SMB1
|
|||
return response;
|
||||
}
|
||||
|
||||
private static NTTransactSetSecurityDescriptorResponse GetSubcommandResponse(SMB1Header header, NTTransactSetSecurityDescriptorRequest subcommand, ISMBShare share, SMB1ConnectionState state)
|
||||
{
|
||||
SMB1Session session = state.GetSession(header.UID);
|
||||
OpenFileObject openFile = session.GetOpenFileObject(subcommand.FID);
|
||||
if (openFile == null)
|
||||
{
|
||||
state.LogToServer(Severity.Verbose, "SetSecurityInformation failed. Invalid FID. (UID: {0}, TID: {1}, FID: {2})", header.UID, header.TID, subcommand.FID);
|
||||
header.Status = NTStatus.STATUS_INVALID_HANDLE;
|
||||
return null;
|
||||
}
|
||||
|
||||
header.Status = share.FileStore.SetSecurityInformation(openFile.Handle, subcommand.SecurityInformation, subcommand.SecurityDescriptor);
|
||||
if (header.Status != NTStatus.STATUS_SUCCESS)
|
||||
{
|
||||
state.LogToServer(Severity.Verbose, "SetSecurityInformation on '{0}{1}' failed. Security information: 0x{2}, NTStatus: {3}. (FID: {4})", share.Name, openFile.Path, subcommand.SecurityInformation.ToString("X"), header.Status, subcommand.FID);
|
||||
return null;
|
||||
}
|
||||
|
||||
state.LogToServer(Severity.Verbose, "SetSecurityInformation on '{0}{1}' succeeded. Security information: 0x{2}. (FID: {3})", share.Name, openFile.Path, subcommand.SecurityInformation.ToString("X"), subcommand.FID);
|
||||
NTTransactSetSecurityDescriptorResponse response = new NTTransactSetSecurityDescriptorResponse();
|
||||
return response;
|
||||
}
|
||||
|
||||
private static NTTransactQuerySecurityDescriptorResponse GetSubcommandResponse(SMB1Header header, uint maxDataCount, NTTransactQuerySecurityDescriptorRequest subcommand, ISMBShare share, SMB1ConnectionState state)
|
||||
{
|
||||
SMB1Session session = state.GetSession(header.UID);
|
||||
OpenFileObject openFile = session.GetOpenFileObject(subcommand.FID);
|
||||
if (openFile == null)
|
||||
{
|
||||
state.LogToServer(Severity.Verbose, "GetSecurityInformation failed. Invalid FID. (UID: {0}, TID: {1}, FID: {2})", header.UID, header.TID, subcommand.FID);
|
||||
header.Status = NTStatus.STATUS_INVALID_HANDLE;
|
||||
return null;
|
||||
}
|
||||
|
||||
int maxOutputLength = (int)maxDataCount;
|
||||
SecurityDescriptor securityDescriptor;
|
||||
header.Status = share.FileStore.GetSecurityInformation(out securityDescriptor, openFile.Handle, subcommand.SecurityInfoFields);
|
||||
if (header.Status != NTStatus.STATUS_SUCCESS)
|
||||
{
|
||||
state.LogToServer(Severity.Verbose, "GetSecurityInformation on '{0}{1}' failed. Security information: 0x{2}, NTStatus: {3}. (FID: {4})", share.Name, openFile.Path, subcommand.SecurityInfoFields.ToString("X"), header.Status, subcommand.FID);
|
||||
return null;
|
||||
}
|
||||
|
||||
NTTransactQuerySecurityDescriptorResponse response = new NTTransactQuerySecurityDescriptorResponse();
|
||||
response.LengthNeeded = (uint)securityDescriptor.Length;
|
||||
if (response.LengthNeeded <= maxDataCount)
|
||||
{
|
||||
state.LogToServer(Severity.Verbose, "GetSecurityInformation on '{0}{1}' succeeded. Security information: 0x{2}. (FID: {3})", share.Name, openFile.Path, subcommand.SecurityInfoFields.ToString("X"), subcommand.FID);
|
||||
response.SecurityDescriptor = securityDescriptor;
|
||||
}
|
||||
else
|
||||
{
|
||||
state.LogToServer(Severity.Verbose, "GetSecurityInformation on '{0}{1}' failed. Security information: 0x{2}, NTStatus: STATUS_BUFFER_TOO_SMALL. (FID: {3})", share.Name, openFile.Path, subcommand.SecurityInfoFields.ToString("X"), subcommand.FID);
|
||||
header.Status = NTStatus.STATUS_BUFFER_TOO_SMALL;
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
internal static List<SMB1Command> GetNTTransactResponse(byte[] responseSetup, byte[] responseParameters, byte[] responseData, int maxBufferSize)
|
||||
{
|
||||
List<SMB1Command> result = new List<SMB1Command>();
|
||||
|
|
|
@ -72,6 +72,44 @@ namespace SMBLibrary.Server.SMB2
|
|||
return response;
|
||||
}
|
||||
}
|
||||
else if (request.InfoType == InfoType.Security)
|
||||
{
|
||||
OpenFileObject openFile = session.GetOpenFileObject(request.FileId);
|
||||
if (openFile == null)
|
||||
{
|
||||
state.LogToServer(Severity.Verbose, "GetSecurityInformation failed. Invalid FileId. (SessionID: {0}, TreeID: {1}, FileId: {2})", request.Header.SessionID, request.Header.TreeID, request.FileId.Volatile);
|
||||
return new ErrorResponse(request.CommandName, NTStatus.STATUS_FILE_CLOSED);
|
||||
}
|
||||
|
||||
if (share is FileSystemShare)
|
||||
{
|
||||
if (!((FileSystemShare)share).HasReadAccess(session.SecurityContext, openFile.Path))
|
||||
{
|
||||
state.LogToServer(Severity.Verbose, "GetSecurityInformation on '{0}{1}' failed. User '{2}' was denied access.", share.Name, openFile.Path, session.UserName);
|
||||
return new ErrorResponse(request.CommandName, NTStatus.STATUS_ACCESS_DENIED);
|
||||
}
|
||||
}
|
||||
|
||||
SecurityDescriptor securityDescriptor;
|
||||
NTStatus queryStatus = share.FileStore.GetSecurityInformation(out securityDescriptor, openFile.Handle, request.SecurityInformation);
|
||||
if (queryStatus != NTStatus.STATUS_SUCCESS)
|
||||
{
|
||||
state.LogToServer(Severity.Verbose, "GetSecurityInformation on '{0}{1}' failed. Security information: 0x{2}, NTStatus: {3}. (FileId: {4})", share.Name, openFile.Path, request.SecurityInformation.ToString("X"), queryStatus, request.FileId.Volatile);
|
||||
return new ErrorResponse(request.CommandName, queryStatus);
|
||||
}
|
||||
|
||||
if (securityDescriptor.Length > request.OutputBufferLength)
|
||||
{
|
||||
state.LogToServer(Severity.Information, "GetSecurityInformation on '{0}{1}' failed. Security information: 0x{2}, NTStatus: STATUS_BUFFER_TOO_SMALL. (FileId: {3})", share.Name, openFile.Path, request.SecurityInformation.ToString("X"), request.FileId.Volatile);
|
||||
byte[] errorData = LittleEndianConverter.GetBytes((uint)securityDescriptor.Length);
|
||||
return new ErrorResponse(request.CommandName, NTStatus.STATUS_BUFFER_TOO_SMALL, errorData);
|
||||
}
|
||||
|
||||
state.LogToServer(Severity.Information, "GetSecurityInformation on '{0}{1}' succeeded. Security information: 0x{2}. (FileId: {3})", share.Name, openFile.Path, request.SecurityInformation.ToString("X"), request.FileId.Volatile);
|
||||
QueryInfoResponse response = new QueryInfoResponse();
|
||||
response.SetSecurityInformation(securityDescriptor);
|
||||
return response;
|
||||
}
|
||||
return new ErrorResponse(request.CommandName, NTStatus.STATUS_NOT_SUPPORTED);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,9 +17,10 @@ namespace SMBLibrary.Server.SMB2
|
|||
internal static SMB2Command GetSetInfoResponse(SetInfoRequest request, ISMBShare share, SMB2ConnectionState state)
|
||||
{
|
||||
SMB2Session session = state.GetSession(request.Header.SessionID);
|
||||
if (request.InfoType == InfoType.File)
|
||||
OpenFileObject openFile = null;
|
||||
if (request.InfoType == InfoType.File || request.InfoType == InfoType.Security)
|
||||
{
|
||||
OpenFileObject openFile = session.GetOpenFileObject(request.FileId);
|
||||
openFile = session.GetOpenFileObject(request.FileId);
|
||||
if (openFile == null)
|
||||
{
|
||||
state.LogToServer(Severity.Verbose, "SetFileInformation failed. Invalid FileId. (SessionID: {0}, TreeID: {1}, FileId: {2})", request.Header.SessionID, request.Header.TreeID, request.FileId.Volatile);
|
||||
|
@ -34,7 +35,10 @@ namespace SMBLibrary.Server.SMB2
|
|||
return new ErrorResponse(request.CommandName, NTStatus.STATUS_ACCESS_DENIED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (request.InfoType == InfoType.File)
|
||||
{
|
||||
FileInformation information;
|
||||
try
|
||||
{
|
||||
|
@ -93,6 +97,29 @@ namespace SMBLibrary.Server.SMB2
|
|||
}
|
||||
return new SetInfoResponse();
|
||||
}
|
||||
else if (request.InfoType == InfoType.Security)
|
||||
{
|
||||
SecurityDescriptor securityDescriptor;
|
||||
try
|
||||
{
|
||||
securityDescriptor = new SecurityDescriptor(request.Buffer, 0);
|
||||
}
|
||||
catch
|
||||
{
|
||||
state.LogToServer(Severity.Verbose, "SetSecurityInformation on '{0}{1}' failed. NTStatus: STATUS_INVALID_PARAMETER.", share.Name, openFile.Path);
|
||||
return new ErrorResponse(request.CommandName, NTStatus.STATUS_INVALID_PARAMETER);
|
||||
}
|
||||
|
||||
NTStatus status = share.FileStore.SetSecurityInformation(openFile, request.SecurityInformation, securityDescriptor);
|
||||
if (status != NTStatus.STATUS_SUCCESS)
|
||||
{
|
||||
state.LogToServer(Severity.Verbose, "SetSecurityInformation on '{0}{1}' failed. Security information: 0x{2}, NTStatus: {3}. (FileId: {4})", share.Name, openFile.Path, request.SecurityInformation.ToString("X"), status, request.FileId.Volatile);
|
||||
return new ErrorResponse(request.CommandName, status);
|
||||
}
|
||||
|
||||
state.LogToServer(Severity.Information, "SetSecurityInformation on '{0}{1}' succeeded. Security information: 0x{2}. (FileId: {3})", share.Name, openFile.Path, request.SecurityInformation.ToString("X"), request.FileId.Volatile);
|
||||
return new SetInfoResponse();
|
||||
}
|
||||
return new ErrorResponse(request.CommandName, NTStatus.STATUS_NOT_SUPPORTED);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue