smbd_smb2_query_directory_send() passes smb_fname->original_lcomp, which will contain the mangled search pattern, to dptr_create().
One way or another, we should pass the unmangled name. From briefly checking all users of smb_fname->original_lcomp, I think we can just store the unmangled name in smb_fname->original_lcomp in unix_convert() rather then storing the original client passed one.
Not sure if SMB 1 has the same problem, still have to take a closer look.
Working on a fix...
Nice find Ralph. I'm pretty sure the SMB1 directory listing code will use the unmangled name - check the code inside:
which checks for the mangled name.
(In reply to Jeremy Allison from comment #1)
ah, sorry, this is actually not a problem in dptr_create() which basically just opens the dirfd, but probably smbd_dirptr_lanman2_match_fn() itself that is will only match mangled name *if the filesystem name needs mangling* but not if the filesystem name is eg just "foo" but the client passed the mangling result of "foo" to SMB2_FIND.
Gna, holy nastyness, I'll write a test so I can reproduce it. :)
Yes, been checking the codepaths and we don't cope with the 'mask' parameter to smbd_dirptr_lanman2_match_fn() being mangled.
I *hate* name mangling :-).
(In reply to Jeremy Allison from comment #3)
Then I guess we should move into the direction of gettting rid of it and make "mangled names = illegal" the default for 4.9.
I wish :-). Unfortunately that makes all non-Windows compatible names on the filesystem (i.e. any name with a ':') inaccessible for clients.
I don't think we can do that.
(In reply to Jeremy Allison from comment #5)
That's *exaclty* what "mangled names = illegal" is all about! From the manpage:
· illegal - does mangling for names with illegal NTFS
characters. This is the most sensible setting for
modern clients that don't use the shortname anymore.
Doh! Yeah, of course that makes sense. I didn't write that code so I forgot what setting it to "illegal" did :-).
smbd_dirptr_lanman2_match_fn() already covers the case that the SMB2_FIND request mask is a mangled name. The problem was only reproducible on a customer system with non-upstream modifications.
While it could be argued it makes sense to pass the unmangled name from the SMB2 layer to the lower layers to avoid mangling/unmangling again in the lower layer, I'm somewhat too scared what else might break with such a change... therefor leaving as is.