summaryrefslogtreecommitdiff
path: root/source/smbd/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/smbd/dir.c')
-rw-r--r--source/smbd/dir.c76
1 files changed, 72 insertions, 4 deletions
diff --git a/source/smbd/dir.c b/source/smbd/dir.c
index c2735c032a..604db984af 100644
--- a/source/smbd/dir.c
+++ b/source/smbd/dir.c
@@ -24,6 +24,8 @@
This module implements directory related functions for Samba.
*/
+extern struct current_user current_user;
+
/* "Special" directory offsets. */
#define END_OF_DIRECTORY_OFFSET ((long)-1)
#define START_OF_DIRECTORY_OFFSET ((long)0)
@@ -921,8 +923,13 @@ bool get_dir_entry(TALLOC_CTX *ctx,
use it for anything security sensitive.
********************************************************************/
-static bool user_can_read_file(connection_struct *conn, char *name)
+static bool user_can_read_file(connection_struct *conn, char *name, SMB_STRUCT_STAT *pst)
{
+ SEC_DESC *psd = NULL;
+ files_struct *fsp;
+ NTSTATUS status;
+ uint32 access_granted;
+
/*
* If user is a member of the Admin group
* we never hide files from them.
@@ -932,7 +939,38 @@ static bool user_can_read_file(connection_struct *conn, char *name)
return True;
}
- return can_access_file_acl(conn, name, FILE_READ_DATA);
+ SMB_ASSERT(VALID_STAT(*pst));
+
+ /* Pseudo-open the file (note - no fd's created). */
+
+ if(S_ISDIR(pst->st_mode)) {
+ status = open_directory(conn, NULL, name, pst,
+ READ_CONTROL_ACCESS,
+ FILE_SHARE_READ|FILE_SHARE_WRITE,
+ FILE_OPEN,
+ 0, /* no create options. */
+ FILE_ATTRIBUTE_DIRECTORY,
+ NULL, &fsp);
+ } else {
+ status = open_file_stat(conn, NULL, name, pst, &fsp);
+ }
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return False;
+ }
+
+ /* Get NT ACL -allocated in main loop talloc context. No free needed here. */
+ status = SMB_VFS_FGET_NT_ACL(fsp,
+ (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
+ close_file(fsp, NORMAL_CLOSE);
+
+ /* No access if SD get failed. */
+ if (!NT_STATUS_IS_OK(status)) {
+ return False;
+ }
+
+ return se_access_check(psd, current_user.nt_user_token, FILE_READ_DATA,
+ &access_granted, &status);
}
/*******************************************************************
@@ -944,6 +982,12 @@ static bool user_can_read_file(connection_struct *conn, char *name)
static bool user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_STAT *pst)
{
+ SEC_DESC *psd = NULL;
+ files_struct *fsp;
+ int info;
+ NTSTATUS status;
+ uint32 access_granted;
+
/*
* If user is a member of the Admin group
* we never hide files from them.
@@ -959,9 +1003,33 @@ static bool user_can_write_file(connection_struct *conn, char *name, SMB_STRUCT_
if(S_ISDIR(pst->st_mode)) {
return True;
+ } else {
+ status = open_file_ntcreate(conn, NULL, name, pst,
+ FILE_WRITE_ATTRIBUTES,
+ FILE_SHARE_READ|FILE_SHARE_WRITE,
+ FILE_OPEN,
+ 0,
+ FILE_ATTRIBUTE_NORMAL,
+ INTERNAL_OPEN_ONLY,
+ &info, &fsp);
+ }
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return False;
+ }
+
+ /* Get NT ACL -allocated in main loop talloc context. No free needed here. */
+ status = SMB_VFS_FGET_NT_ACL(fsp,
+ (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION), &psd);
+ close_file(fsp, NORMAL_CLOSE);
+
+ /* No access if SD get failed. */
+ if (!NT_STATUS_IS_OK(status)) {
+ return False;
}
- return can_write_to_file(conn, name, pst);
+ return se_access_check(psd, current_user.nt_user_token, FILE_WRITE_DATA,
+ &access_granted, &status);
}
/*******************************************************************
@@ -1035,7 +1103,7 @@ bool is_visible_file(connection_struct *conn, const char *dir_path, const char *
}
/* Honour _hide unreadable_ option */
- if (hide_unreadable && !user_can_read_file(conn, entry)) {
+ if (hide_unreadable && !user_can_read_file(conn, entry, pst)) {
DEBUG(10,("is_visible_file: file %s is unreadable.\n", entry ));
SAFE_FREE(entry);
return False;