Closed vishwas-trivedi closed 5 years ago
Hi, STATUS_USER_SESSION_DELETED means that the SessionID being used by the client is invalid. The SessionID is established during SESSION_SETUP, the process is defined in [MS-SMB2] 3.3.5.5.1 Authenticating a New Session: "A session object MUST be allocated for this request. [..] The SMB2 server MUST reserve -1 as an invalid SessionId and 0 as a SessionId for which no session exists."
When looking at the packet capture, it seems to me that you are using a server that does not conform to the specifications: upon receiving the first SESSION_SETUP request, your server return SESSION_SETUP response with SessionID set to 0!
(Only the second SESSION_SETUP response returned by your server contains a valid SessionID, but the specification says that the first one should already include it and that's what the client uses)
IIRC this was a bug in earlier versions of SAMBA and it was later fixed, you can either update your server to match the specifications, or you can modify the client to match this buggy behavior by moving line 162 in SMB2Client.cs to after the second response is received.
And also, ListShares will return the list of shares, the client cannot create a new share, it can only create a folder inside a share.
@TalAloni Thank you very much for the response. As I don't have control over the SMB server, I will try modifying SMB2Client's code.
And also, ListShares will return the list of shares, the client cannot create a new share, it can only create a folder inside a share.
I would be really really grateful if you could share sample code for getting list of folders from share and create and delete folder from share. (ex. : \172.21.1.41\Data_test$)
Regards, Vishwas
You will find a few samples here: https://github.com/TalAloni/SMBLibrary/issues/9
@TalAloni Thank you! I will try to use those samples.
Sorry to ask again, but could you please share any official link or any document to the bug that that you mentioned.
Regards, Vishwas
I'm not able to locate it, is this indeed a SAMBA server?
The official MS-SMB2 documentation: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/5606ad47-5ee0-437a-817e-70c366052962
@TalAloni
It probably is, but I'm not sure as I don't have access to it. But I was able to get shares list after changing the code that you suggested.
Just wanted to confirm what I understood : To login, client sends 2 requests :
Now, according to the protocol both requests should contain session ID. But due to this bug on SMB server, negotiation request(1) has session ID 0 instead of actual session ID. So to fix it on client side(in my case) we have to take session ID from authentication request.
Is this understanding correct??
I will also confirm the official documentation just in case. Regards, Vishwas
Not exactly, first the client send a negotiation request and get a negotiation response from the server, then the client send the first authentication request and get an initial authentication response from the server, then the client send another authentication request and get a final authentication response from the server. The first authentication response (SESSION_SETUP response) should already contain the SessionID. On your server the first SESSION_SETUP response has SessionID set to 0.
@TalAloni Okay, understood what you are saying but SMB2Client.Login() calls TrySendCommand() 2 times, 1st time with negotiateMessage(Line 149) and 2nd time with authenticateMessage(Line 165).
Both the calls are made with SMB2CommandName.SessionSetup (Line 151 and Line 167)
Am I misunderstanding the code somewhere?
@TalAloni
Also, I checked the sample code but I could not find any sample to get directory list. Is there any way I could get the directory list, create or delete directory?
That example is for creating file I believe.
Regards, Vishwas
Don't confuse between a NEGOTIATE request and a SESSION_SETUP request containing a negotiate message, those are two different things. the first negotiate the protocol and the second negotiate the authentication. The two SESSION_SETUP requests are sent in Line 150 and line 166 (in SMB2Client.cs)
To get a directory list you use QueryDirectory, the sample code contain an example. Creating a directory is very similar to creating a file, a single parameter needs to be changed, you'll figure it out.
To delete a file / directory you use SetFileInformation and set the FileDispositionInformation.
@TalAloni Thank you for the response!
To delete a file / directory you use SetFileInformation and set the FileDispositionInformation.
I was successfully able to create the folder and display the list of folder but I could not understand how to delete folder. I'm tried following code to delete a folder :
bool DeleteFolder(SMB2Client client, string folderName)
{
var res = false;
// SUCCESS
if (client.TreeConnect("Data_test$", out var status) is SMB2FileStore fileStore)
{
status = fileStore.CreateFile(out var handle, out var fs, folderName,
AccessMask.SYNCHRONIZE | (AccessMask)DirectoryAccessMask.GENERIC_READ | (AccessMask)DirectoryAccessMask.DELETE , 0,
ShareAccess.Read | ShareAccess.Delete, CreateDisposition.FILE_OPEN | CreateDisposition.FILE_CREATE,
CreateOptions.FILE_SYNCHRONOUS_IO_NONALERT | CreateOptions.FILE_DIRECTORY_FILE , null);
if (status == NTStatus.STATUS_SUCCESS)
{
// FAILURE : STATUS_NOT_SUPPORTED
status = fileStore.GetFileInformation(out var data, handle, FileInformationClass.FileDispositionInformation);
fileStore.CloseFile(handle);
if (status == NTStatus.STATUS_SUCCESS)
{
status = fileStore.SetFileInformation(handle, data);
}
}
}
if (status == NTStatus.STATUS_SUCCESS)
{
res = true;
}
Console.WriteLine("----------Delete Folder----------");
Console.WriteLine("NT Status : {0}", status.ToString());
Console.WriteLine("----------Delete Folder----------");
return res = true;
}
I don't know what to set in FileDispositionInformation, so I tried reading FileDisposeInformation from server but I'm getting STATUS_NOT_SUPPORTED response.
Am I doing something wrong ? Is there any other way to delete the folder?
Regards, Vishwas Trivedi
There are 3 steps to deleting a file:
You should not use GetFileInformation with FileDispositionInformation! it's invalid.
@TalAloni
Thank you for the response. I tried what you suggested and now my code looks like this :
static void DeleteFolder(SMB2Client client, string folderName)
{
if (client.TreeConnect("Data_test$", out var status) is SMB2FileStore fileStore)
{
status = fileStore.CreateFile(out var handle, out var fs, folderName,
AccessMask.SYNCHRONIZE | (AccessMask)DirectoryAccessMask.GENERIC_ALL, 0,
ShareAccess.Read | ShareAccess.Delete, CreateDisposition.FILE_OPEN | CreateDisposition.FILE_CREATE,
CreateOptions.FILE_SYNCHRONOUS_IO_NONALERT | CreateOptions.FILE_DIRECTORY_FILE, null);
if (status == NTStatus.STATUS_SUCCESS)
{
var disppose = new FileDispositionInformation();
disppose.DeletePending = true;
status = fileStore.SetFileInformation(handle, disppose);
fileStore.CloseFile(handle);
}
}
Console.WriteLine("----------Delete Folder----------");
Console.WriteLine("NT Status : {0}", status.ToString());
Console.WriteLine("----------Delete Folder----------");
}
But I'm getting NT Status : STATUS_SHARING_VIOLATION from CreateFile()(I was able to delete in debug mode only one time).
Am I doing it wrong, I have given DirectoryAccessMask.GENERIC_ALL with CreateDisposition.FILE_OPEN | CreateDisposition.FILE_CREATE?
Regards, Vishwas Trivedi
@TalAloni
Sorry for the trouble, it was a stupid mistake! I was not closing the file after creation. Thank you for the help!
Regards, Vishwas Trivedi
@vishwas-trivedi Hi, can you show me the code that create a folder, please?
Same code as creating a file but with FILE_DIRECTORY_FILE flag, please don't hijack a closed issue.
Oh, Sorry. Thanks.
Hello @TalAloni,
I'm trying to get the list of shared folders from SMB server using following code but I'm getting "STATUS_USER_SESSION_DELETED" from ListShares() :
What I'm trying to do here is get the list of folders from SMB and if folder does not exists then create a new one.
Actual path from where I'm want to get directory list is as following : \172.21.1.41\Data_test$\
I've also attached the WireShark packet capture and I'm using the latest version(1.3.7.0). smbSpecific_20190419_1.zip Please confirm.
Any help would be much appreciated. Regards.