summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/smbd/dir.c100
1 files changed, 49 insertions, 51 deletions
diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
index 1a18476b75..31bbe0dec2 100644
--- a/source3/smbd/dir.c
+++ b/source3/smbd/dir.c
@@ -671,10 +671,9 @@ it is used as part of the "hide unreadable" option. Don't
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, SMB_STRUCT_STAT *ste, char *name)
{
extern struct current_user current_user;
- SMB_STRUCT_STAT ste;
SEC_DESC *psd = NULL;
size_t sd_size;
files_struct *fsp;
@@ -683,8 +682,6 @@ static BOOL user_can_read_file(connection_struct *conn, char *name)
NTSTATUS status;
uint32 access_granted;
- ZERO_STRUCT(ste);
-
/*
* If user is a member of the Admin group
* we never hide files from them.
@@ -693,17 +690,13 @@ static BOOL user_can_read_file(connection_struct *conn, char *name)
if (conn->admin_user)
return True;
- /* If we can't stat it does not show it */
- if (vfs_stat(conn, name, &ste) != 0)
- return False;
-
/* Pseudo-open the file (note - no fd's created). */
- if(S_ISDIR(ste.st_mode))
- fsp = open_directory(conn, name, &ste, 0, SET_DENY_MODE(DENY_NONE), (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
+ if(S_ISDIR(ste->st_mode))
+ fsp = open_directory(conn, name, ste, 0, SET_DENY_MODE(DENY_NONE), (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
unix_mode(conn,aRONLY|aDIR, name), &smb_action);
else
- fsp = open_file_shared1(conn, name, &ste, FILE_READ_ATTRIBUTES, SET_DENY_MODE(DENY_NONE),
+ fsp = open_file_shared1(conn, name, ste, FILE_READ_ATTRIBUTES, SET_DENY_MODE(DENY_NONE),
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &smb_action);
if (!fsp)
@@ -728,10 +721,9 @@ it is used as part of the "hide unwriteable" option. Don't
use it for anything security sensitive
********************************************************************/
-static BOOL user_can_write_file(connection_struct *conn, char *name)
+static BOOL user_can_write_file(connection_struct *conn, SMB_STRUCT_STAT *ste, char *name)
{
extern struct current_user current_user;
- SMB_STRUCT_STAT ste;
SEC_DESC *psd = NULL;
size_t sd_size;
files_struct *fsp;
@@ -740,26 +732,12 @@ static BOOL user_can_write_file(connection_struct *conn, char *name)
NTSTATUS status;
uint32 access_granted;
- ZERO_STRUCT(ste);
-
- /*
- * If user is a member of the Admin group
- * we never hide files from them.
- */
-
- if (conn->admin_user)
- return True;
-
- /* If we can't stat it does not show it */
- if (vfs_stat(conn, name, &ste) != 0)
- return False;
-
/* Pseudo-open the file (note - no fd's created). */
- if(S_ISDIR(ste.st_mode))
+ if(S_ISDIR(ste->st_mode))
return True;
else
- fsp = open_file_shared1(conn, name, &ste, FILE_WRITE_ATTRIBUTES, SET_DENY_MODE(DENY_NONE),
+ fsp = open_file_shared1(conn, name, ste, FILE_WRITE_ATTRIBUTES, SET_DENY_MODE(DENY_NONE),
(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), 0, 0, &access_mode, &smb_action);
if (!fsp)
@@ -785,6 +763,7 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto)
{
Dir *dirp;
char *n;
+ SMB_STRUCT_STAT ste;
DIR *p = conn->vfs_ops.opendir(conn,name);
int used=0;
@@ -820,34 +799,53 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto)
l = strlen(n)+1;
- /* If it's a vetoed file, pretend it doesn't even exist */
- if (normal_entry && use_veto && conn && IS_VETO_PATH(conn, n))
- continue;
+ /*
+ * If user is a member of the Admin group
+ * we never hide files from them.
+ */
+
+ if (!conn->admin_user && normal_entry && conn) {
+
+ /* If it's a vetoed file, pretend it doesn't even exist */
+ if (use_veto && IS_VETO_PATH(conn, n))
+ continue;
+
+ ZERO_STRUCT(ste);
- /* Honour _hide unreadable_ option */
- if (normal_entry && conn && lp_hideunreadable(SNUM(conn))) {
- char *entry;
- int ret=0;
+ /* If we can't stat it does not show it */
+ if (vfs_stat(conn, n, &ste) != 0)
+ continue;
+
+ /* If it is a special file, do not show it! */
+ /* FIXME: maybe we should put an option to unhide special files?? --simo */
+ if (!S_ISREG(ste.st_mode) && !S_ISDIR(ste.st_mode) && !S_ISLNK(ste.st_mode))
+ continue;
+
+ /* Honour _hide unreadable_ option */
+ if (lp_hideunreadable(SNUM(conn))) {
+ char *entry;
+ int ret=0;
- if (asprintf(&entry, "%s/%s/%s", conn->origpath, name, n) > 0) {
- ret = user_can_read_file(conn, entry);
- SAFE_FREE(entry);
+ if (asprintf(&entry, "%s/%s/%s", conn->origpath, name, n) > 0) {
+ ret = user_can_read_file(conn, &ste, entry);
+ SAFE_FREE(entry);
+ }
+ if (!ret)
+ continue;
}
- if (!ret)
- continue;
- }
- /* Honour _hide unwriteable_ option */
- if (normal_entry && conn && lp_hideunwriteable_files(SNUM(conn))) {
- char *entry;
- int ret=0;
+ /* Honour _hide unwriteable_ option */
+ if (normal_entry && conn && lp_hideunwriteable_files(SNUM(conn))) {
+ char *entry;
+ int ret=0;
- if (asprintf(&entry, "%s/%s/%s", conn->origpath, name, n) > 0) {
- ret = user_can_write_file(conn, entry);
- SAFE_FREE(entry);
+ if (asprintf(&entry, "%s/%s/%s", conn->origpath, name, n) > 0) {
+ ret = user_can_write_file(conn, &ste, entry);
+ SAFE_FREE(entry);
+ }
+ if (!ret)
+ continue;
}
- if (!ret)
- continue;
}
if (used + l > dirp->mallocsize) {