mirror of
https://github.com/TalAloni/SMBLibrary.git
synced 2025-07-24 02:00:27 +02:00
SMBServer: SMB2: Improved handling of compunded related requests
This commit is contained in:
parent
73b27366c5
commit
df58913372
1 changed files with 100 additions and 4 deletions
|
@ -19,20 +19,51 @@ namespace SMBLibrary.Server
|
|||
{
|
||||
List<SMB2Command> responseChain = new List<SMB2Command>();
|
||||
FileID? fileID = null;
|
||||
NTStatus? fileIDStatus = null;
|
||||
foreach (SMB2Command request in requestChain)
|
||||
{
|
||||
if (request.Header.IsRelatedOperations && fileID.HasValue)
|
||||
SMB2Command response;
|
||||
if (request.Header.IsRelatedOperations && RequestContainsFileID(request))
|
||||
{
|
||||
SetRequestFileID(request, fileID.Value);
|
||||
if (fileIDStatus != null && fileIDStatus != NTStatus.STATUS_SUCCESS && fileIDStatus != NTStatus.STATUS_BUFFER_OVERFLOW)
|
||||
{
|
||||
// [MS-SMB2] When the current request requires a FileId and the previous request either contains
|
||||
// or generates a FileId, if the previous request fails with an error, the server SHOULD fail the
|
||||
// current request with the same error code returned by the previous request.
|
||||
state.LogToServer(Severity.Verbose, "Compunded related request {0} failed because FileId generation failed.", request.CommandName);
|
||||
response = new ErrorResponse(request.CommandName, fileIDStatus.Value);
|
||||
}
|
||||
else if (fileID.HasValue)
|
||||
{
|
||||
SetRequestFileID(request, fileID.Value);
|
||||
response = ProcessSMB2Command(request, ref state);
|
||||
}
|
||||
else
|
||||
{
|
||||
// [MS-SMB2] When the current request requires a FileId, and if the previous request neither contains
|
||||
// nor generates a FileId, the server MUST fail the compounded request with STATUS_INVALID_PARAMETER.
|
||||
state.LogToServer(Severity.Verbose, "Compunded related request {0} failed, the previous request neither contains nor generates a FileId.", request.CommandName);
|
||||
response = new ErrorResponse(request.CommandName, NTStatus.STATUS_INVALID_PARAMETER);
|
||||
}
|
||||
}
|
||||
SMB2Command response = ProcessSMB2Command(request, ref state);
|
||||
else
|
||||
{
|
||||
fileID = GetRequestFileID(request);
|
||||
response = ProcessSMB2Command(request, ref state);
|
||||
}
|
||||
|
||||
if (response != null)
|
||||
{
|
||||
UpdateSMB2Header(response, request, state);
|
||||
responseChain.Add(response);
|
||||
if (!request.Header.IsRelatedOperations)
|
||||
if (GeneratesFileID(response))
|
||||
{
|
||||
fileID = GetResponseFileID(response);
|
||||
fileIDStatus = response.Header.Status;
|
||||
}
|
||||
else if (RequestContainsFileID(request))
|
||||
{
|
||||
fileIDStatus = response.Header.Status;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -250,6 +281,65 @@ namespace SMBLibrary.Server
|
|||
response.Header.IsSigned = (request.Header.IsSigned || signingRequired) && !isInterimResponse;
|
||||
}
|
||||
|
||||
private static bool RequestContainsFileID(SMB2Command command)
|
||||
{
|
||||
return (command is ChangeNotifyRequest ||
|
||||
command is CloseRequest ||
|
||||
command is FlushRequest ||
|
||||
command is IOCtlRequest ||
|
||||
command is LockRequest ||
|
||||
command is QueryDirectoryRequest ||
|
||||
command is QueryInfoRequest ||
|
||||
command is ReadRequest ||
|
||||
command is SetInfoRequest ||
|
||||
command is WriteRequest);
|
||||
}
|
||||
|
||||
private static FileID? GetRequestFileID(SMB2Command command)
|
||||
{
|
||||
if (command is ChangeNotifyRequest)
|
||||
{
|
||||
return ((ChangeNotifyRequest)command).FileId;
|
||||
}
|
||||
else if (command is CloseRequest)
|
||||
{
|
||||
return ((CloseRequest)command).FileId;
|
||||
}
|
||||
else if (command is FlushRequest)
|
||||
{
|
||||
return ((FlushRequest)command).FileId;
|
||||
}
|
||||
else if (command is IOCtlRequest)
|
||||
{
|
||||
return ((IOCtlRequest)command).FileId;
|
||||
}
|
||||
else if (command is LockRequest)
|
||||
{
|
||||
return ((LockRequest)command).FileId;
|
||||
}
|
||||
else if (command is QueryDirectoryRequest)
|
||||
{
|
||||
return ((QueryDirectoryRequest)command).FileId;
|
||||
}
|
||||
else if (command is QueryInfoRequest)
|
||||
{
|
||||
return ((QueryInfoRequest)command).FileId;
|
||||
}
|
||||
else if (command is ReadRequest)
|
||||
{
|
||||
return ((ReadRequest)command).FileId;
|
||||
}
|
||||
else if (command is SetInfoRequest)
|
||||
{
|
||||
return ((SetInfoRequest)command).FileId;
|
||||
}
|
||||
else if (command is WriteRequest)
|
||||
{
|
||||
return ((WriteRequest)command).FileId;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void SetRequestFileID(SMB2Command command, FileID fileID)
|
||||
{
|
||||
if (command is ChangeNotifyRequest)
|
||||
|
@ -294,6 +384,12 @@ namespace SMBLibrary.Server
|
|||
}
|
||||
}
|
||||
|
||||
private static bool GeneratesFileID(SMB2Command command)
|
||||
{
|
||||
return (command.CommandName == SMB2CommandName.Create ||
|
||||
command.CommandName == SMB2CommandName.IOCtl);
|
||||
}
|
||||
|
||||
private static FileID? GetResponseFileID(SMB2Command command)
|
||||
{
|
||||
if (command is CreateResponse)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue