s3: smbd : SMB2 - fix SMB2_SEARCH when searching non wildcard string with a case...
authorJeremy Allison <jra@samba.org>
Tue, 10 Jun 2014 22:58:15 +0000 (15:58 -0700)
committerJeremy Allison <jra@samba.org>
Wed, 11 Jun 2014 16:47:14 +0000 (18:47 +0200)
We need to go through filename_convert() in order for the filename
canonicalization to be done on a non-wildcard search string (as is
done in the SMB1 findfirst code path).

Fixes Bug #10650 - "case sensitive = True" option doesn't work with "max protocol = SMB2" or higher in large directories.

https://bugzilla.samba.org/show_bug.cgi?id=10650

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Volker Lendecke <Volker.Lendecke@SerNet.DE>
Reviewed-by: Ira Cooper <ira@samba.org>
source3/smbd/smb2_find.c

index d66c093a8824cfe54aad0666111130877b962e4c..e9e0542bc268c0abbed05ac90c54d0e4e9cd2ddd 100644 (file)
@@ -224,6 +224,7 @@ static struct tevent_req *smbd_smb2_find_send(TALLOC_CTX *mem_ctx,
        uint32_t dirtype = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DIRECTORY;
        bool dont_descend = false;
        bool ask_sharemode = true;
+       bool wcard_has_wild;
        struct tm tm;
        char *p;
 
@@ -323,11 +324,41 @@ static struct tevent_req *smbd_smb2_find_send(TALLOC_CTX *mem_ctx,
                dptr_CloseDir(fsp);
        }
 
-       if (fsp->dptr == NULL) {
-               bool wcard_has_wild;
+       wcard_has_wild = ms_has_wild(in_file_name);
 
-               wcard_has_wild = ms_has_wild(in_file_name);
+       /* Ensure we've canonicalized any search path if not a wildcard. */
+       if (!wcard_has_wild) {
+               struct smb_filename *smb_fname = NULL;
+               const char *fullpath;
 
+               if (ISDOT(fsp->fsp_name->base_name)) {
+                       fullpath = in_file_name;
+               } else {
+                       fullpath = talloc_asprintf(state,
+                                       "%s/%s",
+                                       fsp->fsp_name->base_name,
+                                       in_file_name);
+               }
+               if (tevent_req_nomem(fullpath, req)) {
+                       return tevent_req_post(req, ev);
+               }
+               status = filename_convert(state,
+                               conn,
+                               false, /* Not a DFS path. */
+                               fullpath,
+                               UCF_SAVE_LCOMP | UCF_ALWAYS_ALLOW_WCARD_LCOMP,
+                               &wcard_has_wild,
+                               &smb_fname);
+
+               if (!NT_STATUS_IS_OK(status)) {
+                       tevent_req_nterror(req, status);
+                       return tevent_req_post(req, ev);
+               }
+
+               in_file_name = smb_fname->original_lcomp;
+       }
+
+       if (fsp->dptr == NULL) {
                status = dptr_create(conn,
                                     NULL, /* req */
                                     fsp,