[PATCH] Some smb readdir optimizations

Volker Lendecke vl at samba.org
Fri Jan 20 12:54:39 UTC 2017


Hi!

Just found this in the attic.

Any objections?

Thanks, Volker
-------------- next part --------------
>From dc9e7df26d0a1741f822f34c5b2f3627f5e7956e Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Thu, 20 Oct 2016 16:48:12 +0200
Subject: [PATCH 01/10] smbd: Fix a typo

Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/lib/ms_fnmatch.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source3/lib/ms_fnmatch.c b/source3/lib/ms_fnmatch.c
index e32d094..9763afe 100644
--- a/source3/lib/ms_fnmatch.c
+++ b/source3/lib/ms_fnmatch.c
@@ -161,7 +161,7 @@ int ms_fnmatch(const char *pattern, const char *string, bool translate_pattern,
 	}
 
 	if (strpbrk(pattern, "<>*?\"") == NULL) {
-		/* this is not just an optmisation - it is essential
+		/* this is not just an optimisation - it is essential
 		   for LANMAN1 correctness */
 		if (is_case_sensitive) {
 			return strcmp(pattern, string);
-- 
2.1.4


>From a0924240da5f4605ed1e46773e5ddfac2f513e66 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Tue, 25 Oct 2016 15:42:28 +0200
Subject: [PATCH 02/10] lib: Avoid a "includes.h"

Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/lib/tevent_barrier.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source3/lib/tevent_barrier.c b/source3/lib/tevent_barrier.c
index 318c896..0fc0a31 100644
--- a/source3/lib/tevent_barrier.c
+++ b/source3/lib/tevent_barrier.c
@@ -17,7 +17,7 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#include "includes.h"
+#include "replace.h"
 #include "tevent_barrier.h"
 #include "lib/util/tevent_unix.h"
 
-- 
2.1.4


>From 55c59eb7661c138c3bc51668c14ea917ba951e0d Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Wed, 26 Oct 2016 12:56:53 +0200
Subject: [PATCH 03/10] smbd: Fix a few signed/unsigned hickups

Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/posix_acls.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index f7829fe..cc3fe92 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -437,7 +437,7 @@ static const char *create_pai_v1_entries(struct pai_val *paiv,
 				const char *entry_offset,
 				bool def_entry)
 {
-	int i;
+	unsigned int i;
 
 	for (i = 0; i < paiv->num_entries; i++) {
 		struct pai_entry *paie = talloc(talloc_tos(), struct pai_entry);
@@ -1844,7 +1844,7 @@ static bool create_canon_ace_lists(files_struct *fsp,
 	canon_ace *current_ace = NULL;
 	bool got_dir_allow = False;
 	bool got_file_allow = False;
-	int i, j;
+	uint32_t i, j;
 
 	*ppfile_ace = NULL;
 	*ppdir_ace = NULL;
@@ -2755,7 +2755,7 @@ static canon_ace *canonicalise_acl(struct connection_struct *conn,
 
 bool current_user_in_group(connection_struct *conn, gid_t gid)
 {
-	int i;
+	uint32_t i;
 	const struct security_unix_token *utok = get_current_utok(conn);
 
 	for (i = 0; i < utok->ngroups; i++) {
@@ -3248,7 +3248,7 @@ static void add_or_replace_ace(struct security_ace *nt_ace_list, size_t *num_ace
 				const struct dom_sid *sid, enum security_ace_type type,
 				uint32_t mask, uint8_t flags)
 {
-	int i;
+	size_t i;
 
 	/* first search for a duplicate */
 	for (i = 0; i < *num_aces; i++) {
@@ -3259,7 +3259,7 @@ static void add_or_replace_ace(struct security_ace *nt_ace_list, size_t *num_ace
 	if (i < *num_aces) { /* found */
 		nt_ace_list[i].type = type;
 		nt_ace_list[i].access_mask = mask;
-		DEBUG(10, ("Replacing ACE %d with SID %s and flags %02x\n",
+		DEBUG(10, ("Replacing ACE %zu with SID %s and flags %02x\n",
 			   i, sid_string_dbg(sid), flags));
 		return;
 	}
@@ -3299,7 +3299,6 @@ static NTSTATUS posix_get_nt_acl_common(struct connection_struct *conn,
 	size_t num_profile_acls = 0;
 	struct dom_sid orig_owner_sid;
 	struct security_descriptor *psd = NULL;
-	int i;
 
 	/*
 	 * Get the owner, group and world SIDs.
@@ -3426,6 +3425,8 @@ static NTSTATUS posix_get_nt_acl_common(struct connection_struct *conn,
 			num_aces = merge_default_aces(nt_ace_list, num_aces);
 
 			if (lp_profile_acls(SNUM(conn))) {
+				size_t i;
+
 				for (i = 0; i < num_aces; i++) {
 					if (dom_sid_equal(&nt_ace_list[i].trustee, &owner_sid)) {
 						add_or_replace_ace(nt_ace_list, &num_aces,
-- 
2.1.4


>From 19970e2ec6dbd07fa471e5236c802b170f506cd1 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Wed, 26 Oct 2016 12:20:39 +0200
Subject: [PATCH 04/10] smbd: Fix an indentation

Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/posix_acls.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index cc3fe92..9d02e8a 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -2470,9 +2470,10 @@ static bool unpack_canon_ace(files_struct *fsp,
 	 * Now go through the DACL and create the canon_ace lists.
 	 */
 
-	if (!create_canon_ace_lists( fsp, pst, pfile_owner_sid, pfile_grp_sid,
-								&file_ace, &dir_ace, psd->dacl))
+	if (!create_canon_ace_lists(fsp, pst, pfile_owner_sid, pfile_grp_sid,
+				    &file_ace, &dir_ace, psd->dacl)) {
 		return False;
+	}
 
 	if ((file_ace == NULL) && (dir_ace == NULL)) {
 		/* W2K traverse DACL set - ignore. */
-- 
2.1.4


>From 93f875face6aad58ce1363c25532fa7390417063 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Thu, 20 Oct 2016 16:33:55 +0200
Subject: [PATCH 05/10] smbd: Streamline get_ea_names_from_file

Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/smbd/trans2.c | 96 +++++++++++++++++++++++++++++----------------------
 1 file changed, 54 insertions(+), 42 deletions(-)

diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 6fe3f92..f58aacf 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -242,12 +242,14 @@ NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx,
 				char ***pnames,
 				size_t *pnum_names)
 {
+	char smallbuf[1024];
 	/* Get a list of all xattrs. Max namesize is 64k. */
 	size_t ea_namelist_size = 1024;
-	char *ea_namelist = NULL;
+	char *ea_namelist = smallbuf;
+	char *to_free = NULL;
 
 	char *p;
-	char **names, **tmp;
+	char **names;
 	size_t num_names;
 	ssize_t sizeret = -1;
 	NTSTATUS status;
@@ -269,54 +271,45 @@ NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx,
 		return NT_STATUS_OK;
 	}
 
-	/*
-	 * TALLOC the result early to get the talloc hierarchy right.
-	 */
-
-	names = talloc_array(mem_ctx, char *, 1);
-	if (names == NULL) {
-		DEBUG(0, ("talloc failed\n"));
-		return NT_STATUS_NO_MEMORY;
+	if (fsp && fsp->fh->fd != -1) {
+		sizeret = SMB_VFS_FLISTXATTR(fsp, ea_namelist,
+					     ea_namelist_size);
+	} else {
+		sizeret = SMB_VFS_LISTXATTR(conn,
+					    smb_fname->base_name,
+					    ea_namelist,
+					    ea_namelist_size);
 	}
 
-	while (ea_namelist_size <= 65536) {
-
-		ea_namelist = talloc_realloc(
-			names, ea_namelist, char, ea_namelist_size);
+	if ((sizeret == -1) && (errno == ERANGE)) {
+		ea_namelist_size = 65536;
+		ea_namelist = talloc_array(mem_ctx, char, ea_namelist_size);
 		if (ea_namelist == NULL) {
-			DEBUG(0, ("talloc failed\n"));
-			TALLOC_FREE(names);
 			return NT_STATUS_NO_MEMORY;
 		}
+		to_free = ea_namelist;
 
 		if (fsp && fsp->fh->fd != -1) {
 			sizeret = SMB_VFS_FLISTXATTR(fsp, ea_namelist,
 						     ea_namelist_size);
 		} else {
 			sizeret = SMB_VFS_LISTXATTR(conn,
-					smb_fname->base_name,
-					ea_namelist,
-					ea_namelist_size);
-		}
-
-		if ((sizeret == -1) && (errno == ERANGE)) {
-			ea_namelist_size *= 2;
-		}
-		else {
-			break;
+						    smb_fname->base_name,
+						    ea_namelist,
+						    ea_namelist_size);
 		}
 	}
 
 	if (sizeret == -1) {
-		TALLOC_FREE(names);
-		return map_nt_error_from_unix(errno);
+		status = map_nt_error_from_unix(errno);
+		TALLOC_FREE(to_free);
+		return status;
 	}
 
-	DEBUG(10, ("%s: ea_namelist size = %u\n",
-		   __func__, (unsigned int)sizeret));
+	DBG_DEBUG("ea_namelist size = %zd\n", sizeret);
 
 	if (sizeret == 0) {
-		TALLOC_FREE(names);
+		TALLOC_FREE(to_free);
 		return NT_STATUS_OK;
 	}
 
@@ -325,7 +318,7 @@ NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx,
 	 */
 
 	if (ea_namelist[sizeret-1] != '\0') {
-		TALLOC_FREE(names);
+		TALLOC_FREE(to_free);
 		return NT_STATUS_INTERNAL_ERROR;
 	}
 
@@ -338,26 +331,45 @@ NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx,
 		num_names += 1;
 	}
 
-	tmp = talloc_realloc(mem_ctx, names, char *, num_names);
-	if (tmp == NULL) {
+	*pnum_names = num_names;
+
+	if (pnames == NULL) {
+		TALLOC_FREE(to_free);
+		return NT_STATUS_OK;
+	}
+
+	names = talloc_array(mem_ctx, char *, num_names);
+	if (names == NULL) {
 		DEBUG(0, ("talloc failed\n"));
-		TALLOC_FREE(names);
+		TALLOC_FREE(to_free);
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	names = tmp;
+	if (ea_namelist == smallbuf) {
+		ea_namelist = talloc_memdup(names, smallbuf, sizeret);
+		if (ea_namelist == NULL) {
+			TALLOC_FREE(names);
+			return NT_STATUS_NO_MEMORY;
+		}
+	} else {
+		talloc_steal(names, ea_namelist);
+
+		ea_namelist = talloc_realloc(names, ea_namelist, char,
+					     sizeret);
+		if (ea_namelist == NULL) {
+			TALLOC_FREE(names);
+			return NT_STATUS_NO_MEMORY;
+		}
+	}
+
 	num_names = 0;
 
 	for (p = ea_namelist; p - ea_namelist < sizeret; p += strlen(p)+1) {
 		names[num_names++] = p;
 	}
 
-	if (pnames) {
-		*pnames = names;
-	} else {
-		TALLOC_FREE(names);
-	}
-	*pnum_names = num_names;
+	*pnames = names;
+
 	return NT_STATUS_OK;
 }
 
-- 
2.1.4


>From b9d42b35f44efbf481582f21db2b734d69c3d5c1 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Mon, 24 Oct 2016 17:32:17 +0200
Subject: [PATCH 06/10] s3/locking: Avoid a talloc for nonexisting
 fetch_share_mode_unlocked

Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/locking/share_mode_lock.c | 32 +++++++++++++++++---------------
 1 file changed, 17 insertions(+), 15 deletions(-)

diff --git a/source3/locking/share_mode_lock.c b/source3/locking/share_mode_lock.c
index f738323..c02cff8 100644
--- a/source3/locking/share_mode_lock.c
+++ b/source3/locking/share_mode_lock.c
@@ -622,19 +622,28 @@ fail:
 	return NULL;
 }
 
+struct fetch_share_mode_unlocked_state {
+	TALLOC_CTX *mem_ctx;
+	struct share_mode_lock *lck;
+};
+
 static void fetch_share_mode_unlocked_parser(
 	TDB_DATA key, TDB_DATA data, void *private_data)
 {
-	struct share_mode_lock *lck = talloc_get_type_abort(
-		private_data, struct share_mode_lock);
+	struct fetch_share_mode_unlocked_state *state = private_data;
 
 	if (data.dsize == 0) {
 		/* Likely a ctdb tombstone record, ignore it */
-		lck->data = NULL;
 		return;
 	}
 
-	lck->data = parse_share_modes(lck, key, data);
+	state->lck = talloc(state->mem_ctx, struct share_mode_lock);
+	if (state->lck == NULL) {
+		DEBUG(0, ("talloc failed\n"));
+		return;
+	}
+
+	state->lck->data = parse_share_modes(state->lck, key, data);
 }
 
 /*******************************************************************
@@ -645,23 +654,16 @@ static void fetch_share_mode_unlocked_parser(
 struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx,
 						  struct file_id id)
 {
-	struct share_mode_lock *lck;
+	struct fetch_share_mode_unlocked_state state = { .mem_ctx = mem_ctx };
 	TDB_DATA key = locking_key(&id);
 	NTSTATUS status;
 
-	lck = talloc(mem_ctx, struct share_mode_lock);
-	if (lck == NULL) {
-		DEBUG(0, ("talloc failed\n"));
-		return NULL;
-	}
 	status = dbwrap_parse_record(
-		lock_db, key, fetch_share_mode_unlocked_parser, lck);
-	if (!NT_STATUS_IS_OK(status) ||
-	    (lck->data == NULL)) {
-		TALLOC_FREE(lck);
+		lock_db, key, fetch_share_mode_unlocked_parser, &state);
+	if (!NT_STATUS_IS_OK(status)) {
 		return NULL;
 	}
-	return lck;
+	return state.lck;
 }
 
 struct share_mode_forall_state {
-- 
2.1.4


>From 9623b887f5529cbf62c19dfe279dfaf62a775771 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Tue, 25 Oct 2016 12:28:12 +0200
Subject: [PATCH 07/10] lib/util/charset: Optimize next_codepoint for the ascii
 case

Reviewed-by: Ralph Boehme <slow at samba.org>
---
 lib/util/charset/codepoints.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/lib/util/charset/codepoints.c b/lib/util/charset/codepoints.c
index 3d444a6..2c9a9c4 100644
--- a/lib/util/charset/codepoints.c
+++ b/lib/util/charset/codepoints.c
@@ -16817,6 +16817,10 @@ _PUBLIC_ codepoint_t next_codepoint_ext(const char *str, size_t len,
 
 _PUBLIC_ codepoint_t next_codepoint(const char *str, size_t *size)
 {
+	if ((str[0] & 0x80) == 0) {
+		*size = 1;
+		return str[0];
+	}
 	return next_codepoint_handle(get_iconv_handle(), str, size);
 }
 
-- 
2.1.4


>From 39d265af48f5994207f67b66f5585c174090966f Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Tue, 25 Oct 2016 11:53:53 +0200
Subject: [PATCH 08/10] lib: Add "is_case_sensitive" to ms_fnmatch_protocol

Reviewed-by: Ralph Boehme <slow at samba.org>
---
 lib/util/ms_fnmatch.c                    | 29 +++++++++++++++++++----------
 lib/util/samba_util.h                    |  3 ++-
 source4/client/client.c                  |  8 +++++---
 source4/ntvfs/cifs_posix_cli/svfs_util.c |  3 ++-
 source4/ntvfs/posix/pvfs_dirlist.c       | 12 ++++++++----
 source4/ntvfs/simple/svfs_util.c         |  3 ++-
 source4/torture/masktest.c               |  3 ++-
 7 files changed, 40 insertions(+), 21 deletions(-)

diff --git a/lib/util/ms_fnmatch.c b/lib/util/ms_fnmatch.c
index ede9eff..7f1cce0 100644
--- a/lib/util/ms_fnmatch.c
+++ b/lib/util/ms_fnmatch.c
@@ -59,7 +59,8 @@ struct max_n {
   not contain a '.', otherwise it points at the last dot in 'n'.
 */
 static int ms_fnmatch_core(const char *p, const char *n, 
-			   struct max_n *max_n, const char *ldot)
+			   struct max_n *max_n, const char *ldot,
+			   bool is_case_sensitive)
 {
 	codepoint_t c, c2;
 	int i;
@@ -76,7 +77,7 @@ static int ms_fnmatch_core(const char *p, const char *n,
 			}
 			for (i=0; n[i]; i += size_n) {
 				next_codepoint(n+i, &size_n);
-				if (ms_fnmatch_core(p, n+i, max_n+1, ldot) == 0) {
+				if (ms_fnmatch_core(p, n+i, max_n+1, ldot, is_case_sensitive) == 0) {
 					return 0;
 				}
 			}
@@ -95,9 +96,9 @@ static int ms_fnmatch_core(const char *p, const char *n,
 			}
 			for (i=0; n[i]; i += size_n) {
 				next_codepoint(n+i, &size_n);
-				if (ms_fnmatch_core(p, n+i, max_n+1, ldot) == 0) return 0;
+				if (ms_fnmatch_core(p, n+i, max_n+1, ldot, is_case_sensitive) == 0) return 0;
 				if (n+i == ldot) {
-					if (ms_fnmatch_core(p, n+i+size_n, max_n+1, ldot) == 0) return 0;
+					if (ms_fnmatch_core(p, n+i+size_n, max_n+1, ldot, is_case_sensitive) == 0) return 0;
 					if (!max_n->postdot || max_n->postdot > n) max_n->postdot = n;
 					return -1;
 				}
@@ -140,8 +141,13 @@ static int ms_fnmatch_core(const char *p, const char *n,
 
 		default:
 			c2 = next_codepoint(n, &size_n);
-			if (c != c2 && codepoint_cmpi(c, c2) != 0) {
-				return -1;
+			if (c != c2) {
+				if (is_case_sensitive) {
+					return -1;
+				}
+				if (codepoint_cmpi(c, c2) != 0) {
+					return -1;
+				}
 			}
 			n += size_n;
 			break;
@@ -155,7 +161,8 @@ static int ms_fnmatch_core(const char *p, const char *n,
 	return -1;
 }
 
-int ms_fnmatch_protocol(const char *pattern, const char *string, int protocol)
+int ms_fnmatch_protocol(const char *pattern, const char *string, int protocol,
+			bool is_case_sensitive)
 {
 	int ret, count, i;
 	struct max_n *max_n = NULL;
@@ -193,7 +200,8 @@ int ms_fnmatch_protocol(const char *pattern, const char *string, int protocol)
 				p[i] = '<';
 			}
 		}
-		ret = ms_fnmatch_protocol(p, string, PROTOCOL_NT1);
+		ret = ms_fnmatch_protocol(p, string, PROTOCOL_NT1,
+					  is_case_sensitive);
 		talloc_free(p);
 		return ret;
 	}
@@ -207,7 +215,8 @@ int ms_fnmatch_protocol(const char *pattern, const char *string, int protocol)
 		return -1;
 	}
 
-	ret = ms_fnmatch_core(pattern, string, max_n, strrchr(string, '.'));
+	ret = ms_fnmatch_core(pattern, string, max_n, strrchr(string, '.'),
+			      is_case_sensitive);
 
 	talloc_free(max_n);
 
@@ -218,5 +227,5 @@ int ms_fnmatch_protocol(const char *pattern, const char *string, int protocol)
 /** a generic fnmatch function - uses for non-CIFS pattern matching */
 int gen_fnmatch(const char *pattern, const char *string)
 {
-	return ms_fnmatch_protocol(pattern, string, PROTOCOL_NT1);
+	return ms_fnmatch_protocol(pattern, string, PROTOCOL_NT1, false);
 }
diff --git a/lib/util/samba_util.h b/lib/util/samba_util.h
index c19e246..f6b5003 100644
--- a/lib/util/samba_util.h
+++ b/lib/util/samba_util.h
@@ -526,7 +526,8 @@ _PUBLIC_ int sys_fsusage(const char *path, uint64_t *dfree, uint64_t *dsize);
  * @brief MS-style Filename matching
  */
 
-int ms_fnmatch_protocol(const char *pattern, const char *string, int protocol);
+int ms_fnmatch_protocol(const char *pattern, const char *string, int protocol,
+			bool is_case_sensitive);
 
 /** a generic fnmatch function - uses for non-CIFS pattern matching */
 int gen_fnmatch(const char *pattern, const char *string);
diff --git a/source4/client/client.c b/source4/client/client.c
index 9866444..10d027b 100644
--- a/source4/client/client.c
+++ b/source4/client/client.c
@@ -311,12 +311,14 @@ static bool mask_match(struct smbcli_state *c, const char *string,
 		return false;
 	
 	if (is_case_sensitive)
-		return ms_fnmatch_protocol(pattern, string, 
-				  c->transport->negotiate.protocol) == 0;
+		return ms_fnmatch_protocol(
+			pattern, string, c->transport->negotiate.protocol,
+			true) == 0;
 
 	p2 = strlower_talloc(NULL, pattern);
 	s2 = strlower_talloc(NULL, string);
-	ret = ms_fnmatch_protocol(p2, s2, c->transport->negotiate.protocol) == 0;
+	ret = ms_fnmatch_protocol(p2, s2, c->transport->negotiate.protocol,
+				  true) == 0;
 	talloc_free(p2);
 	talloc_free(s2);
 
diff --git a/source4/ntvfs/cifs_posix_cli/svfs_util.c b/source4/ntvfs/cifs_posix_cli/svfs_util.c
index cf881a1..ec2e933 100644
--- a/source4/ntvfs/cifs_posix_cli/svfs_util.c
+++ b/source4/ntvfs/cifs_posix_cli/svfs_util.c
@@ -105,7 +105,8 @@ struct cifspsx_dir *cifspsx_list_unix(TALLOC_CTX *mem_ctx, struct ntvfs_request
 		if (!low_name) { continue; }
 
 		/* check it matches the wildcard pattern */
-		if (ms_fnmatch_protocol(low_mask, low_name, PROTOCOL_NT1) != 0) {
+		if (ms_fnmatch_protocol(low_mask, low_name, PROTOCOL_NT1,
+					true) != 0) {
 			continue;
 		}
 		
diff --git a/source4/ntvfs/posix/pvfs_dirlist.c b/source4/ntvfs/posix/pvfs_dirlist.c
index 1bc91c1..d86fce4 100644
--- a/source4/ntvfs/posix/pvfs_dirlist.c
+++ b/source4/ntvfs/posix/pvfs_dirlist.c
@@ -199,7 +199,8 @@ const char *pvfs_list_next(struct pvfs_dir *dir, off_t *ofs)
 	if (*ofs == DIR_OFFSET_DOT) {
 		(*ofs) = DIR_OFFSET_DOTDOT;
 		dir->offset = *ofs;
-		if (ms_fnmatch_protocol(dir->pattern, ".", protocol) == 0) {
+		if (ms_fnmatch_protocol(dir->pattern, ".", protocol,
+					true) == 0) {
 			dcache_add(dir, ".");
 			return ".";
 		}
@@ -208,7 +209,8 @@ const char *pvfs_list_next(struct pvfs_dir *dir, off_t *ofs)
 	if (*ofs == DIR_OFFSET_DOTDOT) {
 		(*ofs) = DIR_OFFSET_BASE;
 		dir->offset = *ofs;
-		if (ms_fnmatch_protocol(dir->pattern, "..", protocol) == 0) {
+		if (ms_fnmatch_protocol(dir->pattern, "..", protocol,
+					true) == 0) {
 			dcache_add(dir, "..");
 			return "..";
 		}
@@ -228,10 +230,12 @@ const char *pvfs_list_next(struct pvfs_dir *dir, off_t *ofs)
 			continue;
 		}
 
-		if (ms_fnmatch_protocol(dir->pattern, dname, protocol) != 0) {
+		if (ms_fnmatch_protocol(dir->pattern, dname, protocol,
+					true) != 0) {
 			char *short_name = pvfs_short_name_component(dir->pvfs, dname);
 			if (short_name == NULL ||
-			    ms_fnmatch_protocol(dir->pattern, short_name, protocol) != 0) {
+			    ms_fnmatch_protocol(dir->pattern, short_name,
+						protocol, true) != 0) {
 				talloc_free(short_name);
 				continue;
 			}
diff --git a/source4/ntvfs/simple/svfs_util.c b/source4/ntvfs/simple/svfs_util.c
index 171813b..21f20c5 100644
--- a/source4/ntvfs/simple/svfs_util.c
+++ b/source4/ntvfs/simple/svfs_util.c
@@ -101,7 +101,8 @@ struct svfs_dir *svfs_list_unix(TALLOC_CTX *mem_ctx, struct ntvfs_request *req,
 		if (!low_name) { continue; }
 
 		/* check it matches the wildcard pattern */
-		if (ms_fnmatch_protocol(low_mask, low_name, PROTOCOL_NT1) != 0) {
+		if (ms_fnmatch_protocol(low_mask, low_name, PROTOCOL_NT1,
+					true) != 0) {
 			continue;
 		}
 		
diff --git a/source4/torture/masktest.c b/source4/torture/masktest.c
index b96c6da..e6e7f4e 100644
--- a/source4/torture/masktest.c
+++ b/source4/torture/masktest.c
@@ -49,7 +49,8 @@ static bool reg_match_one(struct smbcli_state *cli, const char *pattern, const c
 
 	if (ISDOTDOT(file)) file = ".";
 
-	return ms_fnmatch_protocol(pattern, file, cli->transport->negotiate.protocol)==0;
+	return ms_fnmatch_protocol(
+		pattern, file, cli->transport->negotiate.protocol, true)==0;
 }
 
 static char *reg_test(struct smbcli_state *cli, TALLOC_CTX *mem_ctx, const char *pattern, const char *long_name, const char *short_name)
-- 
2.1.4


>From 1a1cfe04da8fa6341fa6a30bba75b687fab99a54 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Tue, 25 Oct 2016 12:28:44 +0200
Subject: [PATCH 09/10] s3/lib: Use ms_fnmatch_protocol in mask_match

This avoids the talloc/free through push_ucs2_talloc

Reviewed-by: Ralph Boehme <slow at samba.org>
---
 source3/lib/util.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source3/lib/util.c b/source3/lib/util.c
index 85cb9b3..6883986 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -1752,7 +1752,7 @@ bool mask_match(const char *string, const char *pattern, bool is_case_sensitive)
 	if (ISDOT(pattern))
 		return False;
 
-	return ms_fnmatch(pattern, string, Protocol <= PROTOCOL_LANMAN2, is_case_sensitive) == 0;
+	return ms_fnmatch_protocol(pattern, string, Protocol, is_case_sensitive) == 0;
 }
 
 /*******************************************************************
-- 
2.1.4


>From 6ae6637a7eae545b4a37bce2ba1b70b62f764820 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Tue, 25 Oct 2016 12:46:00 +0200
Subject: [PATCH 10/10] lib/util: Avoid a talloc in ms_fnmatch_protocol

Reviewed-by: Ralph Boehme <slow at samba.org>
---
 lib/util/ms_fnmatch.c | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/lib/util/ms_fnmatch.c b/lib/util/ms_fnmatch.c
index 7f1cce0..c0f61ab 100644
--- a/lib/util/ms_fnmatch.c
+++ b/lib/util/ms_fnmatch.c
@@ -165,7 +165,6 @@ int ms_fnmatch_protocol(const char *pattern, const char *string, int protocol,
 			bool is_case_sensitive)
 {
 	int ret, count, i;
-	struct max_n *max_n = NULL;
 
 	if (strcmp(string, "..") == 0) {
 		string = ".";
@@ -210,15 +209,14 @@ int ms_fnmatch_protocol(const char *pattern, const char *string, int protocol,
 		if (pattern[i] == '*' || pattern[i] == '<') count++;
 	}
 
-	max_n = talloc_zero_array(NULL, struct max_n, count);
-	if (max_n == NULL) {
-		return -1;
-	}
+	{
+		struct max_n max_n[count];
 
-	ret = ms_fnmatch_core(pattern, string, max_n, strrchr(string, '.'),
-			      is_case_sensitive);
+		memset(max_n, 0, sizeof(struct max_n) * count);
 
-	talloc_free(max_n);
+		ret = ms_fnmatch_core(pattern, string, max_n, strrchr(string, '.'),
+				      is_case_sensitive);
+	}
 
 	return ret;
 }
-- 
2.1.4



More information about the samba-technical mailing list