The Samba-Bugzilla – Attachment 8401 Details for
Bug 9518
conn->share_access appears not be be reset between users
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
git-am format patch for 4.0.x.
bug-9518-4.0.x.patchset (text/plain), 39.64 KB, created by
Jeremy Allison
on 2013-01-09 21:28:57 UTC
(
hide
)
Description:
git-am format patch for 4.0.x.
Filename:
MIME Type:
Creator:
Jeremy Allison
Created:
2013-01-09 21:28:57 UTC
Size:
39.64 KB
patch
obsolete
>From 870ebaeeccd2bde56ec5916f56aecfa41e2e2290 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 20 Dec 2012 11:50:25 -0800 >Subject: [PATCH 01/18] 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@samba.org> >(cherry picked from commit f0450e0d80c2ff56c4834b2f1271a7f84132ca5b) >--- > source3/smbd/uid.c | 5 ++--- > 1 file 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.8.1 > > >From eceb5a5adb4efc29d4daf4190295f5710f777950 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 20 Dec 2012 11:51:55 -0800 >Subject: [PATCH 02/18] Move the definition of struct vuid_cache_entry *ent > outside blocks. > >Signed-off-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 092c9517acf5a4b11577ef7b5f1d645e5e463f6d) >--- > source3/smbd/uid.c | 6 ++---- > 1 file 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.8.1 > > >From 0d3fa3a0bf280d40a3e1d89de5bf7dd246f4f1eb Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 20 Dec 2012 11:52:27 -0800 >Subject: [PATCH 03/18] Remove one set of enclosing {} braces, no longer > needed. > >Signed-off-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit d64ea67c78a5b09559971ff6953cd67feb2b1ec2) >--- > source3/smbd/uid.c | 16 +++++++--------- > 1 file 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.8.1 > > >From 9dce4396cb67af72f8d4d203208f4b4856e58c5a Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 20 Dec 2012 11:53:11 -0800 >Subject: [PATCH 04/18] Remove the second set of {} braces, no longer needed. > (cherry picked from commit ed0a34d163f777b2a0d4a2b358b7fb1b170d7686) > >--- > source3/smbd/uid.c | 38 ++++++++++++++++++-------------------- > 1 file 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.8.1 > > >From 517f24aed3d08b9fde504bc62ee5da26131cef91 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 20 Dec 2012 11:54:07 -0800 >Subject: [PATCH 05/18] Remove dead code now vuser can no longer be NULL. > >Signed-off-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit d35ba04e25eb3c396f791ea80c0ebb74543d4005) >--- > source3/smbd/uid.c | 8 -------- > 1 file changed, 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.8.1 > > >From bfbf2f0389d77b6756259a95709879f90805c9d6 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 20 Dec 2012 11:55:09 -0800 >Subject: [PATCH 06/18] Remove unneeded variable "const struct > auth_session_info *session_info" > >Signed-off-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 5a3cda176f5eecd65b289c74132b0126357c5ef0) >--- > source3/smbd/uid.c | 4 +--- > 1 file changed, 1 insertion(+), 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.8.1 > > >From 2a07ef4c12f0a4e5b22177fd38ac302a08d954b0 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Fri, 21 Dec 2012 09:35:31 -0800 >Subject: [PATCH 07/18] Remove static from create_share_access_mask(). > >Signed-off-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 48187220ff47efe70616361fcef1a794aef765b4) >--- > source3/smbd/proto.h | 1 + > source3/smbd/service.c | 2 +- > 2 files changed, 2 insertions(+), 1 deletion(-) > >diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h >index b48cf44..e004980 100644 >--- a/source3/smbd/proto.h >+++ b/source3/smbd/proto.h >@@ -962,6 +962,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.8.1 > > >From 89534ae50df19dd7dcf0aff5212a172c1a39ff95 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Fri, 21 Dec 2012 09:45:03 -0800 >Subject: [PATCH 08/18] 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@samba.org> >(cherry picked from commit 33167c070c085b30569317666a3fca079d970321) >--- > 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 e004980..97ae1db 100644 >--- a/source3/smbd/proto.h >+++ b/source3/smbd/proto.h >@@ -962,7 +962,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.8.1 > > >From e07aba7a957710675f15fe6c58918dfdc6fdc94a Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Fri, 4 Jan 2013 12:01:17 -0800 >Subject: [PATCH 09/18] 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@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 97ae1db..f0d2c93 100644 >--- a/source3/smbd/proto.h >+++ b/source3/smbd/proto.h >@@ -962,7 +962,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.8.1 > > >From 45469aee72c844b46f7d66a96de58ac43d058ce1 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Fri, 4 Jan 2013 15:04:26 -0800 >Subject: [PATCH 10/18] 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@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 f0d2c93..4fdcd26 100644 >--- a/source3/smbd/proto.h >+++ b/source3/smbd/proto.h >@@ -962,8 +962,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.8.1 > > >From 973be123821018346ed109155f7f0ed7d143ca65 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Fri, 4 Jan 2013 15:06:35 -0800 >Subject: [PATCH 11/18] Correctly setup the conn->share_access based on the > current user token. > >Also use this to set conn->read_only. Cache the share_access >so we only evaluate this once per new user access on this share. > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/uid.c | 44 ++++++++++++++++++++++++++++++++------------ > 1 file changed, 32 insertions(+), 12 deletions(-) > >diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c >index 9244f29..36b79bc 100644 >--- a/source3/smbd/uid.c >+++ b/source3/smbd/uid.c >@@ -79,6 +79,14 @@ static void free_conn_session_info_if_unused(connection_struct *conn) > } > > /******************************************************************* >+ Static cache for storing per-user share access value. This really >+ belongs inside the vuid_cache.array struct but we can't change the >+ VFS ABI for 4.0.x. This is fixed in 4.1.x. JRA. >+********************************************************************/ >+ >+static uint32_t vuid_cache_share_access_array[VUID_CACHE_SIZE]; >+ >+/******************************************************************* > Check if a username is OK. > > This sets up conn->session_info with a copy related to this vuser that >@@ -94,6 +102,8 @@ 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; >+ unsigned int share_array_index; > > for (i=0; i<VUID_CACHE_SIZE; i++) { > ent = &conn->vuid_cache.array[i]; >@@ -101,6 +111,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 = vuid_cache_share_access_array[i]; > return(True); > } > } >@@ -116,11 +127,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,19 +152,12 @@ 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, > NULL, session_info->security_token, lp_admin_users(snum)); > >+ share_array_index = conn->vuid_cache.next_entry; > ent = &conn->vuid_cache.array[conn->vuid_cache.next_entry]; > > conn->vuid_cache.next_entry = >@@ -163,10 +180,13 @@ static bool check_user_ok(connection_struct *conn, > > ent->vuid = vuid; > ent->read_only = readonly_share; >+ vuid_cache_share_access_array[share_array_index] = 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.8.1 > > >From 04904422545e5fd4abdcc2d52f3d78150a00bed6 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Fri, 4 Jan 2013 15:07:50 -0800 >Subject: [PATCH 12/18] Add check_user_share_access() > >This factors out the share security and read_only flag >setting code so this can 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@samba.org> >--- > source3/smbd/proto.h | 4 ++++ > source3/smbd/uid.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 60 insertions(+) > >diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h >index 4fdcd26..cfaa0b0 100644 >--- a/source3/smbd/proto.h >+++ b/source3/smbd/proto.h >@@ -1082,6 +1082,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 36b79bc..6f5ff6d 100644 >--- a/source3/smbd/uid.c >+++ b/source3/smbd/uid.c >@@ -87,6 +87,62 @@ static void free_conn_session_info_if_unused(connection_struct *conn) > static uint32_t vuid_cache_share_access_array[VUID_CACHE_SIZE]; > > /******************************************************************* >+ 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.8.1 > > >From 9085281733977d290fbe9c273336d1615dbe038d Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Fri, 4 Jan 2013 11:05:03 -0800 >Subject: [PATCH 13/18] Initialize stack variables. Prelude to factoring out > calls to check_user_share_access(). > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/uid.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > >diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c >index 6f5ff6d..dc92961 100644 >--- a/source3/smbd/uid.c >+++ b/source3/smbd/uid.c >@@ -155,8 +155,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; > unsigned int share_array_index; >-- >1.8.1 > > >From 8f5a6844e011b973bcef0736ab84aa568603f3bf Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Fri, 4 Jan 2013 15:13:53 -0800 >Subject: [PATCH 14/18] Factor code out of check_user_ok() into a call to > check_user_share_access(). > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/uid.c | 40 +++++++--------------------------------- > 1 file changed, 7 insertions(+), 33 deletions(-) > >diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c >index dc92961..c782a77 100644 >--- a/source3/smbd/uid.c >+++ b/source3/smbd/uid.c >@@ -160,6 +160,7 @@ static bool check_user_ok(connection_struct *conn, > struct vuid_cache_entry *ent = NULL; > uint32_t share_access = 0; > unsigned int share_array_index; >+ NTSTATUS status; > > for (i=0; i<VUID_CACHE_SIZE; i++) { > ent = &conn->vuid_cache.array[i]; >@@ -172,41 +173,14 @@ 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; >- } >+ status = check_user_share_access(conn, >+ session_info, >+ &share_access, >+ &readonly_share); >+ if (!NT_STATUS_IS_OK(status)) { >+ 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")); >- } > > admin_user = token_contains_name_in_list( > session_info->unix_info->unix_name, >-- >1.8.1 > > >From 24370ee2229864cdb62afd434a681eb0905e75e6 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Fri, 4 Jan 2013 15:15:59 -0800 >Subject: [PATCH 15/18] 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@samba.org> >--- > source3/smbd/service.c | 34 +++++++++++----------------------- > 1 file changed, 11 insertions(+), 23 deletions(-) > >diff --git a/source3/smbd/service.c b/source3/smbd/service.c >index 10f4b53..d3cda73 100644 >--- a/source3/smbd/service.c >+++ b/source3/smbd/service.c >@@ -651,30 +651,18 @@ static NTSTATUS make_connection_snum(struct smbd_server_connection *sconn, > TALLOC_FREE(s); > } > >- /* >- * 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. >- * >- */ >- >- 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; >- } >+ /* >+ * Set up the share security descripter >+ */ >+ >+ 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.8.1 > > >From d7aeb17b249e80e0ba1b4c10472604a95db5afc0 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Fri, 4 Jan 2013 15:18:42 -0800 >Subject: [PATCH 16/18] 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@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 cfaa0b0..a6f054b 100644 >--- a/source3/smbd/proto.h >+++ b/source3/smbd/proto.h >@@ -962,9 +962,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 d3cda73..b3abdd8 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 c782a77..d1c45f3 100644 >--- a/source3/smbd/uid.c >+++ b/source3/smbd/uid.c >@@ -86,6 +86,44 @@ static void free_conn_session_info_if_unused(connection_struct *conn) > > static uint32_t vuid_cache_share_access_array[VUID_CACHE_SIZE]; > >+/**************************************************************************** >+ 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.8.1 > > >From 4969a7826d95b9068d5f7bea7069d22094cefa1f Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Wed, 9 Jan 2013 12:40:17 -0800 >Subject: [PATCH 17/18] Fixup the change_to_user_by_session() case as called > from become_user_by_session() > >Use inside source3/printing/nt_printing.c:get_correct_cversion(). > >Allow check_user_ok() to be called with vuid==UID_FIELD_INVALID. >All this should do is throw away one entry in the vuid cache. > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/uid.c | 21 +++++++++++++++++++++ > 1 file changed, 21 insertions(+) > >diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c >index d1c45f3..4c04b78 100644 >--- a/source3/smbd/uid.c >+++ b/source3/smbd/uid.c >@@ -203,6 +203,13 @@ static bool check_user_ok(connection_struct *conn, > for (i=0; i<VUID_CACHE_SIZE; i++) { > ent = &conn->vuid_cache.array[i]; > if (ent->vuid == vuid) { >+ if (vuid == UID_FIELD_INVALID) { >+ /* >+ * Slow path, we don't care >+ * about the array traversal. >+ */ >+ continue; >+ } > free_conn_session_info_if_unused(conn); > conn->session_info = ent->session_info; > conn->read_only = ent->read_only; >@@ -246,11 +253,25 @@ static bool check_user_ok(connection_struct *conn, > return false; > } > >+ /* >+ * It's actually OK to call check_user_ok() with >+ * vuid == UID_FIELD_INVALID as called from change_to_user_by_session(). >+ * All this will do is throw away one entry in the cache. >+ */ > ent->vuid = vuid; > ent->read_only = readonly_share; > vuid_cache_share_access_array[share_array_index] = share_access; > free_conn_session_info_if_unused(conn); > conn->session_info = ent->session_info; >+ if (vuid == UID_FIELD_INVALID) { >+ /* >+ * Not strictly needed, just make it really >+ * clear this entry is actually an unused one. >+ */ >+ ent->read_only = false; >+ vuid_cache_share_access_array[share_array_index] = 0; >+ ent->session_info = NULL; >+ } > > conn->read_only = readonly_share; > conn->share_access = share_access; >-- >1.8.1 > > >From b7c7475596fdbb71091c411a63e613431963d90d Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Thu, 20 Dec 2012 23:05:55 +1100 >Subject: [PATCH 18/18] selftest: show that Samba honours "write list" and > valid users > >Reviewed-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >--- > selftest/target/Samba3.pm | 7 +++++++ > source3/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 2037a2e..6c63413 100755 >--- a/selftest/target/Samba3.pm >+++ b/selftest/target/Samba3.pm >@@ -956,6 +956,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 3341c62..aa2ba77 100755 >--- a/source3/script/tests/test_smbclient_s3.sh >+++ b/source3/script/tests/test_smbclient_s3.sh >@@ -211,7 +211,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=$? >@@ -529,7 +529,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 9b0527c..57c80f2 100755 >--- a/source3/selftest/tests.py >+++ b/source3/selftest/tests.py >@@ -330,6 +330,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.8.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Flags:
abartlet
:
review-
Actions:
View
Attachments on
bug 9518
:
8362
|
8364
|
8380
|
8381
|
8383
|
8384
|
8394
|
8395
|
8401
|
8412