From 3432aafbf86b4d3a559838d81b3ebc039e72a412 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra@samba.org>
Date: Tue, 10 Jun 2014 14:41:45 -0700
Subject: [PATCH 1/2] s3: smbd - SMB[2|3]. Ensure a \ or / can't be found
 anywhere in a search path, not just at the start.

Signed-off-by: Jeremy Allison <jra@samba.org>
---
 source3/smbd/smb2_find.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/source3/smbd/smb2_find.c b/source3/smbd/smb2_find.c
index 59e5b66..b0ab7a8 100644
--- a/source3/smbd/smb2_find.c
+++ b/source3/smbd/smb2_find.c
@@ -255,11 +255,11 @@ static struct tevent_req *smbd_smb2_find_send(TALLOC_CTX *mem_ctx,
 		tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_INVALID);
 		return tevent_req_post(req, ev);
 	}
-	if (strcmp(in_file_name, "\\") == 0) {
+	if (strchr_m(in_file_name, '\\') != NULL) {
 		tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_INVALID);
 		return tevent_req_post(req, ev);
 	}
-	if (strcmp(in_file_name, "/") == 0) {
+	if (strchr_m(in_file_name, '/') != NULL) {
 		tevent_req_nterror(req, NT_STATUS_OBJECT_NAME_INVALID);
 		return tevent_req_post(req, ev);
 	}
-- 
1.9.3


From 190d0f39bb400a373c8f4d6847e2980c0df8da2b Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra@samba.org>
Date: Tue, 10 Jun 2014 15:58:15 -0700
Subject: [PATCH 2/2] s3: smbd : SMB2 - fix SMB2_SEARCH when searching non
 wildcard string with a case-canonicalized share.

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>
---
 source3/smbd/smb2_find.c | 38 +++++++++++++++++++++++++++++++++++---
 1 file changed, 35 insertions(+), 3 deletions(-)

diff --git a/source3/smbd/smb2_find.c b/source3/smbd/smb2_find.c
index b0ab7a8..6fe6545 100644
--- a/source3/smbd/smb2_find.c
+++ b/source3/smbd/smb2_find.c
@@ -229,6 +229,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;
 
 	req = tevent_req_create(mem_ctx, &state,
 				struct smbd_smb2_find_state);
@@ -303,16 +304,47 @@ static struct tevent_req *smbd_smb2_find_send(TALLOC_CTX *mem_ctx,
 		dptr_CloseDir(fsp);
 	}
 
+	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) {
-		bool wcard_has_wild;
 
 		if (!(fsp->access_mask & SEC_DIR_LIST)) {
 			tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
 			return tevent_req_post(req, ev);
 		}
 
-		wcard_has_wild = ms_has_wild(in_file_name);
-
 		status = dptr_create(conn,
 				     fsp,
 				     fsp->fsp_name->base_name,
-- 
1.9.3

