summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/proto.h4
-rw-r--r--source3/smbd/uid.c56
2 files changed, 60 insertions, 0 deletions
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index 2198ccd3f7..e8ee8733a4 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -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);
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index 397380c525..f551e50eda 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -79,6 +79,62 @@ static void free_conn_session_info_if_unused(connection_struct *conn)
}
/*******************************************************************
+ 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.
This sets up conn->session_info with a copy related to this vuser that