[SCM] Samba Shared Repository - branch master updated

Stefan Metzmacher metze at samba.org
Wed Jul 31 09:42:01 UTC 2024


The branch, master has been updated
       via  10e9b858a3f docs: Document parametric form of hide and veto files
       via  a150714cc64 lib: Remove "token" parameter from set_namearray
       via  b5169dd717e lib: Remove per-user support from append_to_namearray
       via  b5a128685e6 tests: Test parametric per-user syntax for hide/veto files
       via  17becb5f526 smbd: Respect per-user hide and veto files with parametric options
       via  fcd595a4642 lib: Factor out append_namearray from set_namearray
       via  89da15756d8 loadparm: Add lp_wi_scan_share_parametrics
       via  0536ac96e92 loadparm: Factor out lp_wi_scan_parametrics
      from  7dc19dd94cb s4:torture/smb2: add 'smb2.bench.session-setup'

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 10e9b858a3f9ca8d7e5dfd1c4e1e7937a03db671
Author: Volker Lendecke <vl at samba.org>
Date:   Tue Jul 30 14:06:21 2024 +0200

    docs: Document parametric form of hide and veto files
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=15688
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    
    Autobuild-User(master): Stefan Metzmacher <metze at samba.org>
    Autobuild-Date(master): Wed Jul 31 09:41:54 UTC 2024 on atb-devel-224

commit a150714cc64294d75028bac47132084bdf6f72c9
Author: Volker Lendecke <vl at samba.org>
Date:   Tue Jul 30 13:55:57 2024 +0200

    lib: Remove "token" parameter from set_namearray
    
    Not needed anymore
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=15688
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit b5169dd717ed5cf66d1e1e90aaf1a4646f7b5ea5
Author: Volker Lendecke <vl at samba.org>
Date:   Tue Jul 30 13:30:21 2024 +0200

    lib: Remove per-user support from append_to_namearray
    
    This is done in check_user_ok now
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=15688
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit b5a128685e68f05a3688aa1391393b9095bf32b0
Author: Volker Lendecke <vl at samba.org>
Date:   Tue Jul 30 14:11:53 2024 +0200

    tests: Test parametric per-user syntax for hide/veto files
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=15688
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit 17becb5f526015de56d00cd1c8f603f8ddacd0ba
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Jul 29 17:49:49 2024 +0200

    smbd: Respect per-user hide and veto files with parametric options
    
    For my taste this is a nicer configuration syntax than
    
    /../username1/file1/../username2/file2/
    
    Is this too expensive? I don't think so. The scanning only happens an
    tcon time, and it only walks the parametric options. If this turns out
    to be a performance problem, we should think about smarter data
    structures for parametric options instead of just a linked list of
    string triples for everything.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=15688
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit fcd595a4642a08169b427af534a00116daf220bf
Author: Volker Lendecke <vl at samba.org>
Date:   Tue Jul 30 13:07:22 2024 +0200

    lib: Factor out append_namearray from set_namearray
    
    We'll have to add to an existing namearray soon.
    
    This turns one talloc_array() into a set of reallocs. This is slower,
    but set_namearray is only used for smb.conf entries where we don't
    expect hundreds or more entries to add. I've done this to avoid array
    length calculations, but if it turns out to be too slow we can get
    smarter again.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=15688
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit 89da15756d81746d80b43c2fe04c51fc07591849
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Jul 29 07:17:21 2024 -0700

    loadparm: Add lp_wi_scan_share_parametrics
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=15688
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit 0536ac96e927c00121e220f45cd63682726bc8e3
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Jul 29 06:27:51 2024 -0700

    loadparm: Factor out lp_wi_scan_parametrics
    
    We'll scan share parametrics soon as well.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=15688
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 docs-xml/smbdotconf/filename/hidefiles.xml |  29 +++++--
 docs-xml/smbdotconf/filename/vetofiles.xml |  29 +++++--
 selftest/target/Samba3.pm                  |   6 +-
 source3/include/proto.h                    |   4 +-
 source3/lib/util_namearray.c               | 119 ++++++++++++--------------
 source3/modules/vfs_virusfilter.c          |   2 -
 source3/param/loadparm.c                   |  50 +++++++++--
 source3/param/loadparm.h                   |   7 ++
 source3/smbd/smb2_service.c                |   2 -
 source3/smbd/uid.c                         | 132 ++++++++++++++++++++++++++++-
 source3/torture/test_matching.c            |   2 +-
 11 files changed, 283 insertions(+), 99 deletions(-)


