[cifs-protocol] [REG:117050715700170] SMB1 processing of FileRnameInfo

Bryan Burgin bburgin at microsoft.com
Wed May 17 20:09:34 UTC 2017


Concurrently, after shifting focus from the Win32 API question, I found our validation code on the server side.  We have code that " If there are any path separators in the name, then we do not support this operation."
Are you sure about " That means rename+replace in SMB1 is limited to dest being at the root of the share."?  It seems that if the CreateFile was against "dir\anotherdir\filename.txt" and you just included "newname.txt" in the tunneled rename, it would work.  In other words, all the path info is in the original CreateFile call.  Can you test that as I don't have the environment (an environment that can emit the request from a client)?

Bryan

-----Original Message-----
From: Uri Simchoni [mailto:uri at samba.org] 
Sent: Wednesday, May 17, 2017 1:01 PM
To: Bryan Burgin <bburgin at microsoft.com>
Cc: cifs-protocol at lists.samba.org; MSSolve Case Email <casemail at microsoft.com>
Subject: Re: [REG:117050715700170] SMB1 processing of FileRnameInfo

Back to my client code -
- Both smbclient and my modified smbtorture3 RENAME test use a leading '\' in file name. BTW, SMB2 and later, that leading '\' is cleared by the client library, that is - the application requests '\file'.
- When I remove the leading '\', it worked as you predicted.
- When there's a '\' anywhere in the dest file name, it doesn't work
(NT_STATUS_NOT_SUPPORTED) - not just leading. That means rename+replace in SMB1 is limited to dest being at the root of the share.

So to sum things up - it appears that SMB1 Windows server supports rename via pass-through FileRenameInfo only if the destination is at the root of the share, and destination specified without a leading '\'. It also appears that this is due to incomplete implementation.

Thanks for digging this up for me :)

Uri

On 05/17/2017 09:24 PM, Bryan Burgin wrote:
> From usermode using Win32 APIs on a Windows client, I believe it is impossible to create the transaction you're trying to emit on-the-wire.
> 
> I used your program and made one of my own, too.  When either of our programs calls SetFileInformationByHandle() it calls Win32Rename(), based on the info class FileRenameInfo.  Within Win32Rename(), it calls RtlDosPathNameToNtPathName_U_WithStatus() on the newname to do "NT path translation" that converts it to "\??\X:\NewFile.txt" -- regardless of how you specified it in your call (with a leading '\', with a leading 'X:\', with a leading 'X:' or just without any drive indication ("NewFile.txt").
> 
> All the above is done in usermode in kernelbase.dll bound to your process long before the request drops into the Kernel and eventually in our redirector that, which, as I indicated yesterday, sees the leading '\' and decides to do this old-school: delete NewFile (in case it's there), then call Rename.  There appears to be nothing you can do in your Win32 call that will protect your buffer from being translated before being passed to the redirector.  I investigated if there were raw NtXxxx or ZwXxxxx calls that could be made instead.  There are none for SetFileInformationByHandle.
> 
> Thus, we should abandon creating this traffic via Win32 APIs and concentrate on the call your client is making.  What happens if the NewFile does not already exist?  What happens if you don't have a leading '\', as I saw on your trace?  It does appear, from the message I sent yesterday that support for pass-through Rename on the server is limited.
> 
> Bryan
> 
> -----Original Message-----
> From: Bryan Burgin
> Sent: Tuesday, May 16, 2017 10:56 AM
> To: 'Uri Simchoni' <uri at samba.org>
> Cc: cifs-protocol at lists.samba.org; MSSolve Case Email 
> <casemail at microsoft.com>
> Subject: RE: [REG:117050715700170] SMB1 processing of FileRnameInfo
> 
> Hi, Uri,
> 
> I found where we service this call on our client-side redirector.  We have a note that the server-side is not completely implemented and that we will revert to the style you cite if RootDirectory is non-NULL or if a '\\' exists in the TargetName (FileName) -- essentially making the 'Rename' into a 'Move'.  In your trace, I see that you have a leading backslash.  While a leading backslash (and none others) would mean the rename is relative to where the file is presently (not a move) the code just looks for the presence of any backslashes.
> 
> Can you test this on your end and see if it changes your observation?  I will look at the code you provided, too.
> 
> Bryan
> 
> -----Original Message-----
> From: Uri Simchoni [mailto:uri at samba.org]
> Sent: Tuesday, May 9, 2017 9:01 PM
> To: Bryan Burgin <bburgin at microsoft.com>
> Cc: cifs-protocol at lists.samba.org; MSSolve Case Email 
> <casemail at microsoft.com>
> Subject: Re: [REG:117050715700170] SMB1 processing of FileRnameInfo
> 
> On 05/09/2017 09:38 PM, Bryan Burgin wrote:
>> After carefully reading your text, I won't need your program.
>> I'll see if there is a different way to make a client send the FileRenameInfo/Passthru command.
>> B.
>>
> FWIW, program attached.
> (notice that paths are hard-coded and files are assumed to be pre-existing).
> Thanks,
> Uri.
> 
>> -----Original Message-----
>> From: Bryan Burgin
>> Sent: Tuesday, May 9, 2017 8:54 AM
>> To: Uri Simchoni <uri at samba.org>
>> Cc: cifs-protocol at lists.samba.org; MSSolve Case Email 
>> <casemail at microsoft.com>
>> Subject: RE: [REG:117050715700170] SMB1 processing of FileRnameInfo
>>
>> Hi Uri,
>>
>> I can research this for you.  Let me look at the code.  Can you send me the source of your test program; that will save me the time of doing the same.
>>
>> Bryan



More information about the cifs-protocol mailing list