From ea9a59c38036d1710810741f0d7f4d13c4effbe4 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 4 Jul 2011 17:02:34 +0200 Subject: [PATCH 1/3] s3: Return "granted" from share_access_check --- source3/include/proto.h | 6 ++++-- source3/lib/sharesec.c | 10 ++++++++-- source3/rpc_server/srvsvc/srv_srvsvc_nt.c | 4 ++-- source3/smbd/service.c | 13 +++++++------ source3/smbd/uid.c | 11 +++++++---- 5 files changed, 28 insertions(+), 16 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 91905d3..c6fd474 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -244,8 +244,10 @@ struct security_descriptor *get_share_security( TALLOC_CTX *ctx, const char *ser size_t *psize); bool set_share_security(const char *share_name, struct security_descriptor *psd); bool delete_share_security(const char *servicename); -bool share_access_check(const struct security_token *token, const char *sharename, - uint32 desired_access); +bool share_access_check(const struct security_token *token, + const char *sharename, + uint32 desired_access, + uint32_t *pgranted); bool parse_usershare_acl(TALLOC_CTX *ctx, const char *acl_str, struct security_descriptor **ppsd); /* The following definitions come from lib/smbrun.c */ diff --git a/source3/lib/sharesec.c b/source3/lib/sharesec.c index ed971a9..0c06d7b 100644 --- a/source3/lib/sharesec.c +++ b/source3/lib/sharesec.c @@ -410,8 +410,10 @@ bool delete_share_security(const char *servicename) Can this user access with share with the required permissions ? ********************************************************************/ -bool share_access_check(const struct security_token *token, const char *sharename, - uint32 desired_access) +bool share_access_check(const struct security_token *token, + const char *sharename, + uint32 desired_access, + uint32_t *pgranted) { uint32 granted; NTSTATUS status; @@ -428,6 +430,10 @@ bool share_access_check(const struct security_token *token, const char *sharenam TALLOC_FREE(psd); + if (pgranted != NULL) { + *pgranted = granted; + } + return NT_STATUS_IS_OK(status); } diff --git a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c index 752b857..78ea5f3 100644 --- a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c +++ b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c @@ -540,8 +540,8 @@ static bool is_enumeration_allowed(struct pipes_struct *p, if (!lp_access_based_share_enum(snum)) return true; - return share_access_check(p->session_info->security_token, lp_servicename(snum), - FILE_READ_DATA); + return share_access_check(p->session_info->security_token, + lp_servicename(snum), FILE_READ_DATA, NULL); } /******************************************************************* diff --git a/source3/smbd/service.c b/source3/smbd/service.c index 73c3c4f..c1d4dd1 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -644,14 +644,15 @@ connection_struct *make_connection_snum(struct smbd_server_connection *sconn, { bool can_write = False; - can_write = share_access_check(conn->session_info->security_token, - lp_servicename(snum), - FILE_WRITE_DATA); + can_write = share_access_check( + conn->session_info->security_token, + lp_servicename(snum), FILE_WRITE_DATA, NULL); if (!can_write) { - if (!share_access_check(conn->session_info->security_token, - lp_servicename(snum), - FILE_READ_DATA)) { + if (!share_access_check( + conn->session_info->security_token, + lp_servicename(snum), FILE_READ_DATA, + NULL)) { /* No access, read or write. */ DEBUG(0,("make_connection: connection to %s " "denied due to security " diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 285b158..8114144 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -121,8 +121,9 @@ static bool check_user_ok(connection_struct *conn, conn); if (!readonly_share && - !share_access_check(session_info->security_token, lp_servicename(snum), - FILE_WRITE_DATA)) { + !share_access_check(session_info->security_token, + lp_servicename(snum), FILE_WRITE_DATA, + NULL)) { /* smb.conf allows r/w, but the security descriptor denies * write. Fall back to looking at readonly. */ readonly_share = True; @@ -130,9 +131,11 @@ static bool check_user_ok(connection_struct *conn, "security descriptor\n")); } - if (!share_access_check(session_info->security_token, lp_servicename(snum), + if (!share_access_check(session_info->security_token, + lp_servicename(snum), readonly_share ? - FILE_READ_DATA : FILE_WRITE_DATA)) { + FILE_READ_DATA : FILE_WRITE_DATA, + NULL)) { return False; } -- 1.7.4.1 From 3239b9b937208e5a4c0925e703fe10a52d304e40 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 4 Jul 2011 18:35:21 +0200 Subject: [PATCH 2/3] s3: Calculate&store the maximum share access mask --- source3/include/smb.h | 1 + source3/smbd/service.c | 37 +++++++++++++++---------------------- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/source3/include/smb.h b/source3/include/smb.h index a72e9ad..4319a10 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -402,6 +402,7 @@ typedef struct connection_struct { bool printer; bool ipc; bool read_only; /* Attributes for the current user of the share. */ + uint32_t share_access; /* Does this filesystem honor sub second timestamps on files and directories when setting time ? */ diff --git a/source3/smbd/service.c b/source3/smbd/service.c index c1d4dd1..5c410be 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -641,28 +641,21 @@ connection_struct *make_connection_snum(struct smbd_server_connection *sconn, * */ - { - bool can_write = False; - - can_write = share_access_check( - conn->session_info->security_token, - lp_servicename(snum), FILE_WRITE_DATA, NULL); - - if (!can_write) { - if (!share_access_check( - conn->session_info->security_token, - lp_servicename(snum), FILE_READ_DATA, - NULL)) { - /* No access, read or write. */ - DEBUG(0,("make_connection: connection to %s " - "denied due to security " - "descriptor.\n", - lp_servicename(snum))); - *pstatus = NT_STATUS_ACCESS_DENIED; - goto err_root_exit; - } else { - conn->read_only = True; - } + share_access_check(conn->session_info->security_token, + lp_servicename(snum), MAXIMUM_ALLOWED_ACCESS, + &conn->share_access); + + if ((conn->share_access & FILE_WRITE_DATA) == 0) { + if ((conn->share_access & FILE_READ_DATA) == 0) { + /* No access, read or write. */ + DEBUG(0,("make_connection: connection to %s " + "denied due to security " + "descriptor.\n", + lp_servicename(snum))); + *pstatus = NT_STATUS_ACCESS_DENIED; + goto err_root_exit; + } else { + conn->read_only = True; } } /* Initialise VFS function pointers */ -- 1.7.4.1 From 9c0435a2b964bb7585c45a85122ba4c97dbcdfb3 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 5 Jul 2011 11:13:07 +0200 Subject: [PATCH 3/3] s3: Fix bug 8102 We can't allow open with access that has been denied via the share security descriptor --- source3/smbd/open.c | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 86a5924..bbab9f1 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -76,6 +76,14 @@ NTSTATUS smbd_check_open_rights(struct connection_struct *conn, /* Check if we have rights to open. */ NTSTATUS status; struct security_descriptor *sd = NULL; + uint32_t rejected_share_access; + + rejected_share_access = access_mask & ~(conn->share_access); + + if (rejected_share_access) { + *access_granted = rejected_share_access; + return NT_STATUS_ACCESS_DENIED; + } if ((access_mask & DELETE_ACCESS) && !lp_acl_check_permissions(SNUM(conn))) { *access_granted = access_mask; -- 1.7.4.1