[PATCH] Version 2 - Additional fix and test for bug #12899 - smbclient "setmode" no longer works to clear attribute bits due to dialect upgrade

Jeremy Allison jra at samba.org
Sat Jul 15 05:46:15 UTC 2017


On Fri, Jul 14, 2017 at 05:39:41PM -0700, Jeremy Allison via samba-technical wrote:
> OK - figured it out.
> 
> Against Windows
> 
> -------------------------------------------------------------------
> Over SMB2 - doing a SMB2_CREATE/SET_FILE_BASIC_INFORMATION/CLOSE
> 
> if attr == 0 - all attributes are left alone.
> if attr == 0x80 (FILE_ATTRIBUTE_NORMAL) - all attributes are cleared (server returns FILE_ATTRIBUTE_NORMAL on query).
> 
> Over SMB1 - using SMB1setatr (0x9):
> 
> if attr == 0 - all attributes are cleared (server returns FILE_ATTRIBUTE_NORMAL on query).
> if attr == 0x80 (FILE_ATTRIBUTE_NORMAL) - all attributes are left alone.
> -------------------------------------------------------------------
> 
> Completely and utterly insane, but there you go and I
> have the wireshark traces to prove it :-).
> 
> What that means is Steve's original patch is incorrect
> (sorry for the +1 review, all I can say is it looked
> correct at the time but further testing proved otherwise :-).
> 
> Yay for more tests :-).
> 
> Most of our existing code uses the API:
> 
> cli_setatr(cli1, fname, 0, 0);
> 
> to mean clear all attributes. So what I think I'm going to
> do is revert Steve's patch and then change cli_smb2_setatr()
> to change attr == 0 to map attr to FILE_ATTRIBUTE_NORMAL
> internally for SMB2. That's actually following the intent.
> 
> It does mean there's no way to use '0' in SMB2 to mean
> 'leave this alone', but I know of no use cases of that
> in our existing code.

Thinking about this on the drive home, it means
that we just change the SMB2 code to match SMB1.

This means:

cli_setatr(cli, fname, FILE_ATTRIBUTE_NORMAL, 0);

specifies "no change" for both SMB1 and SMB2, and

cli_setatr(cli, fname, FILE_ATTRIBUTE_NORMAL, 0);

means "clear all attributes" for both SMB1 and SMB2.

That's the way the current SMB1-specific cli_setatr()
code works, so this fix swaps the semantics for
SMB2 to keep the existing libsmbclient ABI for callers.

Essentially inside cli_smb2_setatr() I do:

if (attr == 0) {
	attr = FILE_ATTRIBUTE_NORMAL;
} else if (attr == FILE_ATTRIBUTE_NORMAL;
	attr = 0;
}

to swap the meaning to the SMB1 semantics (with
appropriate comments explaining this of course).

That keeps the existing ABI and gives no change
to any cli_setatr() or libsmbclient callers. After
reverting Steve's patch and putting this in place
the new test patch will excercise this perfectly
as a regression test.

I'll also look into adding a source4/torture test
for the insane SMB1/SMB2 semantics to make sure
we test the server correctly without going through
the cli_setatr() interface.

Sounds like a plan - should get this done on Monday !

Jeremy.



More information about the samba-technical mailing list