diff options
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/dir.c | 100 |
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) { |