[PATCH] Master fix for bug #9518 - conn->share_access appears not be be reset between users

Jeremy Allison jra at samba.org
Fri Jan 4 17:12:55 MST 2013


Please review and apply to master if ok. It includes
Andrew's regression test patch also.

Cheers,

	Jeremy.
-------------- next part --------------
>From 19a74f3a5034433ba70d8bc37890296f9858b210 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Thu, 20 Dec 2012 11:50:25 -0800
Subject: [PATCH 01/19] Start to tidy-up check_user_ok().

Now we have removed "security=share" we cannot be
called with vuid == UID_FIELD_INVALID.

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/smbd/uid.c |    5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index 30c7154..2aa9fff 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -90,12 +90,11 @@ static bool check_user_ok(connection_struct *conn,
 			const struct auth_session_info *session_info,
 			int snum)
 {
-	bool valid_vuid = (vuid != UID_FIELD_INVALID);
 	unsigned int i;
 	bool readonly_share;
 	bool admin_user;
 
-	if (valid_vuid) {
+	{
 		struct vuid_cache_entry *ent;
 
 		for (i=0; i<VUID_CACHE_SIZE; i++) {
@@ -145,7 +144,7 @@ static bool check_user_ok(connection_struct *conn,
 		session_info->info->domain_name,
 		NULL, session_info->security_token, lp_admin_users(snum));
 
-	if (valid_vuid) {
+	{
 		struct vuid_cache_entry *ent =
 			&conn->vuid_cache.array[conn->vuid_cache.next_entry];
 
-- 
1.7.7.3


>From a8da93b0c212883678c577ac3df462c3ed302761 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Thu, 20 Dec 2012 11:51:55 -0800
Subject: [PATCH 02/19] Move the definition of struct vuid_cache_entry *ent
 outside blocks.

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

diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index 2aa9fff..9361e49 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -93,10 +93,9 @@ static bool check_user_ok(connection_struct *conn,
 	unsigned int i;
 	bool readonly_share;
 	bool admin_user;
+	struct vuid_cache_entry *ent = NULL;
 
 	{
-		struct vuid_cache_entry *ent;
-
 		for (i=0; i<VUID_CACHE_SIZE; i++) {
 			ent = &conn->vuid_cache.array[i];
 			if (ent->vuid == vuid) {
@@ -145,8 +144,7 @@ static bool check_user_ok(connection_struct *conn,
 		NULL, session_info->security_token, lp_admin_users(snum));
 
 	{
-		struct vuid_cache_entry *ent =
-			&conn->vuid_cache.array[conn->vuid_cache.next_entry];
+		ent = &conn->vuid_cache.array[conn->vuid_cache.next_entry];
 
 		conn->vuid_cache.next_entry =
 			(conn->vuid_cache.next_entry + 1) % VUID_CACHE_SIZE;
-- 
1.7.7.3


>From 7d1bb90ed5567e7cafdf083aa5491c1a8171421f Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Thu, 20 Dec 2012 11:52:27 -0800
Subject: [PATCH 03/19] Remove one set of enclosing {} braces, no longer
 needed.

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/smbd/uid.c |   16 +++++++---------
 1 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index 9361e49..9109f05 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -95,15 +95,13 @@ static bool check_user_ok(connection_struct *conn,
 	bool admin_user;
 	struct vuid_cache_entry *ent = NULL;
 
-	{
-		for (i=0; i<VUID_CACHE_SIZE; i++) {
-			ent = &conn->vuid_cache.array[i];
-			if (ent->vuid == vuid) {
-				free_conn_session_info_if_unused(conn);
-				conn->session_info = ent->session_info;
-				conn->read_only = ent->read_only;
-				return(True);
-			}
+	for (i=0; i<VUID_CACHE_SIZE; i++) {
+		ent = &conn->vuid_cache.array[i];
+		if (ent->vuid == vuid) {
+			free_conn_session_info_if_unused(conn);
+			conn->session_info = ent->session_info;
+			conn->read_only = ent->read_only;
+			return(True);
 		}
 	}
 
-- 
1.7.7.3


>From 5eb466e6db0af7796febafb84fc2ce593e9b8e62 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Thu, 20 Dec 2012 11:53:11 -0800
Subject: [PATCH 04/19] Remove the second set of {} braces, no longer needed.

---
 source3/smbd/uid.c |   38 ++++++++++++++++++--------------------
 1 files changed, 18 insertions(+), 20 deletions(-)

diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index 9109f05..9fc5d7c 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -141,33 +141,31 @@ static bool check_user_ok(connection_struct *conn,
 		session_info->info->domain_name,
 		NULL, session_info->security_token, lp_admin_users(snum));
 
-	{
-		ent = &conn->vuid_cache.array[conn->vuid_cache.next_entry];
+	ent = &conn->vuid_cache.array[conn->vuid_cache.next_entry];
 
-		conn->vuid_cache.next_entry =
-			(conn->vuid_cache.next_entry + 1) % VUID_CACHE_SIZE;
+	conn->vuid_cache.next_entry =
+		(conn->vuid_cache.next_entry + 1) % VUID_CACHE_SIZE;
 
-		TALLOC_FREE(ent->session_info);
+	TALLOC_FREE(ent->session_info);
 
-		/*
-		 * If force_user was set, all session_info's are based on the same
-		 * username-based faked one.
-		 */
-
-		ent->session_info = copy_session_info(
-			conn, conn->force_user ? conn->session_info : session_info);
+	/*
+	 * If force_user was set, all session_info's are based on the same
+	 * username-based faked one.
+	 */
 
-		if (ent->session_info == NULL) {
-			ent->vuid = UID_FIELD_INVALID;
-			return false;
-		}
+	ent->session_info = copy_session_info(
+		conn, conn->force_user ? conn->session_info : session_info);
 
-		ent->vuid = vuid;
-		ent->read_only = readonly_share;
-		free_conn_session_info_if_unused(conn);
-		conn->session_info = ent->session_info;
+	if (ent->session_info == NULL) {
+		ent->vuid = UID_FIELD_INVALID;
+		return false;
 	}
 
+	ent->vuid = vuid;
+	ent->read_only = readonly_share;
+	free_conn_session_info_if_unused(conn);
+	conn->session_info = ent->session_info;
+
 	conn->read_only = readonly_share;
 	if (admin_user) {
 		DEBUG(2,("check_user_ok: user %s is an admin user. "
-- 
1.7.7.3


>From 0f47a383145b2bd560611c9cf34eb4c2f78740be Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Thu, 20 Dec 2012 11:54:07 -0800
Subject: [PATCH 05/19] Remove dead code now vuser can no longer be NULL.

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/smbd/uid.c |    8 --------
 1 files changed, 0 insertions(+), 8 deletions(-)

diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index 9fc5d7c..298fa83 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -299,14 +299,6 @@ bool change_to_user(connection_struct *conn, uint64_t vuid)
 	}
 
 	session_info = vuser->session_info;
-
-	if (!conn->force_user && vuser == NULL) {
-		DEBUG(2,("Invalid vuid used %llu in accessing share %s.\n",
-			 (unsigned long long)vuid,
-			 lp_servicename(talloc_tos(), snum)));
-		return False;
-	}
-
 	return change_to_user_internal(conn, session_info, vuid);
 }
 
-- 
1.7.7.3


>From ef8b0c42df91bd38a1b47281ff6806b46c2814c4 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Thu, 20 Dec 2012 11:55:09 -0800
Subject: [PATCH 06/19] Remove unneeded variable "const struct
 auth_session_info *session_info"

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/smbd/uid.c |    4 +---
 1 files changed, 1 insertions(+), 3 deletions(-)

diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index 298fa83..9244f29 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -271,7 +271,6 @@ static bool change_to_user_internal(connection_struct *conn,
 
 bool change_to_user(connection_struct *conn, uint64_t vuid)
 {
-	const struct auth_session_info *session_info = NULL;
 	struct user_struct *vuser;
 	int snum = SNUM(conn);
 
@@ -298,8 +297,7 @@ bool change_to_user(connection_struct *conn, uint64_t vuid)
 		return false;
 	}
 
-	session_info = vuser->session_info;
-	return change_to_user_internal(conn, session_info, vuid);
+	return change_to_user_internal(conn, vuser->session_info, vuid);
 }
 
 static bool change_to_user_by_session(connection_struct *conn,
-- 
1.7.7.3


>From af5908f8291ea38c0b015f4aa987ac76d6993748 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Thu, 20 Dec 2012 14:42:55 -0800
Subject: [PATCH 07/19] Clean up struct connection_struct, make struct
 vuid_cache a pointer not inline.

Change VFS ABI to 31 for 4.1.0.

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/include/vfs.h          |    8 ++++++--
 source3/modules/vfs_readonly.c |    4 ++--
 source3/smbd/conn.c            |    3 ++-
 source3/smbd/uid.c             |   10 +++++-----
 4 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index 2992c1d..7da022e 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -147,7 +147,11 @@
 /* Bump to version 30 - Samba 4.0.0 will ship with interface version 30 */
 /* Leave at 30 - not yet released. Added conn->cwd to save vfs_GetWd() calls. */
 /* Leave at 30 - not yet released. Changed sys_acl_blob_get_file interface to remove type */
-#define SMB_VFS_INTERFACE_VERSION 30
+/* Bump to version 31 - Samba 4.1.0 will ship with interface version 31 */
+/* Leave at 31 - not yet released. Make struct vuid_cache_entry in
+		connection_struct a pointer. */
+
+#define SMB_VFS_INTERFACE_VERSION 31
 
 /*
     All intercepted VFS operations must be declared as static functions inside module source
@@ -306,7 +310,7 @@ typedef struct connection_struct {
 	uint32_t cnum; /* an index passed over the wire */
 	struct share_params *params;
 	bool force_user;
-	struct vuid_cache vuid_cache;
+	struct vuid_cache *vuid_cache;
 	bool printer;
 	bool ipc;
 	bool read_only; /* Attributes for the current user of the share. */
diff --git a/source3/modules/vfs_readonly.c b/source3/modules/vfs_readonly.c
index 7919dbc..f75db09 100644
--- a/source3/modules/vfs_readonly.c
+++ b/source3/modules/vfs_readonly.c
@@ -82,12 +82,12 @@ static int readonly_connect(vfs_handle_struct *handle,
 
       /* Wipe out the VUID cache. */
       for (i=0; i< VUID_CACHE_SIZE; i++) {
-        struct vuid_cache_entry *ent = &conn->vuid_cache.array[i];
+        struct vuid_cache_entry *ent = &conn->vuid_cache->array[i];
         ent->vuid = UID_FIELD_INVALID;
         TALLOC_FREE(ent->session_info);
         ent->read_only = false;
       }
-      conn->vuid_cache.next_entry = 0;
+      conn->vuid_cache->next_entry = 0;
     }
 
     return 0;
diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c
index bc5a03b..1d4444f 100644
--- a/source3/smbd/conn.c
+++ b/source3/smbd/conn.c
@@ -63,6 +63,7 @@ connection_struct *conn_new(struct smbd_server_connection *sconn)
 
 	if (!(conn=talloc_zero(NULL, connection_struct)) ||
 	    !(conn->params = talloc(conn, struct share_params)) ||
+	    !(conn->vuid_cache = talloc_zero(conn, struct vuid_cache)) ||
 	    !(conn->connectpath = talloc_strdup(conn, "")) ||
 	    !(conn->origpath = talloc_strdup(conn, ""))) {
 		DEBUG(0,("TALLOC_ZERO() failed!\n"));
@@ -89,7 +90,7 @@ static void conn_clear_vuid_cache(connection_struct *conn, uint64_t vuid)
 	for (i=0; i<VUID_CACHE_SIZE; i++) {
 		struct vuid_cache_entry *ent;
 
-		ent = &conn->vuid_cache.array[i];
+		ent = &conn->vuid_cache->array[i];
 
 		if (ent->vuid == vuid) {
 			ent->vuid = UID_FIELD_INVALID;
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index 9244f29..f9b5716 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -68,7 +68,7 @@ static void free_conn_session_info_if_unused(connection_struct *conn)
 
 	for (i = 0; i < VUID_CACHE_SIZE; i++) {
 		struct vuid_cache_entry *ent;
-		ent = &conn->vuid_cache.array[i];
+		ent = &conn->vuid_cache->array[i];
 		if (ent->vuid != UID_FIELD_INVALID &&
 				conn->session_info == ent->session_info) {
 			return;
@@ -96,7 +96,7 @@ static bool check_user_ok(connection_struct *conn,
 	struct vuid_cache_entry *ent = NULL;
 
 	for (i=0; i<VUID_CACHE_SIZE; i++) {
-		ent = &conn->vuid_cache.array[i];
+		ent = &conn->vuid_cache->array[i];
 		if (ent->vuid == vuid) {
 			free_conn_session_info_if_unused(conn);
 			conn->session_info = ent->session_info;
@@ -141,10 +141,10 @@ static bool check_user_ok(connection_struct *conn,
 		session_info->info->domain_name,
 		NULL, session_info->security_token, lp_admin_users(snum));
 
-	ent = &conn->vuid_cache.array[conn->vuid_cache.next_entry];
+	ent = &conn->vuid_cache->array[conn->vuid_cache->next_entry];
 
-	conn->vuid_cache.next_entry =
-		(conn->vuid_cache.next_entry + 1) % VUID_CACHE_SIZE;
+	conn->vuid_cache->next_entry =
+		(conn->vuid_cache->next_entry + 1) % VUID_CACHE_SIZE;
 
 	TALLOC_FREE(ent->session_info);
 
-- 
1.7.7.3


>From 74798ecfbab22123796329a010b18a02dd2e15db Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Fri, 21 Dec 2012 09:22:16 -0800
Subject: [PATCH 08/19] Add uint32_t share_access to vuid_cache_entry.

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/include/vfs.h          |    2 ++
 source3/modules/vfs_readonly.c |    1 +
 source3/smbd/conn.c            |    1 +
 3 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index 7da022e..2bce1b7 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -150,6 +150,7 @@
 /* Bump to version 31 - Samba 4.1.0 will ship with interface version 31 */
 /* Leave at 31 - not yet released. Make struct vuid_cache_entry in
 		connection_struct a pointer. */
+/* Leave at 31 - not yet released. Add share_access to vuid_cache_entry. */
 
 #define SMB_VFS_INTERFACE_VERSION 31
 
@@ -279,6 +280,7 @@ struct vuid_cache_entry {
 	struct auth_session_info *session_info;
 	uint64_t vuid; /* SMB2 compat */
 	bool read_only;
+	uint32_t share_access;
 };
 
 struct vuid_cache {
diff --git a/source3/modules/vfs_readonly.c b/source3/modules/vfs_readonly.c
index f75db09..445f947 100644
--- a/source3/modules/vfs_readonly.c
+++ b/source3/modules/vfs_readonly.c
@@ -86,6 +86,7 @@ static int readonly_connect(vfs_handle_struct *handle,
         ent->vuid = UID_FIELD_INVALID;
         TALLOC_FREE(ent->session_info);
         ent->read_only = false;
+        ent->share_access = 0;
       }
       conn->vuid_cache->next_entry = 0;
     }
diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c
index 1d4444f..8f472c0 100644
--- a/source3/smbd/conn.c
+++ b/source3/smbd/conn.c
@@ -118,6 +118,7 @@ static void conn_clear_vuid_cache(connection_struct *conn, uint64_t vuid)
 				TALLOC_FREE(ent->session_info);
 			}
 			ent->read_only = False;
+			ent->share_access = 0;
 		}
 	}
 }
-- 
1.7.7.3


>From 4d48fc9a6779ed2ad8552c5753cb447c003b2509 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Fri, 21 Dec 2012 09:35:31 -0800
Subject: [PATCH 09/19] Remove static from create_share_access_mask().

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/smbd/proto.h   |    1 +
 source3/smbd/service.c |    2 +-
 2 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index 9a9a010..c9efefc 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -971,6 +971,7 @@ void smbd_exit_server_cleanly(const char *const reason) _NORETURN_;
 
 bool set_conn_connectpath(connection_struct *conn, const char *connectpath);
 NTSTATUS set_conn_force_user_group(connection_struct *conn, int snum);
+void create_share_access_mask(connection_struct *conn, int snum);
 bool set_current_service(connection_struct *conn, uint16 flags, bool do_chdir);
 void load_registry_shares(void);
 int add_home_service(const char *service, const char *username, const char *homedir);
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index 2214ac0..828c036 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -515,7 +515,7 @@ NTSTATUS set_conn_force_user_group(connection_struct *conn, int snum)
   Setup the share access mask for a connection.
 ****************************************************************************/
 
-static void create_share_access_mask(connection_struct *conn, int snum)
+void create_share_access_mask(connection_struct *conn, int snum)
 {
 	const struct security_token *token = conn->session_info->security_token;
 
-- 
1.7.7.3


>From e6552427b26d835cefa16a96a80a6011ed902f98 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Fri, 21 Dec 2012 09:45:03 -0800
Subject: [PATCH 10/19] Fix API for create_share_access_mask().

Return the uint32_t share_access rather than directly
changing the conn struct.

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/smbd/proto.h   |    2 +-
 source3/smbd/service.c |   19 +++++++++++--------
 2 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index c9efefc..abcc2e5 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -971,7 +971,7 @@ void smbd_exit_server_cleanly(const char *const reason) _NORETURN_;
 
 bool set_conn_connectpath(connection_struct *conn, const char *connectpath);
 NTSTATUS set_conn_force_user_group(connection_struct *conn, int snum);
-void create_share_access_mask(connection_struct *conn, int snum);
+uint32_t create_share_access_mask(connection_struct *conn, int snum);
 bool set_current_service(connection_struct *conn, uint16 flags, bool do_chdir);
 void load_registry_shares(void);
 int add_home_service(const char *service, const char *username, const char *homedir);
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index 828c036..1cd12a6 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -515,34 +515,37 @@ NTSTATUS set_conn_force_user_group(connection_struct *conn, int snum)
   Setup the share access mask for a connection.
 ****************************************************************************/
 
-void create_share_access_mask(connection_struct *conn, int snum)
+uint32_t create_share_access_mask(connection_struct *conn, int snum)
 {
 	const struct security_token *token = conn->session_info->security_token;
+	uint32_t share_access = 0;
 
 	share_access_check(token,
 			lp_servicename(talloc_tos(), snum),
 			MAXIMUM_ALLOWED_ACCESS,
-			&conn->share_access);
+			&share_access);
 
 	if (!CAN_WRITE(conn)) {
-		conn->share_access &=
+		share_access &=
 			~(SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA |
 			  SEC_FILE_WRITE_EA | SEC_FILE_WRITE_ATTRIBUTE |
 			  SEC_DIR_DELETE_CHILD );
 	}
 
 	if (security_token_has_privilege(token, SEC_PRIV_SECURITY)) {
-		conn->share_access |= SEC_FLAG_SYSTEM_SECURITY;
+		share_access |= SEC_FLAG_SYSTEM_SECURITY;
 	}
 	if (security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
-		conn->share_access |= (SEC_RIGHTS_PRIV_RESTORE);
+		share_access |= (SEC_RIGHTS_PRIV_RESTORE);
 	}
 	if (security_token_has_privilege(token, SEC_PRIV_BACKUP)) {
-		conn->share_access |= (SEC_RIGHTS_PRIV_BACKUP);
+		share_access |= (SEC_RIGHTS_PRIV_BACKUP);
 	}
 	if (security_token_has_privilege(token, SEC_PRIV_TAKE_OWNERSHIP)) {
-		conn->share_access |= (SEC_STD_WRITE_OWNER);
+		share_access |= (SEC_STD_WRITE_OWNER);
 	}
+
+	return share_access;
 }
 
 /****************************************************************************
@@ -654,7 +657,7 @@ static NTSTATUS make_connection_snum(struct smbd_server_connection *sconn,
 	 *
 	 */
 
-	create_share_access_mask(conn, snum);
+	conn->share_access = create_share_access_mask(conn, snum);
 
 	if ((conn->share_access & FILE_WRITE_DATA) == 0) {
 		if ((conn->share_access & FILE_READ_DATA) == 0) {
-- 
1.7.7.3


>From f61679ff2c0767ebb2cac93c25cafa1f541fe13d Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Fri, 4 Jan 2013 11:43:10 -0800
Subject: [PATCH 11/19] Change API for create_share_access_mask() to pass in
 the token.

Don't automatically use the one from conn->session_info->security_token.

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/smbd/proto.h   |    4 +++-
 source3/smbd/service.c |    9 ++++++---
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index abcc2e5..7d53a4b 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -971,7 +971,9 @@ void smbd_exit_server_cleanly(const char *const reason) _NORETURN_;
 
 bool set_conn_connectpath(connection_struct *conn, const char *connectpath);
 NTSTATUS set_conn_force_user_group(connection_struct *conn, int snum);
-uint32_t create_share_access_mask(connection_struct *conn, int snum);
+uint32_t create_share_access_mask(connection_struct *conn,
+			int snum,
+			const struct security_token *token);
 bool set_current_service(connection_struct *conn, uint16 flags, bool do_chdir);
 void load_registry_shares(void);
 int add_home_service(const char *service, const char *username, const char *homedir);
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index 1cd12a6..3e1d87f 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -515,9 +515,10 @@ NTSTATUS set_conn_force_user_group(connection_struct *conn, int snum)
   Setup the share access mask for a connection.
 ****************************************************************************/
 
-uint32_t create_share_access_mask(connection_struct *conn, int snum)
+uint32_t create_share_access_mask(connection_struct *conn,
+				int snum,
+				const struct security_token *token)
 {
-	const struct security_token *token = conn->session_info->security_token;
 	uint32_t share_access = 0;
 
 	share_access_check(token,
@@ -657,7 +658,9 @@ static NTSTATUS make_connection_snum(struct smbd_server_connection *sconn,
 	 *
 	 */
 
-	conn->share_access = create_share_access_mask(conn, snum);
+	conn->share_access = create_share_access_mask(conn,
+					snum,
+					conn->session_info->security_token);
 
 	if ((conn->share_access & FILE_WRITE_DATA) == 0) {
 		if ((conn->share_access & FILE_READ_DATA) == 0) {
-- 
1.7.7.3


>From 322b38605fa9285dccfc4ec86e801682247944fc Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Fri, 4 Jan 2013 14:24:13 -0800
Subject: [PATCH 12/19] Change API for create_share_access_mask() - remove
 conn struct.

Eventually this will be indepentent of conn, just pass in the
readonly flag.

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/smbd/proto.h   |    4 ++--
 source3/smbd/service.c |   10 +++++-----
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index 7d53a4b..ddb13a2 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -971,8 +971,8 @@ void smbd_exit_server_cleanly(const char *const reason) _NORETURN_;
 
 bool set_conn_connectpath(connection_struct *conn, const char *connectpath);
 NTSTATUS set_conn_force_user_group(connection_struct *conn, int snum);
-uint32_t create_share_access_mask(connection_struct *conn,
-			int snum,
+uint32_t create_share_access_mask(int snum,
+			bool readonly_share,
 			const struct security_token *token);
 bool set_current_service(connection_struct *conn, uint16 flags, bool do_chdir);
 void load_registry_shares(void);
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index 3e1d87f..10f4b53 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -515,8 +515,8 @@ NTSTATUS set_conn_force_user_group(connection_struct *conn, int snum)
   Setup the share access mask for a connection.
 ****************************************************************************/
 
-uint32_t create_share_access_mask(connection_struct *conn,
-				int snum,
+uint32_t create_share_access_mask(int snum,
+				bool readonly_share,
 				const struct security_token *token)
 {
 	uint32_t share_access = 0;
@@ -526,7 +526,7 @@ uint32_t create_share_access_mask(connection_struct *conn,
 			MAXIMUM_ALLOWED_ACCESS,
 			&share_access);
 
-	if (!CAN_WRITE(conn)) {
+	if (readonly_share) {
 		share_access &=
 			~(SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA |
 			  SEC_FILE_WRITE_EA | SEC_FILE_WRITE_ATTRIBUTE |
@@ -658,8 +658,8 @@ static NTSTATUS make_connection_snum(struct smbd_server_connection *sconn,
 	 *
 	 */
 
-	conn->share_access = create_share_access_mask(conn,
-					snum,
+	conn->share_access = create_share_access_mask(snum,
+					!CAN_WRITE(conn),
 					conn->session_info->security_token);
 
 	if ((conn->share_access & FILE_WRITE_DATA) == 0) {
-- 
1.7.7.3


>From 3bbc067d5c6d4a5a5a78fb0fdf79fe1d36f3551c Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Fri, 4 Jan 2013 14:25:55 -0800
Subject: [PATCH 13/19] Correctly setup the conn->share_access based on the
 current user token.

Also use this to set conn->read_only. Cache the share_access in the
struct vuid_cache_entry struct so we only evaluate this once per new
user access on this share.

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/smbd/uid.c |   34 ++++++++++++++++++++++------------
 1 files changed, 22 insertions(+), 12 deletions(-)

diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index f9b5716..397380c 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -94,6 +94,7 @@ static bool check_user_ok(connection_struct *conn,
 	bool readonly_share;
 	bool admin_user;
 	struct vuid_cache_entry *ent = NULL;
+	uint32_t share_access = 0;
 
 	for (i=0; i<VUID_CACHE_SIZE; i++) {
 		ent = &conn->vuid_cache->array[i];
@@ -101,6 +102,7 @@ static bool check_user_ok(connection_struct *conn,
 			free_conn_session_info_if_unused(conn);
 			conn->session_info = ent->session_info;
 			conn->read_only = ent->read_only;
+			conn->share_access = ent->share_access;
 			return(True);
 		}
 	}
@@ -116,11 +118,24 @@ static bool check_user_ok(connection_struct *conn,
 		session_info->security_token,
 		conn);
 
+	share_access = create_share_access_mask(snum,
+						readonly_share,
+						session_info->security_token);
+
+	if ((share_access & FILE_WRITE_DATA) == 0) {
+		if ((share_access & FILE_READ_DATA) == 0) {
+			/* No access, read or write. */
+			DEBUG(0,("user %s connection to %s "
+				"denied due to share security "
+				"descriptor.\n",
+				session_info->unix_info->unix_name,
+				lp_servicename(talloc_tos(), snum)));
+			return false;
+		}
+	}
+
 	if (!readonly_share &&
-	    !share_access_check(session_info->security_token,
-				lp_servicename(talloc_tos(), snum),
-				FILE_WRITE_DATA,
-				NULL)) {
+	    !(share_access & FILE_WRITE_DATA)) {
 		/* smb.conf allows r/w, but the security descriptor denies
 		 * write. Fall back to looking at readonly. */
 		readonly_share = True;
@@ -128,14 +143,6 @@ static bool check_user_ok(connection_struct *conn,
 			 "security descriptor\n"));
 	}
 
-	if (!share_access_check(session_info->security_token,
-				lp_servicename(talloc_tos(), snum),
-				readonly_share ?
-				FILE_READ_DATA : FILE_WRITE_DATA,
-				NULL)) {
-		return False;
-	}
-
 	admin_user = token_contains_name_in_list(
 		session_info->unix_info->unix_name,
 		session_info->info->domain_name,
@@ -163,10 +170,13 @@ static bool check_user_ok(connection_struct *conn,
 
 	ent->vuid = vuid;
 	ent->read_only = readonly_share;
+	ent->share_access = share_access;
 	free_conn_session_info_if_unused(conn);
 	conn->session_info = ent->session_info;
 
 	conn->read_only = readonly_share;
+	conn->share_access = share_access;
+
 	if (admin_user) {
 		DEBUG(2,("check_user_ok: user %s is an admin user. "
 			"Setting uid as %d\n",
-- 
1.7.7.3


>From 7a469b6109fd960f98bfb3c58b04a5a846435d73 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Fri, 4 Jan 2013 14:27:18 -0800
Subject: [PATCH 14/19] Add check_user_share_access() which factors out the
 share security and read_only flag setting code.

Allows this to be called from both make_connection_snum() as well as check_user_ok().
Gives a consistent share security check function.

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/smbd/proto.h |    4 +++
 source3/smbd/uid.c   |   56 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+), 0 deletions(-)

diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index ddb13a2..8a101c2 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -1091,6 +1091,10 @@ void reply_transs2(struct smb_request *req);
 /* The following definitions come from smbd/uid.c  */
 
 bool change_to_guest(void);
+NTSTATUS check_user_share_access(connection_struct *conn,
+				const struct auth_session_info *session_info,
+				uint32_t *p_share_access,
+				bool *p_readonly_share);
 bool change_to_user(connection_struct *conn, uint64_t vuid);
 bool change_to_root_user(void);
 bool smbd_change_to_root_user(void);
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index 397380c..f551e50 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -79,6 +79,62 @@ static void free_conn_session_info_if_unused(connection_struct *conn)
 }
 
 /*******************************************************************
+ Calculate access mask and if this user can access this share.
+********************************************************************/
+
+NTSTATUS check_user_share_access(connection_struct *conn,
+				const struct auth_session_info *session_info,
+				uint32_t *p_share_access,
+				bool *p_readonly_share)
+{
+	int snum = SNUM(conn);
+	uint32_t share_access = 0;
+	bool readonly_share = false;
+
+	if (!user_ok_token(session_info->unix_info->unix_name,
+			   session_info->info->domain_name,
+			   session_info->security_token, snum)) {
+		return NT_STATUS_ACCESS_DENIED;
+	}
+
+	readonly_share = is_share_read_only_for_token(
+		session_info->unix_info->unix_name,
+		session_info->info->domain_name,
+		session_info->security_token,
+		conn);
+
+	share_access = create_share_access_mask(snum,
+					readonly_share,
+					session_info->security_token);
+
+	if ((share_access & FILE_WRITE_DATA) == 0) {
+		if ((share_access & FILE_READ_DATA) == 0) {
+			/* No access, read or write. */
+			DEBUG(0,("user %s connection to %s "
+				"denied due to share security "
+				"descriptor.\n",
+				session_info->unix_info->unix_name,
+				lp_servicename(talloc_tos(), snum)));
+			return NT_STATUS_ACCESS_DENIED;
+		}
+	}
+
+	if (!readonly_share &&
+	    !(share_access & FILE_WRITE_DATA)) {
+		/* smb.conf allows r/w, but the security descriptor denies
+		 * write. Fall back to looking at readonly. */
+		readonly_share = True;
+		DEBUG(5,("falling back to read-only access-evaluation due to "
+			 "security descriptor\n"));
+	}
+
+	*p_share_access = share_access;
+	*p_readonly_share = readonly_share;
+
+	return NT_STATUS_OK;
+}
+
+/*******************************************************************
  Check if a username is OK.
 
  This sets up conn->session_info with a copy related to this vuser that
-- 
1.7.7.3


>From 3dfbb29582f80f94896e1c2c18ca250aae940f0e Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Thu, 3 Jan 2013 16:06:40 -0800
Subject: [PATCH 15/19] Initialize stack variables. Prelude to factoring out
 calls to check_user_share_access().

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

diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index f551e50..9802056 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -147,8 +147,8 @@ static bool check_user_ok(connection_struct *conn,
 			int snum)
 {
 	unsigned int i;
-	bool readonly_share;
-	bool admin_user;
+	bool readonly_share = false;
+	bool admin_user = false;
 	struct vuid_cache_entry *ent = NULL;
 	uint32_t share_access = 0;
 
-- 
1.7.7.3


>From 21bac1d9438d4f53b7f7ce46e61963efaa63d512 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Fri, 4 Jan 2013 14:35:46 -0800
Subject: [PATCH 16/19] Factor code out of check_user_ok() into a call to
 check_user_share_access().

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/smbd/uid.c |   41 +++++++----------------------------------
 1 files changed, 7 insertions(+), 34 deletions(-)

diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index 9802056..efdd824 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -151,6 +151,7 @@ static bool check_user_ok(connection_struct *conn,
 	bool admin_user = false;
 	struct vuid_cache_entry *ent = NULL;
 	uint32_t share_access = 0;
+	NTSTATUS status;
 
 	for (i=0; i<VUID_CACHE_SIZE; i++) {
 		ent = &conn->vuid_cache->array[i];
@@ -163,40 +164,12 @@ static bool check_user_ok(connection_struct *conn,
 		}
 	}
 
-	if (!user_ok_token(session_info->unix_info->unix_name,
-			   session_info->info->domain_name,
-			   session_info->security_token, snum))
-		return(False);
-
-	readonly_share = is_share_read_only_for_token(
-		session_info->unix_info->unix_name,
-		session_info->info->domain_name,
-		session_info->security_token,
-		conn);
-
-	share_access = create_share_access_mask(snum,
-						readonly_share,
-						session_info->security_token);
-
-	if ((share_access & FILE_WRITE_DATA) == 0) {
-		if ((share_access & FILE_READ_DATA) == 0) {
-			/* No access, read or write. */
-			DEBUG(0,("user %s connection to %s "
-				"denied due to share security "
-				"descriptor.\n",
-				session_info->unix_info->unix_name,
-				lp_servicename(talloc_tos(), snum)));
-			return false;
-		}
-	}
-
-	if (!readonly_share &&
-	    !(share_access & FILE_WRITE_DATA)) {
-		/* smb.conf allows r/w, but the security descriptor denies
-		 * write. Fall back to looking at readonly. */
-		readonly_share = True;
-		DEBUG(5,("falling back to read-only access-evaluation due to "
-			 "security descriptor\n"));
+	status = check_user_share_access(conn,
+					session_info,
+					&share_access,
+					&readonly_share);
+	if (!NT_STATUS_IS_OK(status)) {
+		return false;
 	}
 
 	admin_user = token_contains_name_in_list(
-- 
1.7.7.3


>From b1d344650ba3d1434f5fea5018752a2747508fdc Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Fri, 4 Jan 2013 14:40:05 -0800
Subject: [PATCH 17/19] Fix bug #9518 - conn->share_access appears not be be
 reset between users.

Ensure make_connection_snum() uses the same logic as
check_user_ok() to decide if a user can access a share.

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/smbd/service.c |   28 ++++++++--------------------
 1 files changed, 8 insertions(+), 20 deletions(-)

diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index 10f4b53..fabc5a3 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -652,29 +652,17 @@ static NTSTATUS make_connection_snum(struct smbd_server_connection *sconn,
 	}
 
 	/*
-	 * New code to check if there's a share security descripter
-	 * added from NT server manager. This is done after the
-	 * smb.conf checks are done as we need a uid and token. JRA.
-	 *
+	 * Set up the share security descripter
 	 */
 
-	conn->share_access = create_share_access_mask(snum,
-					!CAN_WRITE(conn),
-					conn->session_info->security_token);
-
-	if ((conn->share_access & FILE_WRITE_DATA) == 0) {
-		if ((conn->share_access & FILE_READ_DATA) == 0) {
-			/* No access, read or write. */
-			DEBUG(0,("make_connection: connection to %s "
-				 "denied due to security "
-				 "descriptor.\n",
-				 lp_servicename(talloc_tos(), snum)));
-			status = NT_STATUS_ACCESS_DENIED;
-			goto err_root_exit;
-		} else {
-			conn->read_only = True;
-		}
+	status = check_user_share_access(conn,
+					conn->session_info,
+					&conn->share_access,
+					&conn->read_only);
+	if (!NT_STATUS_IS_OK(status)) {
+		goto err_root_exit;
 	}
+
 	/* Initialise VFS function pointers */
 
 	if (!smbd_vfs_init(conn)) {
-- 
1.7.7.3


>From 26a619c32fff2f65405401075a321d31a2bb1f00 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Fri, 4 Jan 2013 14:42:23 -0800
Subject: [PATCH 18/19] Move create_share_access_mask() from smbd/service.c to
 smbd/uid.c.

Make it static. Only called from uid.c now.

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/smbd/proto.h   |    3 ---
 source3/smbd/service.c |   38 --------------------------------------
 source3/smbd/uid.c     |   38 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 38 insertions(+), 41 deletions(-)

diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index 8a101c2..6d2a828 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -971,9 +971,6 @@ void smbd_exit_server_cleanly(const char *const reason) _NORETURN_;
 
 bool set_conn_connectpath(connection_struct *conn, const char *connectpath);
 NTSTATUS set_conn_force_user_group(connection_struct *conn, int snum);
-uint32_t create_share_access_mask(int snum,
-			bool readonly_share,
-			const struct security_token *token);
 bool set_current_service(connection_struct *conn, uint16 flags, bool do_chdir);
 void load_registry_shares(void);
 int add_home_service(const char *service, const char *username, const char *homedir);
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index fabc5a3..8f6d485 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -512,44 +512,6 @@ NTSTATUS set_conn_force_user_group(connection_struct *conn, int snum)
 }
 
 /****************************************************************************
-  Setup the share access mask for a connection.
-****************************************************************************/
-
-uint32_t create_share_access_mask(int snum,
-				bool readonly_share,
-				const struct security_token *token)
-{
-	uint32_t share_access = 0;
-
-	share_access_check(token,
-			lp_servicename(talloc_tos(), snum),
-			MAXIMUM_ALLOWED_ACCESS,
-			&share_access);
-
-	if (readonly_share) {
-		share_access &=
-			~(SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA |
-			  SEC_FILE_WRITE_EA | SEC_FILE_WRITE_ATTRIBUTE |
-			  SEC_DIR_DELETE_CHILD );
-	}
-
-	if (security_token_has_privilege(token, SEC_PRIV_SECURITY)) {
-		share_access |= SEC_FLAG_SYSTEM_SECURITY;
-	}
-	if (security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
-		share_access |= (SEC_RIGHTS_PRIV_RESTORE);
-	}
-	if (security_token_has_privilege(token, SEC_PRIV_BACKUP)) {
-		share_access |= (SEC_RIGHTS_PRIV_BACKUP);
-	}
-	if (security_token_has_privilege(token, SEC_PRIV_TAKE_OWNERSHIP)) {
-		share_access |= (SEC_STD_WRITE_OWNER);
-	}
-
-	return share_access;
-}
-
-/****************************************************************************
   Make a connection, given the snum to connect to, and the vuser of the
   connecting user if appropriate.
 ****************************************************************************/
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index efdd824..b9cebce 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -78,6 +78,44 @@ static void free_conn_session_info_if_unused(connection_struct *conn)
 	TALLOC_FREE(conn->session_info);
 }
 
+/****************************************************************************
+  Setup the share access mask for a connection.
+****************************************************************************/
+
+static uint32_t create_share_access_mask(int snum,
+				bool readonly_share,
+				const struct security_token *token)
+{
+	uint32_t share_access = 0;
+
+	share_access_check(token,
+			lp_servicename(talloc_tos(), snum),
+			MAXIMUM_ALLOWED_ACCESS,
+			&share_access);
+
+	if (readonly_share) {
+		share_access &=
+			~(SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA |
+			  SEC_FILE_WRITE_EA | SEC_FILE_WRITE_ATTRIBUTE |
+			  SEC_DIR_DELETE_CHILD );
+	}
+
+	if (security_token_has_privilege(token, SEC_PRIV_SECURITY)) {
+		share_access |= SEC_FLAG_SYSTEM_SECURITY;
+	}
+	if (security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
+		share_access |= (SEC_RIGHTS_PRIV_RESTORE);
+	}
+	if (security_token_has_privilege(token, SEC_PRIV_BACKUP)) {
+		share_access |= (SEC_RIGHTS_PRIV_BACKUP);
+	}
+	if (security_token_has_privilege(token, SEC_PRIV_TAKE_OWNERSHIP)) {
+		share_access |= (SEC_STD_WRITE_OWNER);
+	}
+
+	return share_access;
+}
+
 /*******************************************************************
  Calculate access mask and if this user can access this share.
 ********************************************************************/
-- 
1.7.7.3


>From d443993997e186a9b64d17846531f42e5561c998 Mon Sep 17 00:00:00 2001
From: Andrew Bartlett <abartlet at samba.org>
Date: Thu, 20 Dec 2012 23:05:55 +1100
Subject: [PATCH 19/19] selftest: show that Samba honours "write list" and
 valid users

Reviewed-by: Jeremy Allison <jra at samba.org>
---
 selftest/target/Samba3.pm                          |    7 +++++++
 .../script/tests/test_smbclient_machine_auth.sh    |    4 ++++
 source3/script/tests/test_smbclient_s3.sh          |    8 ++++++--
 source3/selftest/tests.py                          |    5 +++++
 4 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
index adca52f..8546bd2 100755
--- a/selftest/target/Samba3.pm
+++ b/selftest/target/Samba3.pm
@@ -963,6 +963,13 @@ sub provision($$$$$$)
 [ro-tmp]
 	path = $ro_shrdir
 	guest ok = yes
+[write-list-tmp]
+	path = $shrdir
+        read only = yes
+	write list = $unix_name
+[valid-users-tmp]
+	path = $shrdir
+	valid users = $unix_name
 [msdfs-share]
 	path = $msdfs_shrdir
 	msdfs root = yes
diff --git a/source3/script/tests/test_smbclient_machine_auth.sh b/source3/script/tests/test_smbclient_machine_auth.sh
index f67256d..a890d48 100755
--- a/source3/script/tests/test_smbclient_machine_auth.sh
+++ b/source3/script/tests/test_smbclient_machine_auth.sh
@@ -19,3 +19,7 @@ incdir=`dirname $0`/../../../testprogs/blackbox
 . $incdir/subunit.sh
 
 testit "smbclient //$SERVER/tmp" $SMBCLIENT //$SERVER/tmp --machine-pass -I $SERVER_IP -p 139 -c quit $ADDARGS
+
+# Testing these here helps because we know the machine account isn't already this user/group
+testit "smbclient //$SERVER/forceuser" $SMBCLIENT //$SERVER/tmp --machine-pass -I $SERVER_IP -p 139 -c quit $ADDARGS
+testit "smbclient //$SERVER/forcegroup" $SMBCLIENT //$SERVER/tmp --machine-pass -I $SERVER_IP -p 139 -c quit $ADDARGS
diff --git a/source3/script/tests/test_smbclient_s3.sh b/source3/script/tests/test_smbclient_s3.sh
index fb518c5..b240da0 100755
--- a/source3/script/tests/test_smbclient_s3.sh
+++ b/source3/script/tests/test_smbclient_s3.sh
@@ -212,7 +212,7 @@ mkdir a_test_dir
 quit
 EOF
 
-    cmd='CLI_FORCE_INTERACTIVE=yes $SMBCLIENT "$@" -U% //$SERVER/ro-tmp -I $SERVER_IP $ADDARGS < $tmpfile 2>&1'
+    cmd='CLI_FORCE_INTERACTIVE=yes $SMBCLIENT -U% //$SERVER/$1" -I $SERVER_IP $ADDARGS < $tmpfile 2>&1'
     eval echo "$cmd"
     out=`eval $cmd`
     ret=$?
@@ -581,7 +581,11 @@ testit "creating a good symlink and deleting it by path" \
    failed=`expr $failed + 1`
 
 testit "writing into a read-only directory fails" \
-   test_read_only_dir || \
+   test_read_only_dir ro-tmp || \
+   failed=`expr $failed + 1`
+
+testit "writing into a read-only share fails" \
+   test_read_only_dir valid-users-tmp || \
    failed=`expr $failed + 1`
 
 testit "Reading a owner-only file fails" \
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index 57a67ed..44efe18 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -333,6 +333,11 @@ for t in tests:
     elif t == "smb2.durable-open" or t == "smb2.durable-v2-open":
         plansmbtorture4testsuite(t, "s3dc", '//$SERVER_IP/durable -U$USERNAME%$PASSWORD')
         plansmbtorture4testsuite(t, "plugin_s4_dc", '//$SERVER_IP/durable -U$USERNAME%$PASSWORD')
+    elif t == "base.rw1":
+        plansmbtorture4testsuite(t, "s3dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD')
+        plansmbtorture4testsuite(t, "s3dc", '//$SERVER_IP/valid-users-tmp -U$USERNAME%$PASSWORD')
+        plansmbtorture4testsuite(t, "s3dc", '//$SERVER_IP/write-list-tmp -U$USERNAME%$PASSWORD')
+        plansmbtorture4testsuite(t, "plugin_s4_dc", '//$SERVER/tmp -U$USERNAME%$PASSWORD')
     else:
         plansmbtorture4testsuite(t, "s3dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD')
         plansmbtorture4testsuite(t, "plugin_s4_dc", '//$SERVER/tmp -U$USERNAME%$PASSWORD')
-- 
1.7.7.3



More information about the samba-technical mailing list