Add check_user_share_access()
authorJeremy Allison <jra@samba.org>
Fri, 11 Jan 2013 19:01:25 +0000 (11:01 -0800)
committerKarolin Seeger <kseeger@samba.org>
Mon, 14 Jan 2013 18:03:28 +0000 (19:03 +0100)
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
source3/smbd/uid.c

index 6cf915ad562d96f1fdd8ad46518eac1734ff7ddc..f9cf5fbbc938884224ede520af5be0a881aa5174 100644 (file)
@@ -1087,6 +1087,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);
index bed0b54ff0e95a1cc7c2d428516c36371ea3e427..e60f10850104972df289f90e005819ef8c98f43d 100644 (file)
@@ -78,6 +78,61 @@ static void free_conn_session_info_if_unused(connection_struct *conn)
        TALLOC_FREE(conn->session_info);
 }
 
+/*******************************************************************
+ 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.