Changeset truncated at 500 lines:

diff --git a/docs-xml/smbdotconf/filename/hidefiles.xml b/docs-xml/smbdotconf/filename/hidefiles.xml
index f93885e43a3..3290f8df8db 100644
--- a/docs-xml/smbdotconf/filename/hidefiles.xml
+++ b/docs-xml/smbdotconf/filename/hidefiles.xml
@@ -14,14 +14,22 @@
 	as in DOS wildcards.</para>
 
 	<para>
-	If a file or directory name is prefixed by "../USERNAME/"
-	or "../GROUPNAME/", then the subsequent filename is only hidden for the
-	given user or group. Instead of specifying users or groups by name, they
-	can also be specified by SID.
+	<smbconfoption name="hide files"/> can also be used as a
+	parametric option where NAME in</para>
+
+	<para>
+	hide files : NAME =
 	</para>
 
-	<para>User and group names use the same format as <smbconfoption
-	name="valid users"/>.</para>
+	<para>
+	specifies a user or group name with the same syntax as
+	<smbconfoption name="valid users"/>. This parametric form can
+	be specified multiple times for different users or
+	groups. This means that "hide files : NAME" set both
+	in the [global] and the share section add up, whereas normally
+	options set in a share section overwrite the default in the
+	[global] section.
+	</para>
 
 	<para>Each entry must be a Unix path, not a DOS path and must 
 	not include the Unix directory separator '/'.</para>
@@ -46,9 +54,12 @@
 hide files = /.*/DesktopFolderDB/TrashFor%m/resource.frk/
 
 ; Hide some files for anyone and some files for specific users and groups
-hide files = hideforall1/../joe/hideforuserjoe/hideforall2/../students/hideforstudents/hideforall3
-hide files = ../UNIVERSITY\Alumnis/somefile.txt/../john at university.org/anotherfile.txt
-hide files = ../S-1-5-21-123-456-789-1000/secretfile.txt
+hide files = /hideforall1/
+hide files : USER = /hidetoforuser/
+hide files : GROUP = /hideforgroup/
+hide files : UNIVERSITY\Alumnis = /somefile.txt/
+hide files : john at university.org = /anotherfile.txt/
+hide files : S-1-5-21-123-456-789-1000 = /secretfile.txt/
 
 </programlisting>
 	</para>
diff --git a/docs-xml/smbdotconf/filename/vetofiles.xml b/docs-xml/smbdotconf/filename/vetofiles.xml
index e47490ee49d..e90cf707c2d 100644
--- a/docs-xml/smbdotconf/filename/vetofiles.xml
+++ b/docs-xml/smbdotconf/filename/vetofiles.xml
@@ -11,14 +11,22 @@
 	</para>
 
 	<para>
-	If a file or directory name is prefixed by "../USERNAME/"
-	or "../GROUPNAME/", then the subsequent filename is only hidden for the
-	given user or group. Instead of specifying users or groups by name, they
-	can also be specified by SID.
+	<smbconfoption name="veto files"/> can also be used as a
+	parametric option where NAME in</para>
+
+	<para>
+	veto files : NAME =
 	</para>
 
-	<para>User and group names use the same format as <smbconfoption
-	name="valid users"/>.</para>
+	<para>
+	specifies a user or group name with the same syntax as
+	<smbconfoption name="valid users"/>. This parametric form can
+	be specified multiple times for different users or
+	groups. This means that "veto files : NAME" set both
+	in the [global] and the share section add up, whereas normally
+	options set in a share section overwrite the default in the
+	[global] section.
+	</para>
 
 	<para>
 	Each filename must be a unix path, not a DOS path and must
@@ -51,9 +59,12 @@
 veto files = /*Security*/*.tmp/*root*/
 
 ; Veto some files for anyone and some files for specific users and groups
-veto files = /vetoforall1/../USER/vetoforuser/vetoforall2/../GROUP/vetoforgroup/vetoforall3/
-veto files = ../UNIVERSITY\Alumnis/somefile.txt/../john at university.org/anotherfile.txt
-veto files = ../S-1-5-21-123-456-789-1000/secretfile.txt
+veto files = /vetoforall1/
+veto files : USER = /vetotoforuser/
+veto files : GROUP = /vetoforgroup/
+veto files : UNIVERSITY\Alumnis = /somefile.txt/
+veto files : john at university.org = /anotherfile.txt/
+veto files : S-1-5-21-123-456-789-1000 = /secretfile.txt/
 
 ; Veto the Apple specific files that a NetAtalk server
 ; creates.
diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
index 8d7f690ecf6..aea64bf5d5d 100755
--- a/selftest/target/Samba3.pm
+++ b/selftest/target/Samba3.pm
@@ -1968,6 +1968,8 @@ sub setup_fileserver
 
 	get quota command = $prefix_abs/getset_quota.py
 	set quota command = $prefix_abs/getset_quota.py
+	veto files : user1 = /user1file/
+	veto files : +group1 = /group1file/
 [tarmode]
 	path = $tarmode_sharedir
 	comment = tar test share
@@ -2079,7 +2081,9 @@ sub setup_fileserver
 
 [veto_files]
 	path = $veto_sharedir
-	veto files = /veto_name*/../user1/user1file/../user2/user2file/../+group1/group1file/../+group2/group2file
+	veto files = /veto_name*/
+	veto files : user2 = /user2file/
+	veto files : +group2 = /group2file/
 
 [delete_yes_unwrite]
 	read only = no
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 966d038cc40..f398106e5a2 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -326,9 +326,11 @@ bool token_contains_name(TALLOC_CTX *mem_ctx,
 			 const struct security_token *token,
 			 const char *name,
 			 bool *match);
+bool append_to_namearray(TALLOC_CTX *mem_ctx,
+			 const char *namelist_in,
+			 struct name_compare_entry **_name_array);
 bool set_namearray(TALLOC_CTX *mem_ctx,
 		   const char *namelist,
-		   const struct security_token *token,
 		   struct name_compare_entry **_name_array);
 bool fcntl_lock(int fd, int op, off_t offset, off_t count, int type);
 bool fcntl_getlock(int fd, int op, off_t *poffset, off_t *pcount, int *ptype, pid_t *ppid);
diff --git a/source3/lib/util_namearray.c b/source3/lib/util_namearray.c
index ca3344e09f1..1c5b4ac6a0e 100644
--- a/source3/lib/util_namearray.c
+++ b/source3/lib/util_namearray.c
@@ -179,6 +179,17 @@ bool token_contains_name(TALLOC_CTX *mem_ctx,
 	return true;
 }
 
+static size_t namearray_len(const struct name_compare_entry *array)
+{
+	size_t i = 0;
+
+	while (array[i].name != NULL) {
+		i += 1;
+	}
+
+	return i;
+}
+
 /*******************************************************************
  Strip a '/' separated list into an array of
  name_compare_enties structures suitable for
@@ -190,94 +201,70 @@ bool token_contains_name(TALLOC_CTX *mem_ctx,
  if possible.
 ********************************************************************/
 
