[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Wed Sep 30 17:24:03 UTC 2020


The branch, master has been updated
       via  9f24b5098f7 smbclient: Fix recursive mget
       via  254a5b034e5 test3: Add a test showing that smbclient recursive mget is broken
       via  71bc4d4b8d9 smbclient: Slightly simplify do_mget()
       via  8fa451d2b05 smbclient: Remove the "abort_mget" variable
       via  9d14187c959 lib: Remove an optimization in string_replace()
       via  2c04e9a6f24 spoolss: Align some integer types
       via  44fd74476d1 spoolss: Align some integer types
       via  62237e6b97c smbd: process.c does not need libsmb.h
       via  2915522da47 smbd: Align integer types in gid_in_use()
       via  f67c8f95626 libsmb: Make cli_smb2_list() prototype more descriptive
       via  6ee90adf737 libsmb: Make cli_list() prototype more descriptive
      from  fca8cb63762 s3: smbd: Don't overwrite contents of fsp->aio_requests[0] with NULL via TALLOC_FREE().

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


- Log -----------------------------------------------------------------
commit 9f24b5098f796f364a3f403ad4e9ae28b3c0935a
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Sep 28 15:03:41 2020 +0200

    smbclient: Fix recursive mget
    
    Make do_mget rely on do_list() already doing the recursion in a
    breadth-first manner. The previous code called do_list() from within
    its callback. Unfortunately the recent simplifications of do_list()
    broke this, leading to recursive mget to segfault. Instead of figuring
    out how this worked before the simplifications in do_list() (I did
    spend a few hours on this) and fixing it, I chose to restructure
    do_mget() to not recursively call do_list() anymore but instead rely
    on do_list() to do the recursion. Saves quite a few lines of code and
    complexity.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=14517
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Wed Sep 30 17:23:45 UTC 2020 on sn-devel-184

commit 254a5b034e5a081c9d3f28717a4b54d2af0180fc
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Sep 28 16:29:27 2020 +0200

    test3: Add a test showing that smbclient recursive mget is broken
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=14517
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 71bc4d4b8d94458ac2e40d659f06110d434fd5c9
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Sep 28 14:21:24 2020 +0200

    smbclient: Slightly simplify do_mget()
    
    Put the prompt query into a separate if-statement, move the "quest"
    variable closer to its use
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=14517
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 8fa451d2b052223a11b24ffc2a956b80d03aaa7c
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Sep 28 14:11:13 2020 +0200

    smbclient: Remove the "abort_mget" variable
    
    This was never set to true anywhere in the code
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=14517
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 9d14187c95920670c0db5ccb47bdfe790482a3a7
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Sep 28 12:31:13 2020 +0200

    lib: Remove an optimization in string_replace()
    
    Why? This simplifies the code.
    
    Why do I believe we can do this? I don't think this is a very common
    operation in critical code paths. Also, next_codepoint() already has
    the same optimization. If this turns out to be a measurable
    performance issue, we should turn next_codepoint() into a static
    inline function doing the 7-bit optimized code path inlined the same
    way we did it for tdb_oob(). This way all callers would benefit from
    this optimization.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 2c04e9a6f245c60b25f21b022bc50b24901c58a0
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Sep 28 11:56:33 2020 +0200

    spoolss: Align some integer types
    
    SPOOLSS_NOTIFY_MSG_CTR->num_groups is defined as uint32_t
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 44fd74476d15344ff133c458226694a6254b5337
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Sep 28 11:55:57 2020 +0200

    spoolss: Align some integer types
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 62237e6b97c3e8ec27804966ce568c47faab5bc5
Author: Volker Lendecke <vl at samba.org>
Date:   Sun Sep 27 21:05:53 2020 +0200

    smbd: process.c does not need libsmb.h
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 2915522da472311f86a7cdb0eb1fa77ecebdd1ae
Author: Volker Lendecke <vl at samba.org>
Date:   Sun Sep 27 21:04:40 2020 +0200

    smbd: Align integer types in gid_in_use()
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit f67c8f95626518ac478513c2f7998655371e325c
Author: Volker Lendecke <vl at samba.org>
Date:   Sun Sep 27 13:43:19 2020 +0200

    libsmb: Make cli_smb2_list() prototype more descriptive
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 6ee90adf737db320095c82ebc8e582769fde9eba
Author: Volker Lendecke <vl at samba.org>
Date:   Sun Sep 27 11:41:48 2020 +0200

    libsmb: Make cli_list() prototype more descriptive
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

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

Summary of changes:
 lib/util/util_str_common.c                  |  34 +------
 source3/client/client.c                     | 152 ++++++++--------------------
 source3/libsmb/cli_smb2_fnum.c              |  16 +--
 source3/libsmb/cli_smb2_fnum.h              |  14 +--
 source3/libsmb/clilist.c                    |  16 ++-
 source3/libsmb/proto.h                      |  11 +-
 source3/rpc_server/spoolss/srv_spoolss_nt.c |   7 +-
 source3/script/tests/test_smbclient_mget.sh |  39 +++++++
 source3/selftest/tests.py                   |  10 ++
 source3/smbd/process.c                      |   3 +-
 10 files changed, 136 insertions(+), 166 deletions(-)
 create mode 100755 source3/script/tests/test_smbclient_mget.sh


Changeset truncated at 500 lines:

diff --git a/lib/util/util_str_common.c b/lib/util/util_str_common.c
index 1e93a46fbad..7bdba9a7a8c 100644
--- a/lib/util/util_str_common.c
+++ b/lib/util/util_str_common.c
@@ -72,40 +72,16 @@ _PUBLIC_ size_t ucs2_align(const void *base_ptr, const void *p, int flags)
 **/
 void string_replace( char *s, char oldc, char newc )
 {
-	char *p;
-
-	/* this is quite a common operation, so we want it to be
-	   fast. We optimise for the ascii case, knowing that all our
-	   supported multi-byte character sets are ascii-compatible
-	   (ie. they match for the first 128 chars) */
-
-	for (p = s; *p; p++) {
-		if (*p & 0x80) /* mb string - slow path. */
-			break;
-		if (*p == oldc) {
-			*p = newc;
-		}
-	}
-
-	if (!*p)
-		return;
-
-	/* Slow (mb) path. */
-#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
-	/* With compose characters we must restart from the beginning. JRA. */
-	p = s;
-#endif
-
-	while (*p) {
+	while (*s != '\0') {
 		size_t c_size;
-		next_codepoint(p, &c_size);
+		next_codepoint(s, &c_size);
 
 		if (c_size == 1) {
-			if (*p == oldc) {
-				*p = newc;
+			if (*s == oldc) {
+				*s = newc;
 			}
 		}
-		p += c_size;
+		s += c_size;
 	}
 }
 
diff --git a/source3/client/client.c b/source3/client/client.c
index 4b3ac1955e6..d6d5585f305 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -86,8 +86,6 @@ static char dest_ss_str[INET6_ADDRSTRLEN];
 
 #define SEPARATORS " \t\n\r"
 
-static bool abort_mget = true;
-
 /* timing globals */
 uint64_t get_total_size = 0;
 unsigned int get_total_time_ms = 0;
@@ -1202,12 +1200,10 @@ static NTSTATUS do_mget(struct cli_state *cli_state, struct file_info *finfo,
 		    const char *dir)
 {
 	TALLOC_CTX *ctx = talloc_tos();
-	NTSTATUS status = NT_STATUS_OK;
-	char *rname = NULL;
-	char *quest = NULL;
-	char *saved_curdir = NULL;
-	char *mget_mask = NULL;
-	char *new_cd = NULL;
+	const char *client_cwd = NULL;
+	size_t client_cwd_len;
+	char *path = NULL;
+	char *local_path = NULL;
 
 	if (!finfo->name) {
 		return NT_STATUS_OK;
@@ -1216,121 +1212,63 @@ static NTSTATUS do_mget(struct cli_state *cli_state, struct file_info *finfo,
 	if (strequal(finfo->name,".") || strequal(finfo->name,".."))
 		return NT_STATUS_OK;
 
-	if (abort_mget)	{
-		d_printf("mget aborted\n");
-		return NT_STATUS_UNSUCCESSFUL;
-	}
-
-	if (finfo->attr & FILE_ATTRIBUTE_DIRECTORY) {
-		if (asprintf(&quest,
-			 "Get directory %s? ",finfo->name) < 0) {
-			return NT_STATUS_NO_MEMORY;
-		}
-	} else {
-		if (asprintf(&quest,
-			 "Get file %s? ",finfo->name) < 0) {
-			return NT_STATUS_NO_MEMORY;
-		}
-	}
-
-	if (prompt && !yesno(quest)) {
-		SAFE_FREE(quest);
+	if ((finfo->attr & FILE_ATTRIBUTE_DIRECTORY) && !recurse) {
 		return NT_STATUS_OK;
 	}
-	SAFE_FREE(quest);
 
-	if (!(finfo->attr & FILE_ATTRIBUTE_DIRECTORY)) {
-		rname = talloc_asprintf(ctx,
-				"%s%s",
-				client_get_cur_dir(),
-				finfo->name);
-		if (!rname) {
+	if (prompt) {
+		const char *object = (finfo->attr & FILE_ATTRIBUTE_DIRECTORY) ?
+			"directory" : "file";
+		char *quest = NULL;
+		bool ok;
+
+		quest = talloc_asprintf(
+			ctx, "Get %s %s? ", object, finfo->name);
+		if (quest == NULL) {
 			return NT_STATUS_NO_MEMORY;
 		}
-		rname = client_clean_name(ctx, rname);
-		if (rname == NULL) {
-			return NT_STATUS_NO_MEMORY;
+
+		ok = yesno(quest);
+		TALLOC_FREE(quest);
+		if (!ok) {
+			return NT_STATUS_OK;
 		}
-		do_get(rname, finfo->name, false);
-		TALLOC_FREE(rname);
-		return NT_STATUS_OK;
 	}
 
-	/* handle directories */
-	saved_curdir = talloc_strdup(ctx, client_get_cur_dir());
-	if (!saved_curdir) {
+	path = talloc_asprintf(
+		ctx, "%s%c%s", dir, CLI_DIRSEP_CHAR, finfo->name);
+	if (path == NULL) {
 		return NT_STATUS_NO_MEMORY;
 	}
-
-	new_cd = talloc_asprintf(ctx,
-				"%s%s%s",
-				client_get_cur_dir(),
-				finfo->name,
-				CLI_DIRSEP_STR);
-	if (!new_cd) {
+	path = client_clean_name(ctx, path);
+	if (path == NULL) {
 		return NT_STATUS_NO_MEMORY;
 	}
-	new_cd = client_clean_name(ctx, new_cd);
-	if (new_cd == NULL) {
-		return NT_STATUS_NO_MEMORY;
-	}
-	client_set_cur_dir(new_cd);
-
-	string_replace(finfo->name,'\\','/');
-	if (lowercase) {
-		if (!strlower_m(finfo->name)) {
-			return NT_STATUS_INVALID_PARAMETER;
-		}
-	}
 
-	if (!directory_exist(finfo->name) &&
-	    mkdir(finfo->name,0777) != 0) {
-		d_printf("failed to create directory %s\n",finfo->name);
-		client_set_cur_dir(saved_curdir);
-		return map_nt_error_from_unix(errno);
-	}
-
-	if (chdir(finfo->name) != 0) {
-		d_printf("failed to chdir to directory %s\n",finfo->name);
-		client_set_cur_dir(saved_curdir);
-		return map_nt_error_from_unix(errno);
-	}
-
-	mget_mask = talloc_asprintf(ctx,
-			"%s*",
-			client_get_cur_dir());
+	/*
+	 * Skip the path prefix if we've done a remote "cd" when
+	 * creating the local path
+	 */
+	client_cwd = client_get_cur_dir();
+	client_cwd_len = strlen(client_cwd);
 
-	if (!mget_mask) {
+	local_path = talloc_strdup(ctx, path + client_cwd_len);
+	if (local_path == NULL) {
+		TALLOC_FREE(path);
 		return NT_STATUS_NO_MEMORY;
 	}
+	string_replace(local_path, CLI_DIRSEP_CHAR, '/');
 
-	mget_mask = client_clean_name(ctx, mget_mask);
-	if (mget_mask == NULL) {
-		return NT_STATUS_NO_MEMORY;
-	}
-	status = do_list(mget_mask,
-			 (FILE_ATTRIBUTE_SYSTEM
-			  | FILE_ATTRIBUTE_HIDDEN
-			  | FILE_ATTRIBUTE_DIRECTORY),
-			 do_mget, false, true);
-	if (!NT_STATUS_IS_OK(status)
-	 && !NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
-		/*
-		 * Ignore access denied errors to ensure all permitted files are
-		 * pulled down.
-		 */
-		return status;
-	}
+	if (finfo->attr & FILE_ATTRIBUTE_DIRECTORY) {
+		int ret = mkdir(local_path, 0777);
 
-	if (chdir("..") == -1) {
-		d_printf("do_mget: failed to chdir to .. (error %s)\n",
-			strerror(errno) );
-		return map_nt_error_from_unix(errno);
+		if ((ret == -1) && (errno != EEXIST)) {
+			return map_nt_error_from_unix(errno);
+		}
+	} else {
+		do_get(path, local_path, false);
 	}
-	client_set_cur_dir(saved_curdir);
-	TALLOC_FREE(mget_mask);
-	TALLOC_FREE(saved_curdir);
-	TALLOC_FREE(new_cd);
+
 	return NT_STATUS_OK;
 }
 
@@ -1418,8 +1356,6 @@ static int cmd_mget(void)
 		attribute |= FILE_ATTRIBUTE_DIRECTORY;
 	}
 
-	abort_mget = false;
-
 	while (next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) {
 
 		mget_mask = talloc_strdup(ctx, client_get_cur_dir());
@@ -1439,7 +1375,7 @@ static int cmd_mget(void)
 		if (mget_mask == NULL) {
 			return 1;
 		}
-		status = do_list(mget_mask, attribute, do_mget, false, true);
+		status = do_list(mget_mask, attribute, do_mget, recurse, true);
 		if (!NT_STATUS_IS_OK(status)) {
 			return 1;
 		}
@@ -1461,7 +1397,7 @@ static int cmd_mget(void)
 		if (mget_mask == NULL) {
 			return 1;
 		}
-		status = do_list(mget_mask, attribute, do_mget, false, true);
+		status = do_list(mget_mask, attribute, do_mget, recurse, true);
 		if (!NT_STATUS_IS_OK(status)) {
 			return 1;
 		}
diff --git a/source3/libsmb/cli_smb2_fnum.c b/source3/libsmb/cli_smb2_fnum.c
index 2b8f9a0e742..c19fc4d7d39 100644
--- a/source3/libsmb/cli_smb2_fnum.c
+++ b/source3/libsmb/cli_smb2_fnum.c
@@ -1285,13 +1285,13 @@ static bool windows_parent_dirname(TALLOC_CTX *mem_ctx,
 ***************************************************************/
 
 NTSTATUS cli_smb2_list(struct cli_state *cli,
-			const char *pathname,
-			uint32_t attribute,
-			NTSTATUS (*fn)(const char *,
-				struct file_info *,
-				const char *,
-				void *),
-			void *state)
+		       const char *pathname,
+		       uint32_t attribute,
+		       NTSTATUS (*fn)(const char *mointpoint,
+				      struct file_info *finfo,
+				      const char *mask,
+				      void *private_data),
+		       void *private_data)
 {
 	NTSTATUS status;
 	uint16_t fnum = 0xffff;
@@ -1433,7 +1433,7 @@ NTSTATUS cli_smb2_list(struct cli_state *cli,
 				status = fn(cli->dfs_mountpoint,
 					finfo,
 					pathname,
-					state);
+					private_data);
 
 				if (!NT_STATUS_IS_OK(status)) {
 					break;
diff --git a/source3/libsmb/cli_smb2_fnum.h b/source3/libsmb/cli_smb2_fnum.h
index 06f939d6dbf..e24c8cb7279 100644
--- a/source3/libsmb/cli_smb2_fnum.h
+++ b/source3/libsmb/cli_smb2_fnum.h
@@ -94,13 +94,13 @@ struct tevent_req *cli_smb2_unlink_send(
 	const struct smb2_create_blobs *in_cblobs);
 NTSTATUS cli_smb2_unlink_recv(struct tevent_req *req);
 NTSTATUS cli_smb2_list(struct cli_state *cli,
-			const char *pathname,
-			uint32_t attribute,
-			NTSTATUS (*fn)(const char *,
-				struct file_info *,
-				const char *,
-				void *),
-			void *state);
+		       const char *pathname,
+		       uint32_t attribute,
+		       NTSTATUS (*fn)(const char *mointpoint,
+				      struct file_info *finfo,
+				      const char *mask,
+				      void *private_data),
+		       void *private_data);
 NTSTATUS cli_smb2_qpathinfo_basic(struct cli_state *cli,
 			const char *name,
 			SMB_STRUCT_STAT *sbuf,
diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c
index 3a0c10e55b0..59404bce7bf 100644
--- a/source3/libsmb/clilist.c
+++ b/source3/libsmb/clilist.c
@@ -1037,9 +1037,14 @@ NTSTATUS cli_list_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
 	return NT_STATUS_OK;
 }
 
-NTSTATUS cli_list(struct cli_state *cli, const char *mask, uint32_t attribute,
-		  NTSTATUS (*fn)(const char *, struct file_info *, const char *,
-			     void *), void *state)
+NTSTATUS cli_list(struct cli_state *cli,
+		  const char *mask,
+		  uint32_t attribute,
+		  NTSTATUS (*fn)(const char *mointpoint,
+				 struct file_info *finfo,
+				 const char *mask,
+				 void *private_data),
+		  void *private_data)
 {
 	TALLOC_CTX *frame = NULL;
 	struct tevent_context *ev;
@@ -1050,7 +1055,7 @@ NTSTATUS cli_list(struct cli_state *cli, const char *mask, uint32_t attribute,
 	uint16_t info_level;
 
 	if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
-		return cli_smb2_list(cli, mask, attribute, fn, state);
+		return cli_smb2_list(cli, mask, attribute, fn, private_data);
 	}
 
 	frame = talloc_stackframe();
@@ -1084,7 +1089,8 @@ NTSTATUS cli_list(struct cli_state *cli, const char *mask, uint32_t attribute,
 	}
 
 	for (i=0; i<num_finfo; i++) {
-		status = fn(cli->dfs_mountpoint, &finfo[i], mask, state);
+		status = fn(
+			cli->dfs_mountpoint, &finfo[i], mask, private_data);
 		if (!NT_STATUS_IS_OK(status)) {
 			goto fail;
 		}
diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h
index eeabcaa7463..cb42df88426 100644
--- a/source3/libsmb/proto.h
+++ b/source3/libsmb/proto.h
@@ -760,9 +760,14 @@ struct tevent_req *cli_list_send(TALLOC_CTX *mem_ctx,
 				 uint16_t info_level);
 NTSTATUS cli_list_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
 		       struct file_info **finfo, size_t *num_finfo);
-NTSTATUS cli_list(struct cli_state *cli,const char *Mask,uint32_t attribute,
-		  NTSTATUS (*fn)(const char *, struct file_info *, const char *,
-			     void *), void *state);
+NTSTATUS cli_list(struct cli_state *cli,
+		  const char *mask,
+		  uint32_t attribute,
+		  NTSTATUS (*fn)(const char *mointpoint,
+				 struct file_info *finfo,
+				 const char *mask,
+				 void *private_data),
+		  void *private_data);
 
 /* The following definitions come from libsmb/climessage.c  */
 
diff --git a/source3/rpc_server/spoolss/srv_spoolss_nt.c b/source3/rpc_server/spoolss/srv_spoolss_nt.c
index 055ff172526..0f2cfd7d690 100644
--- a/source3/rpc_server/spoolss/srv_spoolss_nt.c
+++ b/source3/rpc_server/spoolss/srv_spoolss_nt.c
@@ -1020,7 +1020,7 @@ static SPOOLSS_NOTIFY_MSG_GROUP* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR *ct
  How many groups of change messages do we have ?
  **********************************************************************/
 
-static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR *ctr )
+static uint32_t notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR *ctr )
 {
 	if ( !ctr )
 		return 0;
@@ -1037,7 +1037,7 @@ static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR *ctr, SPOOLSS_NOTIFY_MS
 	SPOOLSS_NOTIFY_MSG_GROUP	*groups = NULL;
 	SPOOLSS_NOTIFY_MSG_GROUP	*msg_grp = NULL;
 	SPOOLSS_NOTIFY_MSG		*msg_list = NULL;
-	int				i, new_slot;
+	uint32_t			i, new_slot;
 
 	if ( !ctr || !msg )
 		return 0;
@@ -1364,13 +1364,12 @@ static void receive_notify2_message_list(struct messaging_context *msg,
 					 struct server_id server_id,
 					 DATA_BLOB *data)
 {
-	size_t 			msg_count, i;
+	size_t 			msg_count, i, num_groups;
 	char 			*buf = (char *)data->data;
 	char 			*msg_ptr;
 	size_t 			msg_len;
 	SPOOLSS_NOTIFY_MSG	notify;
 	SPOOLSS_NOTIFY_MSG_CTR	messages;
-	int			num_groups;
 
 	if (data->length < 4) {
 		DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n"));
diff --git a/source3/script/tests/test_smbclient_mget.sh b/source3/script/tests/test_smbclient_mget.sh
new file mode 100755
index 00000000000..45f62f15d4d
--- /dev/null
+++ b/source3/script/tests/test_smbclient_mget.sh
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+if [ $# -lt 6 ]; then
+cat <<EOF
+Usage: $0 smbclient3 server share user password directory
+EOF
+exit 1;
+fi
+
+incdir=`dirname $0`/../../../testprogs/blackbox
+. $incdir/subunit.sh
+
+failed=0
+
+SMBCLIENT3="$1"; shift
+SERVER="$1"; shift
+SHARE="$1"; shift
+USERNAME="$1"; shift
+PASSWORD="$1"; shift
+DIRECTORY="$1"; shift
+
+# Can't use "testit" here -- it somehow breaks the -c command passed
+# to smbclient into two, spoiling the "mget"
+
+name="smbclient mget"
+subunit_start_test "$name"
+output=$("$SMBCLIENT3" //"$SERVER"/"$SHARE" \
+         -U"$USERNAME"%"$PASSWORD" -c "recurse;prompt;mget $DIRECTORY")
+status=$?
+if [ x$status = x0 ]; then
+    subunit_pass_test "$name"
+else
+    echo "$output" | subunit_fail_test "$name"
+fi
+
+testit "rm foo" rm "$DIRECTORY"/foo || failed=`expr $failed + 1`
+testit "rmdir $DIRECTORY" rmdir "$DIRECTORY" || failed=`expr $failed + 1`
+
+testok $0 $failed
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index a8e8be8eb87..c307e9c16e9 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -1112,6 +1112,16 @@ for env in ["ad_member_idmap_rid:local", "maptoguest:local"]:
 
 plantestsuite("samba3.blackbox.itime", "ad_dc", [os.path.join(samba3srcdir, "script/tests/test_itime.sh"), '$SERVER', '$USERNAME', '$PASSWORD', '$LOCAL_PATH', smbclient3, 'xattr'])
 
+plantestsuite("samba3.blackbox.smbclient-mget",
+              "fileserver",
+              [os.path.join(samba3srcdir, "script/tests/test_smbclient_mget.sh"),
+               smbclient3,
+               "$SERVER",
+               "tmp",
+               "$USERNAME",
+               "$PASSWORD",
+               "valid_users"])
+
 t = "readdir-timestamp"
 plantestsuite(
     "samba3.smbtorture_s3.plain.%s" % t,
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 5205674a006..2b2a2e09d05 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -35,7 +35,6 @@
 #include "lib/messages_ctdb.h"
 #include "smbprofile.h"
 #include "rpc_server/spoolss/srv_spoolss_nt.h"


-- 
Samba Shared Repository



More information about the samba-cvs mailing list