From 15e1fd7c540ab47dffdfbd4cfad3a8c18a3f62dc Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 4 Dec 2008 11:20:57 -0800 Subject: [PATCH] Fix bug #1254 - write list not working under share-level security A somewhat more elegant fix than I could use for 3.2.x or 3.0.x. Turns out the only part of check_user_ok() that needs to change for share level security is the VUID cache pieces, so I can just always use check_user_ok() for all lp_security() cases. Jeremy --- source3/auth/auth_util.c | 2 +- source3/include/proto.h | 6 ++-- source3/smbd/share_access.c | 4 +-- source3/smbd/uid.c | 81 +++++++++++++++++++++++++-------------------- 4 files changed, 52 insertions(+), 41 deletions(-) diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index 9220df01c00..d2a8591ae61 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -1294,7 +1294,7 @@ NTSTATUS make_serverinfo_from_username(TALLOC_CTX *mem_ctx, struct auth_serversupplied_info *copy_serverinfo(TALLOC_CTX *mem_ctx, - auth_serversupplied_info *src) + const auth_serversupplied_info *src) { auth_serversupplied_info *dst; diff --git a/source3/include/proto.h b/source3/include/proto.h index 63fe4d47c54..89b443e9db9 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -123,7 +123,7 @@ NTSTATUS make_serverinfo_from_username(TALLOC_CTX *mem_ctx, bool is_guest, struct auth_serversupplied_info **presult); struct auth_serversupplied_info *copy_serverinfo(TALLOC_CTX *mem_ctx, - auth_serversupplied_info *src); + const auth_serversupplied_info *src); bool init_guest_info(void); bool server_info_set_session_key(struct auth_serversupplied_info *info, DATA_BLOB session_key); @@ -8462,10 +8462,10 @@ bool token_contains_name_in_list(const char *username, const struct nt_user_token *token, const char **list); bool user_ok_token(const char *username, const char *domain, - struct nt_user_token *token, int snum); + const struct nt_user_token *token, int snum); bool is_share_read_only_for_token(const char *username, const char *domain, - struct nt_user_token *token, + const struct nt_user_token *token, connection_struct *conn); /* The following definitions come from smbd/srvstr.c */ diff --git a/source3/smbd/share_access.c b/source3/smbd/share_access.c index 9dbacc29983..c72251b5a77 100644 --- a/source3/smbd/share_access.c +++ b/source3/smbd/share_access.c @@ -192,7 +192,7 @@ bool token_contains_name_in_list(const char *username, */ bool user_ok_token(const char *username, const char *domain, - struct nt_user_token *token, int snum) + const struct nt_user_token *token, int snum) { if (lp_invalid_users(snum) != NULL) { if (token_contains_name_in_list(username, domain, @@ -252,7 +252,7 @@ bool user_ok_token(const char *username, const char *domain, bool is_share_read_only_for_token(const char *username, const char *domain, - struct nt_user_token *token, + const struct nt_user_token *token, connection_struct *conn) { int snum = SNUM(conn); diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index ca7df264e2f..5a4b8a52e79 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -61,22 +61,27 @@ bool change_to_guest(void) later code can then mess with. ********************************************************************/ -static bool check_user_ok(connection_struct *conn, uint16_t vuid, - struct auth_serversupplied_info *server_info, - int snum) +static bool check_user_ok(connection_struct *conn, + uint16_t vuid, + const struct auth_serversupplied_info *server_info, + int snum) { + bool valid_vuid = (vuid != UID_FIELD_INVALID); unsigned int i; - struct vuid_cache_entry *ent = NULL; bool readonly_share; bool admin_user; - for (i=0; ivuid_cache.array[i]; - if (ent->vuid == vuid) { - conn->server_info = ent->server_info; - conn->read_only = ent->read_only; - conn->admin_user = ent->admin_user; - return(True); + if (valid_vuid) { + struct vuid_cache_entry *ent; + + for (i=0; ivuid_cache.array[i]; + if (ent->vuid == vuid) { + conn->server_info = ent->server_info; + conn->read_only = ent->read_only; + conn->admin_user = ent->admin_user; + return(True); + } } } @@ -112,33 +117,36 @@ static bool check_user_ok(connection_struct *conn, uint16_t vuid, pdb_get_domain(server_info->sam_account), NULL, server_info->ptok, lp_admin_users(snum)); - ent = &conn->vuid_cache.array[conn->vuid_cache.next_entry]; + if (valid_vuid) { + struct vuid_cache_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->server_info); + TALLOC_FREE(ent->server_info); - /* - * If force_user was set, all server_info's are based on the same - * username-based faked one. - */ + /* + * If force_user was set, all server_info's are based on the same + * username-based faked one. + */ - ent->server_info = copy_serverinfo( - conn, conn->force_user ? conn->server_info : server_info); + ent->server_info = copy_serverinfo( + conn, conn->force_user ? conn->server_info : server_info); - if (ent->server_info == NULL) { - ent->vuid = UID_FIELD_INVALID; - return false; - } + if (ent->server_info == NULL) { + ent->vuid = UID_FIELD_INVALID; + return false; + } - ent->vuid = vuid; - ent->read_only = readonly_share; - ent->admin_user = admin_user; + ent->vuid = vuid; + ent->read_only = readonly_share; + ent->admin_user = admin_user; + conn->server_info = ent->server_info; + } - conn->read_only = ent->read_only; - conn->admin_user = ent->admin_user; - conn->server_info = ent->server_info; + conn->read_only = readonly_share; + conn->admin_user = admin_user; return(True); } @@ -172,6 +180,7 @@ void conn_clear_vuid_cache(connection_struct *conn, uint16_t vuid) bool change_to_user(connection_struct *conn, uint16 vuid) { + const struct auth_serversupplied_info *server_info = NULL; user_struct *vuser = get_valid_user_struct(vuid); int snum; gid_t gid; @@ -207,13 +216,15 @@ bool change_to_user(connection_struct *conn, uint16 vuid) snum = SNUM(conn); - if ((vuser) && !check_user_ok(conn, vuid, vuser->server_info, snum)) { + server_info = vuser ? vuser->server_info : conn->server_info; + + if (!check_user_ok(conn, vuid, server_info, snum)) { DEBUG(2,("change_to_user: SMB user %s (unix user %s, vuid %d) " "not permitted access to share %s.\n", - vuser->server_info->sanitized_username, - vuser->server_info->unix_name, vuid, + server_info->sanitized_username, + server_info->unix_name, vuid, lp_servicename(snum))); - return False; + return false; } /* -- 2.11.4.GIT