Add check_user_share_access() which factors out the share security and read_only...
authorJeremy Allison <jra@samba.org>
Fri, 4 Jan 2013 22:27:18 +0000 (14:27 -0800)
committerAndrew Bartlett <abartlet@samba.org>
Wed, 9 Jan 2013 04:29:22 +0000 (15:29 +1100)
Allows this to 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>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
source3/smbd/proto.h
source3/smbd/uid.c

index 2198ccd..e8ee873 100644 (file)
@@ -1099,6 +1099,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 397380c..f551e50 100644 (file)
@@ -78,6 +78,62 @@ 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.