Correctly setup the conn->share_access based on the current user token.
authorJeremy Allison <jra@samba.org>
Fri, 4 Jan 2013 22:25:55 +0000 (14:25 -0800)
committerAndrew Bartlett <abartlet@samba.org>
Wed, 9 Jan 2013 04:29:18 +0000 (15:29 +1100)
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@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
source3/smbd/uid.c

index f9b5716f3d6d9c591f1e461c11ba733b4882d515..397380c52517623e9ad6b7e69ceeb2f1072a20d6 100644 (file)
@@ -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",