[PATCH] Fix bug #10650 - "case sensitive = True" option doesn't work with "max protocol = SMB2" or higher in large directories.
Volker Lendecke
Volker.Lendecke at SerNet.DE
Wed Jun 11 03:39:48 MDT 2014
Hi!
Attached find your patches with my r-b. Also find two
more-or-less cosmetic patches on top.
Please review and/or push!
Thanks,
Volker
On Tue, Jun 10, 2014 at 04:16:18PM -0700, Jeremy Allison wrote:
> Here's a fix for the SMB2/3 server when given a non-wildcard
> search path.
>
> For a non-wildcard string we need it to go through the
> filename_convert() function that takes care of name
> canonicalization and lookup in the same way as any
> other given pathname.
>
> This is the same way it's done in the old SMB1 trans2
> findfirst code.
>
> Please review and/or push if you're happy.
>
> Thanks !
>
> Jeremy.
> From c997a4a4a40f9f8f7755e60be783de106371caec Mon Sep 17 00:00:00 2001
> From: Jeremy Allison <jra at 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 at 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 3f779b8..d66c093 100644
> --- a/source3/smbd/smb2_find.c
> +++ b/source3/smbd/smb2_find.c
> @@ -252,11 +252,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);
> }
> --
> 2.0.0.526.g5318336
>
>
> From f5a1dde50b0328965c859c39a61b79cf88a363e7 Mon Sep 17 00:00:00 2001
> From: Jeremy Allison <jra at 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 at samba.org>
> ---
> source3/smbd/smb2_find.c | 37 ++++++++++++++++++++++++++++++++++---
> 1 file changed, 34 insertions(+), 3 deletions(-)
>
> diff --git a/source3/smbd/smb2_find.c b/source3/smbd/smb2_find.c
> index d66c093..e9e0542 100644
> --- a/source3/smbd/smb2_find.c
> +++ b/source3/smbd/smb2_find.c
> @@ -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,
> --
> 2.0.0.526.g5318336
>
--
SerNet GmbH, Bahnhofsallee 1b, 37081 Göttingen
phone: +49-551-370000-0, fax: +49-551-370000-9
AG Göttingen, HRB 2816, GF: Dr. Johannes Loxen
http://www.sernet.de, mailto:kontakt at sernet.de
-------------- next part --------------
From 5f5c94531028a611055fbc42de66122035c0bf2e Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Tue, 10 Jun 2014 14:41:45 -0700
Subject: [PATCH 1/4] 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 at samba.org>
Reviewed-by: Volker Lendecke <vl at 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 3f779b8..d66c093 100644
--- a/source3/smbd/smb2_find.c
+++ b/source3/smbd/smb2_find.c
@@ -252,11 +252,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.8.1.2
From 88bdeab70770ba6fa51251324d3f502e316d65e5 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Tue, 10 Jun 2014 15:58:15 -0700
Subject: [PATCH 2/4] 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 at samba.org>
Reviewed-by: Volker Lendecke <vl at samba.org>
---
source3/smbd/smb2_find.c | 37 ++++++++++++++++++++++++++++++++++---
1 file changed, 34 insertions(+), 3 deletions(-)
diff --git a/source3/smbd/smb2_find.c b/source3/smbd/smb2_find.c
index d66c093..e9e0542 100644
--- a/source3/smbd/smb2_find.c
+++ b/source3/smbd/smb2_find.c
@@ -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,
--
1.8.1.2
From c91d72228e36a3894522be9b7aec96ac57641c19 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Wed, 11 Jun 2014 09:32:56 +0000
Subject: [PATCH 3/4] smbd: Use full_path_tos() where appropriate
Recently I've got reports that SMB2_FIND is slower than trans2 findfirst,
so this tries to use recent performance-sensitive APIs right from the
start :-)
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/smbd/smb2_find.c | 22 +++++++++++++++-------
1 file changed, 15 insertions(+), 7 deletions(-)
diff --git a/source3/smbd/smb2_find.c b/source3/smbd/smb2_find.c
index e9e0542..481dcb9 100644
--- a/source3/smbd/smb2_find.c
+++ b/source3/smbd/smb2_find.c
@@ -330,17 +330,23 @@ static struct tevent_req *smbd_smb2_find_send(TALLOC_CTX *mem_ctx,
if (!wcard_has_wild) {
struct smb_filename *smb_fname = NULL;
const char *fullpath;
+ char tmpbuf[PATH_MAX];
+ char *to_free = NULL;
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);
+ size_t len;
+ char *tmp;
+
+ len = full_path_tos(
+ fsp->fsp_name->base_name, in_file_name,
+ tmpbuf, sizeof(tmpbuf), &tmp, &to_free);
+ if (len == -1) {
+ tevent_req_oom(req);
+ return tevent_req_post(req, ev);
+ }
+ fullpath = tmp;
}
status = filename_convert(state,
conn,
@@ -350,6 +356,8 @@ static struct tevent_req *smbd_smb2_find_send(TALLOC_CTX *mem_ctx,
&wcard_has_wild,
&smb_fname);
+ TALLOC_FREE(to_free);
+
if (!NT_STATUS_IS_OK(status)) {
tevent_req_nterror(req, status);
return tevent_req_post(req, ev);
--
1.8.1.2
From 6aa6ae585ec99fe21f63e7fd22e9c1696bd9870e Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Wed, 11 Jun 2014 09:35:37 +0000
Subject: [PATCH 4/4] smbd: tevent_req_nterror already returns bool :-)
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/smbd/smb2_find.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/source3/smbd/smb2_find.c b/source3/smbd/smb2_find.c
index 481dcb9..6bc44a5 100644
--- a/source3/smbd/smb2_find.c
+++ b/source3/smbd/smb2_find.c
@@ -358,8 +358,7 @@ static struct tevent_req *smbd_smb2_find_send(TALLOC_CTX *mem_ctx,
TALLOC_FREE(to_free);
- if (!NT_STATUS_IS_OK(status)) {
- tevent_req_nterror(req, status);
+ if (tevent_req_nterror(req, status)) {
return tevent_req_post(req, ev);
}
--
1.8.1.2
More information about the samba-technical
mailing list