FLAG_CASELESS_PATHNAMES/SMBFLG_CASELESS in set_current_service()

Jeremy Allison jra at samba.org
Wed Jun 13 16:30:54 UTC 2018


On Wed, Jun 13, 2018 at 10:17:31AM +0200, Stefan Metzmacher wrote:
> Hi Jeremy,
> hi Steve,
> 
> I'm wondering about the mess regarding conn->case_sensitive we have in
> set_current_service(). Is this really needed?

I hope not. I'd really like to get rid of it.

> Windows servers ignore FLAG_CASELESS_PATHNAMES completely,
> but we do some magic just for smbclient and cifs.ko.
> Only [lib]smbclient supports changing the flag on a per request basis,
> but is it really used in practice?

No.

> Can't we just set conn->case_sensitive based on, smb1 unix extension
> being used on the share?

Yes, I think so.

> Does it really make sense to have an 'case sensitive' smb.conf option?
> Do we really want to have conn->case_sensitive = true for non-unix
> extensions clients?

In theory Windows can support this mode (you have to set
a registry switch and reboot).

https://blogs.msdn.microsoft.com/commandline/2018/02/28/per-directory-case-sensitivity-and-wsl/

"Case sensitivity in Windows

The Windows NT family of operating systems (including Windows 10) has
always had the ability to perform case sensitive file system operations.
Applications can pass the FILE_FLAG_POSIX_SEMANTICS flag to the CreateFile
API to indicate that they want the path to be treated as case sensitive.
However, for compatibility reasons, there is a global registry key that
overrides this behavior; when this key is set, all file operations are
case insensitive, even when the FILE_FLAG_POSIX_SEMANTICS flag is
specified. Since Windows XP, this has been the default."

In practice no one ever does this (changes the registry key).

> Do we really need a 'nocase'/'ignorecase' mount option?
> 
> In libsmbclient it seems that SMBC_server_internal() will
> use cli_get_fs_attr_info() and set may fill in
> FILE_CASE_SENSITIVE_SEARCH if the server supports it
> (samba does).
> 
> To me it seems that smbclient and libsmbclient behave differently,
> because smbclient doesn't use SMBC_server[_internal]()
> and doesn't call cli_get_fs_attr_info().
> 
> smbclient has the "case_sensitive" operation to toggle
> FILE_CASE_SENSITIVE_SEARCH, which later leads to
> FLAG_CASELESS_PATHNAMES=0.
> 
> This makes it really difficult to progress on my impersonation patches,
> because we don't have the per request FLAG_CASELESS_PATHNAMES available
> when we restore the impersonation based on just the connection/vuid.

Yes, I can believe this is all muddled up, as in SMB1
there are many pathname-based operations - this is what
FLAG_CASELESS_PATHNAMES in an SMB1 request is supposed
to be for. Without the registry key set I'm guessing Windows
servers just ignore it (would be interesting to know if
they ignore it even with the registry key sey).

Here's what we currently do in the server code:

 132         /*
 133          * Obey the client case sensitivity requests - only for clients that
 134          * support it. */
 135         switch (lp_case_sensitive(snum)) {
 136         case Auto:
 137                 /*
 138                  * We need this uglyness due to DOS/Win9x clients that lie
 139                  * about case insensitivity. */
 140                 ra_type = get_remote_arch();
 141                 if (conn->sconn->using_smb2) {
 142                         conn->case_sensitive = false;
 143                 } else if ((ra_type != RA_SAMBA) && (ra_type != RA_CIFSFS)) {
 144                         /*
 145                          * Client can't support per-packet case sensitive
 146                          * pathnames. */
 147                         conn->case_sensitive = false;
 148                 } else {
 149                         conn->case_sensitive =
 150                                         !(flags & FLAG_CASELESS_PATHNAMES);
 151                 }
 152         break;
 153         case True:
 154                 conn->case_sensitive = true;
 155                 break;
 156         default:
 157                 conn->case_sensitive = false;
 158                 break;
 159         }

If we decide to ignore FLAG_CASELESS_PATHNAMES (which I'm in favor
of) then we can ditch the whole lp_case_sensitive(snum) paths and
just say - Windows opens (SMB1 & SMB2+) means case insensitive unless
FILE_FLAG_POSIX_SEMANTICS set on SMB2_Create or SMB1 NTCreate request.

POSIX opens (SMB1 global switch or SMB3 POSIX create context)
always mean case sensitive.

> Can this all be done by FILE_FLAG_POSIX_SEMANTICS/ATTR_POSIX_SEMANTICS?
> Where we also have req->posix_pathnames and UCF_POSIX_PATHNAMES?

Yeah, I think so - see above.

> Any ideas how to move forward here?

Does my plan work ? The only issues I can see are when we're
running on a Linux system that actually *has* a case-insensitive
filesystem underneath (XFS or ZFS mounted in case-insensitive mode).

We have 2 cases:

1). Hide case-sensitivity or case-insensitivity of underlying UNIX
filesystem (always expose case-insensitive semantics to SMB client). This
is the normal SMB1/2/3 case for Windows and Mac clients.

2). Expose case-sensitivity or case-insensitivity of underlying UNIX
filesystem (SMB client sees unfiltered view of mounted filesystem).
This is the SMB1-posix extensions, SMB3+-posix extensions view.

When a client sends FILE_FLAG_POSIX_SEMANTICS in a Windows-style
open, do we want to select case #1 (as Windows does without
registry key change) ? Or do we want to select case #2 (which
I think we do at present in smbd) ?

Feel free to call and discuss if this is confusing. I'll
hapily review patches that remove 'conn->case_sensitive'.

I think we need to keep the case-folding code in incoming
pathnames (as this helps a *lot* with large directory optimizations
in the exposing Windows case insensitivity on underlying
UNIX case sensitive filesystems code paths), but these
can be done inside filename_convert without needing
to flip state back and forth on impersonation.

Cheers,

	Jeremy.



More information about the samba-technical mailing list