FLAG_CASELESS_PATHNAMES/SMBFLG_CASELESS in set_current_service()

Jeremy Allison jra at samba.org
Wed Jun 13 22:15:16 UTC 2018


On Wed, Jun 13, 2018 at 09:30:54PM +0200, Stefan Metzmacher wrote:
> Am 13.06.2018 um 18:30 schrieb Jeremy Allison via samba-technical:
> > 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.
> 
> So can we just remove this completely without breaking any existing
> setups? So we would also completely ignore FLAG_CASELESS_PATHNAMES
> and also remove the "case sensitive" option. Or just let that
> option only control the return of FILE_CASE_SENSITIVE_SEARCH.

I think so - at least we need to ensure it passes all
existing tests of course. Having it affect FILE_CASE_SENSITIVE_SEARCH
file system attribute return seems to be the right option.

> >> 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.
> 
> So we can really remove smbc_setOptionCaseSensitive() ?
> And the "case_sensitive" smbclient command?

Yes, I think we can.

> And also don't look at FILE_CASE_SENSITIVE_SEARCH anymore in the client.

Yep.

> >> Can't we just set conn->case_sensitive based on, smb1 unix extension
> >> being used on the share?
> 
> > Yes, I think so.
> 
> Similar to req->posix_pathnames?

Yes.

> >> 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).
> 
> Ok, I thougt FILE_FLAG_POSIX_SEMANTICS would be part of the unix extensions.

It's being used internally to specify a POSIX open to
the VFS, and currently inside SMB1 NTCreateX if the client sets it
we change our case semantics, then strip it out of the
passed in flags.

See the code in source3/smbd/nttrans.c:

 530         if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
 531                 case_state = set_posix_case_semantics(ctx, conn);
 532                 if (!case_state) {
 533                         reply_nterror(req, NT_STATUS_NO_MEMORY);
 534                         goto out;
 535                 }
 536         }
...
 559         /*
 560          * Bug #6898 - clients using Windows opens should
 561          * never be able to set this attribute into the
 562          * VFS.
 563          */
 564         file_attributes &= ~FILE_FLAG_POSIX_SEMANTICS;

So currently it does change server behavior if set by
the client, but this is not what Windows does.

I think we can probably just strip it out if sent from
the client, and rely on the SMB1 code paths that forcibly
add it on a POSIX open/mkdir request, and my new code paths
that forcibly add it on receiving a SMB3+ posix open context.

e.g. remove the lines 530-536 above.

> >> 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).
> 
> [MS-CIFS] claims that it's completely ignored by windows.
> 
> <26> Section 2.2.3.1: This bit is ignored by Windows systems, which
> always handle pathnames as
> case-insensitive.

Yes, we should ignore it too and remove from all
server code I think.

> > 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.
> 
> So we remove the whole section?

Yes.

> > POSIX opens (SMB1 global switch or SMB3 POSIX create context)
> > always mean case sensitive.
> 
> Good.
> 
> >> 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).
> 
> Then the filesystem should not announce FILE_CASE_SENSITIVE_SEARCH.

Yes, that makes sense. The client can then know that
even if it asks for POSIX extensions it will not get
case-sensitive pathnames.

> > 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) ?
> 
> If possible I'd ignore that unless it breaks existing setups
> and that's where I'm unsure.

You mean select option #1 above ?

> > 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.
> 
> Sounds good.
> 
> Today worked on the attached patches in order to clean up the
> existing code and set_current_user_info and set_current_service
> to change_to_user().
> 
> But adding the chdir_current_service seems to fail.
> Any idea? It fails with ACCESS_DENIED, but I didn't have time to look
> at details I'll do that tomorrow.

I'll try and take a look later this week if you
don't figure it out first.

Jeremy.



More information about the samba-technical mailing list