summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/proto.h4
-rw-r--r--source3/modules/vfs_acl_xattr.c2
-rw-r--r--source3/smbd/open.c81
-rw-r--r--source4/torture/raw/acls.c2
4 files changed, 85 insertions, 4 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 254c33d075..0d4404b339 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -8040,6 +8040,10 @@ void reply_nttranss(struct smb_request *req);
/* The following definitions come from smbd/open.c */
+NTSTATUS smb1_file_se_access_check(const struct security_descriptor *sd,
+ const NT_USER_TOKEN *token,
+ uint32_t access_desired,
+ uint32_t *access_granted);
NTSTATUS fd_close(files_struct *fsp);
bool map_open_params_to_ntcreate(const char *fname, int deny_mode, int open_func,
uint32 *paccess_mask,
diff --git a/source3/modules/vfs_acl_xattr.c b/source3/modules/vfs_acl_xattr.c
index c3b27f81a5..5dfe43e55b 100644
--- a/source3/modules/vfs_acl_xattr.c
+++ b/source3/modules/vfs_acl_xattr.c
@@ -437,7 +437,7 @@ static int open_acl_xattr(vfs_handle_struct *handle,
&pdesc);
if (NT_STATUS_IS_OK(status)) {
/* See if we can access it. */
- status = se_access_check(pdesc,
+ status = smb1_file_se_access_check(pdesc,
handle->conn->server_info->ptok,
fsp->access_mask,
&access_granted);
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index b134e8f0fd..480352beda 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -30,6 +30,56 @@ struct deferred_open_record {
};
/****************************************************************************
+ SMB1 file varient of se_access_check. Never test FILE_READ_ATTRIBUTES.
+****************************************************************************/
+
+NTSTATUS smb1_file_se_access_check(const struct security_descriptor *sd,
+ const NT_USER_TOKEN *token,
+ uint32_t access_desired,
+ uint32_t *access_granted)
+{
+ return se_access_check(sd,
+ token,
+ (access_desired & ~FILE_READ_ATTRIBUTES),
+ access_granted);
+}
+
+/****************************************************************************
+ Check if we have open rights.
+****************************************************************************/
+
+static NTSTATUS check_open_rights(struct connection_struct *conn,
+ const char *fname,
+ uint32_t access_mask)
+{
+ /* Check if we have rights to open. */
+ NTSTATUS status;
+ uint32_t access_granted = 0;
+ struct security_descriptor *sd;
+
+ status = SMB_VFS_GET_NT_ACL(conn, fname,
+ (OWNER_SECURITY_INFORMATION |
+ GROUP_SECURITY_INFORMATION |
+ DACL_SECURITY_INFORMATION),&sd);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("check_open_rights: Could not get acl "
+ "on %s: %s\n",
+ fname,
+ nt_errstr(status)));
+ return status;
+ }
+
+ status = smb1_file_se_access_check(sd,
+ conn->server_info->ptok,
+ access_mask,
+ &access_granted);
+
+ TALLOC_FREE(sd);
+ return status;
+}
+
+/****************************************************************************
fd support routines - attempt to do a dos_open.
****************************************************************************/
@@ -337,6 +387,17 @@ static NTSTATUS open_file(files_struct *fsp,
} else {
fsp->fh->fd = -1; /* What we used to call a stat open. */
+ if (file_existed) {
+ status = check_open_rights(conn,
+ path,
+ access_mask);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("open_file: Access denied on "
+ "file %s\n",
+ path));
+ return status;
+ }
+ }
}
if (!file_existed) {
@@ -1146,6 +1207,7 @@ static NTSTATUS calculate_access_mask(connection_struct *conn,
/* Calculate MAXIMUM_ALLOWED_ACCESS if requested. */
if (access_mask & MAXIMUM_ALLOWED_ACCESS) {
if (file_existed) {
+
struct security_descriptor *sd;
uint32_t access_granted = 0;
@@ -1162,8 +1224,10 @@ static NTSTATUS calculate_access_mask(connection_struct *conn,
return NT_STATUS_ACCESS_DENIED;
}
- status = se_access_check(sd, conn->server_info->ptok,
- access_mask, &access_granted);
+ status = smb1_file_se_access_check(sd,
+ conn->server_info->ptok,
+ access_mask,
+ &access_granted);
TALLOC_FREE(sd);
@@ -2274,6 +2338,19 @@ NTSTATUS open_directory(connection_struct *conn,
return NT_STATUS_NOT_A_DIRECTORY;
}
+ if (info == FILE_WAS_OPENED) {
+ status = check_open_rights(conn,
+ fname,
+ access_mask);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("open_directory: check_open_rights on "
+ "file %s failed with %s\n",
+ fname,
+ nt_errstr(status)));
+ return status;
+ }
+ }
+
status = file_new(req, conn, &fsp);
if(!NT_STATUS_IS_OK(status)) {
return status;
diff --git a/source4/torture/raw/acls.c b/source4/torture/raw/acls.c
index 2a67bd98c5..862b96ac17 100644
--- a/source4/torture/raw/acls.c
+++ b/source4/torture/raw/acls.c
@@ -1088,7 +1088,7 @@ static bool test_owner_bits(struct torture_context *tctx,
{
NTSTATUS status;
union smb_open io;
- const char *fname = BASEDIR "\\generic.txt";
+ const char *fname = BASEDIR "\\test_owner_bits.txt";
bool ret = true;
int fnum = -1, i;
union smb_fileinfo q;