-bool set_namearray(TALLOC_CTX *mem_ctx,
-		   const char *namelist_in,
-		   const struct security_token *token,
-		   struct name_compare_entry **_name_array)
+bool append_to_namearray(TALLOC_CTX *mem_ctx,
+			 const char *namelist_in,
+			 struct name_compare_entry **_name_array)
 {
-	struct name_compare_entry *name_array = NULL;
-	struct name_compare_entry *e = NULL;
+	struct name_compare_entry *name_array = *_name_array;
+	size_t len;
 	char *namelist = NULL;
 	const char *p = NULL;
-	size_t num_entries;
-	bool ok;
-
-	*_name_array = NULL;
 
 	if ((namelist_in == NULL) || (namelist_in[0] == '\0')) {
 		return true;
 	}
 
-	namelist = path_to_strv(mem_ctx, namelist_in);
-	if (namelist == NULL) {
-		DBG_ERR("path_to_strv failed\n");
-		return false;
+	if (name_array == NULL) {
+		name_array = talloc_zero(mem_ctx, struct name_compare_entry);
+		if (name_array == NULL) {
+			return false;
+		}
 	}
+	len = namearray_len(name_array);
 
-	num_entries = strv_count(namelist);
-
-	name_array = talloc_zero_array(mem_ctx,
-				       struct name_compare_entry,
-				       num_entries + 1);
-	if (name_array == NULL) {
-		DBG_ERR("talloc failed\n");
-		TALLOC_FREE(namelist);
+	namelist = path_to_strv(name_array, namelist_in);
+	if (namelist == NULL) {
+		DBG_ERR("path_to_strv failed\n");
 		return false;
 	}
 
-	namelist = talloc_reparent(mem_ctx, name_array, namelist);
-
-	e = &name_array[0];
-
 	while ((p = strv_next(namelist, p)) != NULL) {
+		struct name_compare_entry *tmp = NULL;
+
 		if (*p == '\0') {
 			/* cope with multiple (useless) /s) */
 			continue;
 		}
 
-		if (ISDOTDOT(p) && token != NULL) {
-			const char *username = NULL;
-			bool match;
-
-			/* Get the username */
-			p = strv_next(namelist, p);
-			if (p == NULL) {
-				DBG_ERR("Missing username\n");
-				TALLOC_FREE(namelist);
-				return false;
-			}
-			username = p;
-
-			/* Get the filename */
-			p = strv_next(namelist, p);
-			if (p == NULL) {
-				DBG_ERR("Missing filename after username '%s'\n",
-					username);
-				TALLOC_FREE(namelist);
-				return false;
-			}
-
-			ok = token_contains_name(talloc_tos(),
-						 NULL,
-						 NULL,
-						 NULL,
-						 token,
-						 username,
-						 &match);
-			if (!ok) {
-				TALLOC_FREE(namelist);
-				return false;
-			}
-			if (!match) {
-				continue;
-			}
+		tmp = talloc_realloc(mem_ctx,
+				     name_array,
+				     struct name_compare_entry,
+				     len + 2);
+		if (tmp == NULL) {
+			return false;
 		}
-
-		e->name = p;
-		e->is_wild = ms_has_wild(e->name);
-		e++;
+		name_array = tmp;
+
+		name_array[len] = (struct name_compare_entry){
+			.name = p,
+			.is_wild = ms_has_wild(p),
+		};
+		name_array[len + 1] = (struct name_compare_entry){};
+		len += 1;
 	}
 
 	*_name_array = name_array;
 	return true;
 }
+
+bool set_namearray(TALLOC_CTX *mem_ctx,
+		   const char *namelist_in,
+		   struct name_compare_entry **_name_array)
+{
+	bool ret;
+
+	*_name_array = NULL;
+
+	ret = append_to_namearray(mem_ctx, namelist_in, _name_array);
+	return ret;
+}
diff --git a/source3/modules/vfs_virusfilter.c b/source3/modules/vfs_virusfilter.c
index 6d4a6fdb98c..b566b628ed2 100644
--- a/source3/modules/vfs_virusfilter.c
+++ b/source3/modules/vfs_virusfilter.c
@@ -258,7 +258,6 @@ static int virusfilter_vfs_connect(
 	if (exclude_files != NULL) {
 		ok = set_namearray(config,
 				   exclude_files,
-				   NULL,
 				   &config->exclude_files);
 		if (!ok) {
 			DBG_ERR("set_namearray failed\n");
@@ -271,7 +270,6 @@ static int virusfilter_vfs_connect(
 	if (infected_files != NULL) {
 		ok = set_namearray(config,
 				   infected_files,
-				   NULL,
 				   &config->infected_files);
 		if (!ok) {
 			DBG_ERR("set_namearray failed\n");
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index 663edb2c653..f9bc1c42796 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -1204,11 +1204,13 @@ static void discard_whitespace(char *str)
  *                      See "man regexec" for possible errors
  */
 
-int lp_wi_scan_global_parametrics(
-	const char *regex_str, size_t max_matches,
-	bool (*cb)(const char *string, regmatch_t matches[],
-		   void *private_data),
-	void *private_data)
+static int lp_wi_scan_parametrics(struct parmlist_entry *parmlist,
+				  const char *regex_str,
+				  size_t max_matches,
+				  bool (*cb)(const char *string,
+					     regmatch_t matches[],
+					     void *private_data),
+				  void *private_data)
 {
 	struct parmlist_entry *data;
 	regex_t regex;
@@ -1219,7 +1221,7 @@ int lp_wi_scan_global_parametrics(
 		return ret;
 	}
 
-	for (data = Globals.param_opt; data != NULL; data = data->next) {
+	for (data = parmlist; data != NULL; data = data->next) {
 		size_t keylen = strlen(data->key);
 		char key[keylen+1];
 		regmatch_t matches[max_matches];
@@ -1248,6 +1250,42 @@ fail:
 	return ret;
 }
 
+int lp_wi_scan_global_parametrics(const char *regex_str,
+				  size_t max_matches,
+				  bool (*cb)(const char *string,
+					     regmatch_t matches[],
+					     void *private_data),
+				  void *private_data)
+{
+	int ret = lp_wi_scan_parametrics(
+		Globals.param_opt, regex_str, max_matches, cb, private_data);
+	return ret;
+}
+
+int lp_wi_scan_share_parametrics(int snum,
+				 const char *regex_str,
+				 size_t max_matches,
+				 bool (*cb)(const char *string,
+					    regmatch_t matches[],
+					    void *private_data),
+				 void *private_data)
+{
+	struct loadparm_service *s = NULL;
+	int ret;
+
+	if (!LP_SNUM_OK(snum)) {
+		/*
+		 * We return regex return values here, REG_NOMATCH is
+		 * the closest I could find.
+		 */
+		return REG_NOMATCH;
+	}
+	s = ServicePtrs[snum];
+
+	ret = lp_wi_scan_parametrics(
+		s->param_opt, regex_str, max_matches, cb, private_data);
+	return ret;
+}
 
 #define MISSING_PARAMETER(name) \
     DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
diff --git a/source3/param/loadparm.h b/source3/param/loadparm.h
index 622e2290d3c..e8f06ddbc2c 100644
--- a/source3/param/loadparm.h
+++ b/source3/param/loadparm.h
@@ -75,6 +75,13 @@ int lp_wi_scan_global_parametrics(
 	bool (*cb)(const char *string, regmatch_t matches[],
 		   void *private_data),
 	void *private_data);
+int lp_wi_scan_share_parametrics(int snum,
+				 const char *regex_str,
+				 size_t max_matches,
+				 bool (*cb)(const char *string,
+					    regmatch_t matches[],
+					    void *private_data),
+				 void *private_data);
 
 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def);
 struct loadparm_service;
diff --git a/source3/smbd/smb2_service.c b/source3/smbd/smb2_service.c
index 06c20c16749..b6e8ca54e85 100644
--- a/source3/smbd/smb2_service.c
+++ b/source3/smbd/smb2_service.c
@@ -755,7 +755,6 @@ NTSTATUS make_connection_snum(struct smbXsrv_connection *xconn,
 	if (!IS_IPC(conn) && !IS_PRINT(conn)) {
 		ok = set_namearray(conn,
 				   lp_veto_oplock_files(talloc_tos(), lp_sub, snum),
-				   NULL,
 				   &conn->veto_oplock_list);
 		if (!ok) {
 			status = NT_STATUS_NO_MEMORY;
@@ -763,7 +762,6 @@ NTSTATUS make_connection_snum(struct smbXsrv_connection *xconn,
 		}
 		ok = set_namearray(conn,
 				   lp_aio_write_behind(talloc_tos(), lp_sub, snum),
-				   NULL,
 				   &conn->aio_write_behind_list);
 		if (!ok) {
 			status = NT_STATUS_NO_MEMORY;
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index fa5f9bcc2f6..2f390651a0e 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -179,6 +179,81 @@ NTSTATUS check_user_share_access(connection_struct *conn,
 	return NT_STATUS_OK;
 }
 
+struct scan_file_list_state {
+	TALLOC_CTX *mem_ctx;
+	const struct loadparm_substitution *lp_sub;
+	int snum;
+	const char *param_type;
+	struct security_token *token;
+	struct name_compare_entry **list;
+	bool ok;
+};
+
+static bool scan_file_list_cb(const char *string,
+			      regmatch_t matches[],
+			      void *private_data)
+{
+	struct scan_file_list_state *state = private_data;
+
+	if (matches[1].rm_so == -1) {
+		DBG_WARNING("Found match, but no name??\n");
+		goto fail;
+	}
+	if (matches[1].rm_eo <= matches[1].rm_so) {
+		DBG_WARNING("Invalid match\n");
+		goto fail;
+	}
+
+	{
+		regoff_t len = matches[1].rm_eo - matches[1].rm_so;
+		char name[len + 1];
+		bool ok, match;
+		char *files = NULL;
+
+		memcpy(name, string + matches[1].rm_so, len);
+		name[len] = '\0';
+
+		DBG_DEBUG("Found name \"%s : %s\"\n", state->param_type, name);
+
+		ok = token_contains_name(talloc_tos(),
+					 NULL,
+					 NULL,
+					 NULL,
+					 state->token,
+					 name,
+					 &match);
+		if (!ok) {
+			goto fail;
+		}
+		if (!match) {
+			return false; /* don't stop traverse */
+		}
+
+		files = lp_parm_substituted_string(state->mem_ctx,
+						   state->lp_sub,
+						   state->snum,
+						   state->param_type,
+						   name,
+						   NULL);
+		if (files == NULL) {
+			goto fail;
+		}
+
+		ok = append_to_namearray(state->mem_ctx,


-- 
Samba Shared Repository



More information about the samba-cvs mailing list