summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2008-12-04 11:20:57 -0800
committerJeremy Allison <jra@samba.org>2008-12-04 11:20:57 -0800
commit15e1fd7c540ab47dffdfbd4cfad3a8c18a3f62dc (patch)
tree7a78b82d7d13f64ca24ebd6fe357bfbb90ed4bb0
parent677e0fb9659abe1ad684dd980d61b88caad9f8a2 (diff)
downloadsamba-15e1fd7c540ab47dffdfbd4cfad3a8c18a3f62dc.tar.gz
samba-15e1fd7c540ab47dffdfbd4cfad3a8c18a3f62dc.tar.bz2
samba-15e1fd7c540ab47dffdfbd4cfad3a8c18a3f62dc.zip
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
-rw-r--r--source3/auth/auth_util.c2
-rw-r--r--source3/include/proto.h6
-rw-r--r--source3/smbd/share_access.c4
-rw-r--r--source3/smbd/uid.c81
4 files changed, 52 insertions, 41 deletions
diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
index 9220df01c0..d2a8591ae6 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 63fe4d47c5..89b443e9db 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 9dbacc2998..c72251b5a7 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 ca7df264e2..5a4b8a52e7 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; i<VUID_CACHE_SIZE; i++) {
- ent = &conn->vuid_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; i<VUID_CACHE_SIZE; i++) {
+ ent = &conn->vuid_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;
}
/*