do not expose special files, only files, directories and links (and we
authorSimo Sorce <idra@samba.org>
Sat, 24 Aug 2002 01:33:25 +0000 (01:33 +0000)
committerSimo Sorce <idra@samba.org>
Sat, 24 Aug 2002 01:33:25 +0000 (01:33 +0000)
should really check if a link points to a special file and deny access
imho), expose no fifo, socket, devices ...
(This used to be commit 59954113348cfb2061fa6bd7dfe7545f614e2891)

source3/smbd/dir.c

index 1a18476b75b179f425970133979688363d66e3fe..31bbe0dec2e23f21290c00ee840fb7706494c1d8 100644 (file)
@@ -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) {