summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2015-10-13 16:49:41 -0700
committerKarolin Seeger <kseeger@samba.org>2015-10-20 08:48:17 +0200
commit52d8aeb9e783a17313e81860d58f14ac1f7bb0d5 (patch)
tree8831bb8d2a562abe80106728a683760c59227ab1
parent617ffc4c88c371bab4a4fb5db4025153e97d79c9 (diff)
downloadsamba-52d8aeb9e783a17313e81860d58f14ac1f7bb0d5.tar.gz
s3: smbd: Fix our access-based enumeration on "hide unreadable" to match Windows.
Torture test to follow. https://bugzilla.samba.org/show_bug.cgi?id=10252 Signed-off-by: Jeremy Allison <jra@samba.org> Reviewed-by: Volker Lendecke <vl@samba.org> (cherry picked from commit cc05f73872c36cd307da3d6fed200beb16d5c2a8)
-rw-r--r--source3/smbd/dir.c64
1 files changed, 61 insertions, 3 deletions
diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
index c700cb7dd12..86c5f10ba6a 100644
--- a/source3/smbd/dir.c
+++ b/source3/smbd/dir.c
@@ -1343,6 +1343,15 @@ bool get_dir_entry(TALLOC_CTX *ctx,
static bool user_can_read_file(connection_struct *conn,
struct smb_filename *smb_fname)
{
+ NTSTATUS status;
+ uint32_t rejected_share_access = 0;
+ uint32_t rejected_mask = 0;
+ struct security_descriptor *sd = NULL;
+ uint32_t access_mask = FILE_READ_DATA|
+ FILE_READ_EA|
+ FILE_READ_ATTRIBUTES|
+ SEC_STD_READ_CONTROL;
+
/*
* Never hide files from the root user.
* We use (uid_t)0 here not sec_initial_uid()
@@ -1353,10 +1362,59 @@ static bool user_can_read_file(connection_struct *conn,
return True;
}
- return NT_STATUS_IS_OK(smbd_check_access_rights(conn,
- smb_fname,
+ /*
+ * We can't directly use smbd_check_access_rights()
+ * here, as this implicitly grants FILE_READ_ATTRIBUTES
+ * which the Windows access-based-enumeration code
+ * explicitly checks for on the file security descriptor.
+ * See bug:
+ *
+ * https://bugzilla.samba.org/show_bug.cgi?id=10252
+ *
+ * and the smb2.acl2.ACCESSBASED test for details.
+ */
+
+ rejected_share_access = access_mask & ~(conn->share_access);
+ if (rejected_share_access) {
+ DEBUG(10, ("rejected share access 0x%x "
+ "on %s (0x%x)\n",
+ (unsigned int)access_mask,
+ smb_fname_str_dbg(smb_fname),
+ (unsigned int)rejected_share_access ));
+ return false;
+ }
+
+ status = SMB_VFS_GET_NT_ACL(conn,
+ smb_fname->base_name,
+ (SECINFO_OWNER |
+ SECINFO_GROUP |
+ SECINFO_DACL),
+ talloc_tos(),
+ &sd);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("Could not get acl "
+ "on %s: %s\n",
+ smb_fname_str_dbg(smb_fname),
+ nt_errstr(status)));
+ return false;
+ }
+
+ status = se_file_access_check(sd,
+ get_current_nttok(conn),
false,
- FILE_READ_DATA));
+ access_mask,
+ &rejected_mask);
+
+ TALLOC_FREE(sd);
+
+ if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
+ DEBUG(10,("rejected bits 0x%x read access for %s\n",
+ (unsigned int)rejected_mask,
+ smb_fname_str_dbg(smb_fname) ));
+ return false;
+ }
+ return true;
}
/*******************************************************************