added, tested and debugged new "hide files" option.
authorSamba Release Account <samba-bugs@samba.org>
Sun, 6 Jul 1997 13:48:10 +0000 (13:48 +0000)
committerSamba Release Account <samba-bugs@samba.org>
Sun, 6 Jul 1997 13:48:10 +0000 (13:48 +0000)
lkcl
(This used to be commit 60af320a436c3a26230fd7ac71856e67ef64e819)

source3/include/proto.h
source3/include/smb.h
source3/lib/util.c
source3/param/loadparm.c
source3/smbd/chgpasswd.c
source3/smbd/dir.c
source3/smbd/reply.c
source3/smbd/server.c
source3/smbd/trans2.c

index 8aecf7907ad725977374e73d55299854d3b1d04a..aae5b3a63b9c9e00a9368d79f7b49af18549bab3 100644 (file)
@@ -73,13 +73,13 @@ void dptr_closecnum(int cnum);
 void dptr_idlecnum(int cnum);
 void dptr_closepath(char *path,int pid);
 int dptr_create(int cnum,char *path, BOOL expect_close,int pid);
-BOOL dptr_fill(char *buf1,unsigned int key);
+BOOL dptr_fill(int snum, char *buf1,unsigned int key);
 BOOL dptr_zero(char *buf);
-void *dptr_fetch(char *buf,int *num);
-void *dptr_fetch_lanman2(char *params,int dptr_num);
+void *dptr_fetch(int snum, char *buf,int *num);
+void *dptr_fetch_lanman2(int snum, char *params,int dptr_num);
 BOOL dir_check_ftype(int cnum,int mode,struct stat *st,int dirtype);
 BOOL get_dir_entry(int cnum,char *mask,int dirtype,char *fname,int *size,int *mode,time_t *date,BOOL check_descend);
-void *OpenDir(char *name, BOOL use_veto);
+void *OpenDir(int snum, char *name, BOOL use_veto);
 void CloseDir(void *p);
 char *ReadDirName(void *p);
 BOOL SeekDir(void *p,int pos);
@@ -141,7 +141,6 @@ char *lp_username_map(void);
 char *lp_character_set(void);
 char *lp_logon_script(void);
 char *lp_logon_path(void);
-char *lp_veto_files(void);
 char *lp_remote_announce(void);
 char *lp_wins_server(void);
 char *lp_interfaces(void);
@@ -219,6 +218,8 @@ char *lp_readlist(int );
 char *lp_writelist(int );
 char *lp_volume(int );
 char *lp_mangled_map(int );
+char *lp_veto_files(int );
+char *lp_hide_files(int );
 BOOL lp_alternate_permissions(int );
 BOOL lp_revalidate(int );
 BOOL lp_casesensitive(int );
@@ -948,8 +949,9 @@ char *gidtoname(int gid);
 void BlockSignals(BOOL block,int signum);
 void ajt_panic(void);
 char *readdirname(void *p);
-BOOL is_vetoed_name(char *name);
-BOOL is_vetoed_path(char *name);
+BOOL is_hidden_path(int snum, char *name);
+BOOL is_vetoed_name(int snum, char *name);
+BOOL is_in_path(char *name, char *namelist);
 BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type);
 int file_lock(char *name,int timeout);
 void file_unlock(int fd);
index ddbd05792dfab7984ef9245b33da1c8ed2725b41..d4ad9105fe51ee9c1f1f579a475c5195b0f0793d 100644 (file)
@@ -915,4 +915,7 @@ enum case_handling {CASE_LOWER,CASE_UPPER};
 /* Size of buffer to use when moving files across filesystems. */
 #define COPYBUF_SIZE (8*1024)
 
+/* service-based parameter - files are not visible, but are accessible */
+#define DEFAULT_FILES_TO_HIDE "*/.*"
+
 /* _SMB_H */
index 31cb4d6629d20e8e9e06e394470add1a0f2bebdb..0ee6947d098be82d7ddcf4ea4c26bee2c28d3332 100644 (file)
@@ -3433,99 +3433,95 @@ char *readdirname(void *p)
 }
 
 
-BOOL is_vetoed_name(char *name)
+BOOL is_hidden_path(int snum, char *name)
 {
-  char *namelist = lp_veto_files();
-  char *nameptr = namelist;
-  char *name_end;
-
-  /* if we have no list it's obviously not vetoed */
-  if((nameptr == NULL ) || (*nameptr == '\0')) 
-    return 0;
-
-  /* if the name doesn't exist in the list, it's obviously ok too */
-  if(strstr(namelist,name) == NULL ) 
-    return 0;
+   return is_in_path(name, lp_hide_files(snum));
+}
 
-  /* now, we need to find the names one by one and check them
-     they can contain spaces and all sorts of stuff so we
-     separate them with of all things '/' which can never be in a filename
-     I could use "" but then I have to break them all out
-     maybe such a routine exists somewhere?
-  */
-  while(*nameptr) 
-    {
-      if ( *nameptr == '/' ) 
-        {
-          nameptr++;
-          continue;
-        }
-      if((name_end = strchr(nameptr,'/'))!=NULL) 
-        {
-          *name_end = 0;
-        }
-      /* a match! it's veto'd */
-      if(strcmp(name,nameptr) == 0) 
-        return 1;
-      if(name_end == NULL) 
-        return 0;
-      /* next segment please */
-      nameptr = name_end + 1;
-    }
-  return 0;
+BOOL is_vetoed_name(int snum, char *name)
+{
+   return is_in_path(name, lp_veto_files(snum));
 }
 
-BOOL is_vetoed_path(char *name)
+BOOL is_in_path(char *name, char *namelist)
 {
-  char *namelist = lp_veto_files();
+
   char *nameptr = namelist;
-  char *sub;
   char *name_end;
-  int len;
 
-  /* if we have no list it's obviously not vetoed */
-  if((nameptr == NULL ) || (*nameptr == '\0')) 
-    return 0;
+  DEBUG(5, ("is_in_path: %s list: %s\n", name, namelist));
 
+  /* if we have no list it's obviously not in the path */
+  if((nameptr == NULL ) || (*nameptr == '\0')) 
+  {
+    DEBUG(5,("is_in_path: no name list.  return False\n"));
+    return False;
+  }
 
   /* now, we need to find the names one by one and check them
      they can contain spaces and all sorts of stuff so we
-     separate them with of all things '/' which can never be in a filename
+     separate them with of all things '\' which can never be in a filename
      I could use "" but then I have to break them all out
      maybe such a routine exists somewhere?
   */
-  while(*nameptr) 
+  /* lkcl 03jul97 - the separator character used to be a '/'.
+     i changed it to a '\', after examining the code, and seeing
+     that unix_convert is called before check_path and dos_mode.
+     unix_convert changes, in the path, all dos '\'s to unix '/'s.
+
+     therefore, users might want to match against '/'s in the path,
+     and therefore '\' must be used as the separator.
+
+     the alternatives are:
+
+     1) move all check_path and dos_mode calls to before the
+        unix_convert calls.
+
+     2) have a corresponding dos_convert call, which can be used
+        in here to reverse '/'s into '\'s and vice-versa.  users
+        would specify the lp_veto_files and lp_hide_files parameters
+        in dos mode path format ('\' for directory separator), with a
+        list separator of '/', and they would be swapped inside this
+        function, before making the search.
+
+   */
+
+  while (*nameptr) 
     {
-      if ( *nameptr == '/' ) 
-        {
+      if ( *nameptr == '\\' ) 
+      {
+          /* cope with multiple (useless) \s) */
           nameptr++;
           continue;
-        }
-      if((name_end = strchr(nameptr,'/'))!=NULL) 
-        {
+      }
+      /* find the next \ */
+      if ((name_end = strchr(nameptr,'\\')) != NULL) 
+      {
           *name_end = 0;
-        }
-
-      len = strlen(nameptr);
-      sub = name;
-      /* If the name doesn't exist in the path, try the next name.. */
-      while( sub && ((sub = strstr(sub,nameptr)) != NULL)) 
-        {
-           /* Is it a whole component? */
-           if(((sub == name) || (sub[-1] == '/'))
-                && ((sub[len] == '\0') || (sub[len] == '/'))) 
-             {
-               return 1;
-             }
-           /* skip to the next component of the path */
-              sub =strchr(sub,'/');
-         }
-      if(name_end == NULL) 
-        return 0;
+      }
+
+      /* look for a match. */
+      if (mask_match(name, nameptr, case_sensitive, False))
+      {
+         DEBUG(5,("is_in_path: mask match succeeded\n"));
+         return True;
+      }
+
+      /* oops - the last check for a \ didn't find one. */
+      if (name_end == NULL)
+      {
+         DEBUG(5,("is_in_path: last name.  failed\n"));
+         return False;
+      }
+
       /* next segment please */
       nameptr = name_end + 1;
     }
-  return 0;
+  
+  DEBUG(5,("is_in_path: not found\n"));
+
+  return False;
 }
 
 /****************************************************************************
index 4c6ce30b193e3643f52237d2758b3c8328aafa9b..dbe711eac6df9b3d69a2af0a7f08d69bf08e89ac 100644 (file)
@@ -129,7 +129,6 @@ typedef struct
   char *szCharacterSet;
   char *szLogonScript;
   char *szLogonPath;
-  char *szVetoFiles;
   char *szSmbrun;
   char *szWINSserver;
   char *szInterfaces;
@@ -214,6 +213,8 @@ typedef struct
   char *szMagicScript;
   char *szMagicOutput;
   char *szMangledMap;
+  char *szVetoFiles;
+  char *szHideFiles;
   char *comment;
   char *force_user;
   char *force_group;
@@ -291,6 +292,8 @@ static service sDefault =
   NULL,    /* szMagicScript */
   NULL,    /* szMagicOutput */
   NULL,    /* szMangledMap */
+  NULL,    /* szVetoFiles */
+  DEFAULT_FILES_TO_HIDE,    /* szVetoFiles */
   NULL,    /* comment */
   NULL,    /* force user */
   NULL,    /* force group */
@@ -395,7 +398,6 @@ struct parm_struct
   {"socket options",   P_GSTRING, P_GLOBAL, user_socket_options,        NULL},
   {"netbios name",     P_UGSTRING,P_GLOBAL, myname,                     NULL},
   {"smbrun",           P_STRING,  P_GLOBAL, &Globals.szSmbrun,          NULL},
-  {"veto files",       P_STRING,  P_GLOBAL, &Globals.szVetoFiles,       NULL},
   {"log file",         P_STRING,  P_GLOBAL, &Globals.szLogFile,         NULL},
   {"config file",      P_STRING,  P_GLOBAL, &Globals.szConfigFile,      NULL},
   {"smb passwd file",  P_STRING,  P_GLOBAL, &Globals.szSMBPasswdFile,   NULL},
@@ -509,6 +511,8 @@ struct parm_struct
   {"set directory",    P_BOOLREV, P_LOCAL,  &sDefault.bNo_set_dir,      NULL},
   {"status",           P_BOOL,    P_LOCAL,  &sDefault.status,           NULL},
   {"hide dot files",   P_BOOL,    P_LOCAL,  &sDefault.bHideDotFiles,    NULL},
+  {"veto files",       P_STRING,  P_LOCAL,  &sDefault.szVetoFiles,      NULL},
+  {"hide files",       P_STRING,  P_LOCAL,  &sDefault.szHideFiles,      NULL},
   {"guest only",       P_BOOL,    P_LOCAL,  &sDefault.bGuest_only,      NULL},
   {"only guest",       P_BOOL,    P_LOCAL,  &sDefault.bGuest_only,      NULL},
   {"guest ok",         P_BOOL,    P_LOCAL,  &sDefault.bGuest_ok,        NULL},
@@ -810,7 +814,6 @@ FN_GLOBAL_STRING(lp_username_map,&Globals.szUsernameMap)
 FN_GLOBAL_STRING(lp_character_set,&Globals.szCharacterSet) 
 FN_GLOBAL_STRING(lp_logon_script,&Globals.szLogonScript) 
 FN_GLOBAL_STRING(lp_logon_path,&Globals.szLogonPath) 
-FN_GLOBAL_STRING(lp_veto_files,&Globals.szVetoFiles)
 FN_GLOBAL_STRING(lp_remote_announce,&Globals.szRemoteAnnounce) 
 FN_GLOBAL_STRING(lp_wins_server,&Globals.szWINSserver)
 FN_GLOBAL_STRING(lp_interfaces,&Globals.szInterfaces)
@@ -891,6 +894,8 @@ FN_LOCAL_STRING(lp_readlist,readlist)
 FN_LOCAL_STRING(lp_writelist,writelist)
 FN_LOCAL_STRING(lp_volume,volume)
 FN_LOCAL_STRING(lp_mangled_map,szMangledMap)
+FN_LOCAL_STRING(lp_veto_files,szVetoFiles)
+FN_LOCAL_STRING(lp_hide_files,szHideFiles)
 
 FN_LOCAL_BOOL(lp_alternate_permissions,bAlternatePerm)
 FN_LOCAL_BOOL(lp_revalidate,bRevalidate)
index e0dd7fc0aeaebf8b98e1e4fa0fe34a7c071fe2d2..79ea66253dc04f3877a015a362c139e521ecbce6 100644 (file)
@@ -56,7 +56,7 @@ static int findpty(char **slave)
 #else
   strcpy( line, "/dev/ptyXX" );
 
-  dirp = OpenDir("/dev", True);
+  dirp = OpenDir(-1, "/dev", True);
   if (!dirp) return(-1);
   while ((dpname = ReadDirName(dirp)) != NULL) {
     if (strncmp(dpname, "pty", 3) == 0 && strlen(dpname) == 5) {
index 1d0228864cc2c71fc0eb8bab049bf4b81c023ff3..2a219e0281a466bd5e7cdd62cf8714ccff21dfe8 100644 (file)
@@ -108,7 +108,7 @@ static void dptr_idleoldest(void)
 /****************************************************************************
 get the dir ptr for a dir index
 ****************************************************************************/
-static void *dptr_get(int key,uint32 lastused)
+static void *dptr_get(int snum, int key,uint32 lastused)
 {
   if (dirptrs[key].valid) {
     if (lastused) dirptrs[key].lastused = lastused;
@@ -116,7 +116,7 @@ static void *dptr_get(int key,uint32 lastused)
       if (dptrs_open >= MAXDIR)
        dptr_idleoldest();
       DEBUG(4,("Reopening dptr key %d\n",key));
-      if ((dirptrs[key].ptr = OpenDir(dirptrs[key].path, True)))
+      if ((dirptrs[key].ptr = OpenDir(snum, dirptrs[key].path, True)))
        dptrs_open++;
     }
     return(dirptrs[key].ptr);
@@ -259,7 +259,7 @@ static BOOL start_dir(int cnum,char *directory)
   if (! *directory)
     directory = ".";
 
-  Connections[cnum].dirptr = OpenDir(directory, True);
+  Connections[cnum].dirptr = OpenDir(SNUM(cnum), directory, True);
   if (Connections[cnum].dirptr) {    
     dptrs_open++;
     string_set(&Connections[cnum].dirpath,directory);
@@ -345,10 +345,10 @@ int dptr_create(int cnum,char *path, BOOL expect_close,int pid)
 /****************************************************************************
 fill the 5 byte server reserved dptr field
 ****************************************************************************/
-BOOL dptr_fill(char *buf1,unsigned int key)
+BOOL dptr_fill(int snum, char *buf1,unsigned int key)
 {
   unsigned char *buf = (unsigned char *)buf1;
-  void *p = dptr_get(key,0);
+  void *p = dptr_get(snum, key,0);
   uint32 offset;
   if (!p) {
     DEBUG(1,("filling null dirptr %d\n",key));
@@ -373,10 +373,10 @@ BOOL dptr_zero(char *buf)
 /****************************************************************************
 fetch the dir ptr and seek it given the 5 byte server field
 ****************************************************************************/
-void *dptr_fetch(char *buf,int *num)
+void *dptr_fetch(int snum, char *buf,int *num)
 {
   unsigned int key = *(unsigned char *)buf;
-  void *p = dptr_get(key,dircounter++);
+  void *p = dptr_get(snum, key,dircounter++);
   uint32 offset;
   if (!p) {
     DEBUG(3,("fetched null dirptr %d\n",key));
@@ -393,9 +393,9 @@ void *dptr_fetch(char *buf,int *num)
 /****************************************************************************
 fetch the dir ptr and seek it given the lanman2 parameter block
 ****************************************************************************/
-void *dptr_fetch_lanman2(char *params,int dptr_num)
+void *dptr_fetch_lanman2(int snum, char *params,int dptr_num)
 {
-  void *p = dptr_get(dptr_num,dircounter++);
+  void *p = dptr_get(snum, dptr_num,dircounter++);
   uint32 resume_key = SVAL(params,6);
   BOOL uses_resume_key = BITSETW(params+10,2);
   BOOL continue_bit = BITSETW(params+10,3);
@@ -520,7 +520,7 @@ typedef struct
 /*******************************************************************
 open a directory
 ********************************************************************/
-void *OpenDir(char *name, BOOL use_veto)
+void *OpenDir(int snum, char *name, BOOL use_veto)
 {
   Dir *dirp;
   char *n;
@@ -536,11 +536,13 @@ void *OpenDir(char *name, BOOL use_veto)
   dirp->pos = dirp->numentries = dirp->mallocsize = 0;
   dirp->data = dirp->current = NULL;
 
-  while ((n = readdirname(p))) {
+  while ((n = readdirname(p)))
+  {
     int l = strlen(n)+1;
+
     /* If it's a vetoed file, pretend it doesn't even exist */
-    if(use_veto && is_vetoed_name(n))
-      continue;
+    if (use_veto && is_vetoed_name(snum, n)) continue;
+
     if (used + l > dirp->mallocsize) {
       int s = MAX(used+l,used+2000);
       char *r;
index 5f030d537241a6250f769709787400a031138b13..af980943caab0f2e4d32fa4c3e0e14a88e7d084d 100644 (file)
@@ -767,7 +767,7 @@ int reply_search(char *inbuf,char *outbuf)
       memcpy(mask,status+1,11);
       mask[11] = 0;
       dirtype = CVAL(status,0) & 0x1F;
-      Connections[cnum].dirptr = dptr_fetch(status+12,&dptr_num);      
+      Connections[cnum].dirptr = dptr_fetch(SNUM(cnum), status+12,&dptr_num);      
       if (!Connections[cnum].dirptr)
        goto SearchEmpty;
       string_set(&Connections[cnum].dirpath,dptr_path(dptr_num));
@@ -832,7 +832,7 @@ int reply_search(char *inbuf,char *outbuf)
            {     
              memcpy(p,status,21);
              make_dir_struct(p,"???????????",volume_label(SNUM(cnum)),0,aVOLID,0);
-             dptr_fill(p+12,dptr_num);
+             dptr_fill(SNUM(cnum), p+12,dptr_num);
              if (dptr_zero(p+12) && (status_len==0))
                numentries = 1;
              else
@@ -854,7 +854,7 @@ int reply_search(char *inbuf,char *outbuf)
                    {
                      memcpy(p,status,21);
                      make_dir_struct(p,mask,fname,size,mode,date);
-                     dptr_fill(p+12,dptr_num);
+                     dptr_fill(SNUM(cnum), p+12,dptr_num);
                      numentries++;
                    }
                  p += DIR_STRUCT_SIZE;
@@ -937,7 +937,7 @@ int reply_fclose(char *inbuf,char *outbuf)
 
   memcpy(status,smb_buf(inbuf) + 1 + strlen(path) + 4,21);
 
-  if(dptr_fetch(status+12,&dptr_num)) {
+  if(dptr_fetch(SNUM(cnum), status+12,&dptr_num)) {
     /*  Close the dptr - we know it's gone */
     dptr_close(dptr_num);
   }
@@ -1326,7 +1326,7 @@ int reply_unlink(char *inbuf,char *outbuf)
     char *dname;
 
     if (check_name(directory,cnum))
-      dirptr = OpenDir(directory, True);
+      dirptr = OpenDir(SNUM(cnum), directory, True);
 
     /* XXXX the CIFS spec says that if bit0 of the flags2 field is set then
        the pattern matches against the long name, otherwise the short name 
@@ -2736,7 +2736,7 @@ int reply_mv(char *inbuf,char *outbuf)
     pstring destname;
 
     if (check_name(directory,cnum))
-      dirptr = OpenDir(directory, True);
+      dirptr = OpenDir(SNUM(cnum), directory, True);
 
     if (dirptr)
       {
@@ -2927,7 +2927,7 @@ int reply_copy(char *inbuf,char *outbuf)
     pstring destname;
 
     if (check_name(directory,cnum))
-      dirptr = OpenDir(directory, True);
+      dirptr = OpenDir(SNUM(cnum), directory, True);
 
     if (dirptr)
       {
index 30d8ce3d2a3caa255842f1ddace5351ab50f0ee8..0361c5aa4679df86de41aa0f222121781e933d29 100644 (file)
@@ -179,6 +179,8 @@ int dos_mode(int cnum,char *path,struct stat *sbuf)
   int result = 0;
   extern struct current_user current_user;
 
+  DEBUG(5,("dos_mode: %d %s\n", cnum, path));
+
   if (CAN_WRITE(cnum) && !lp_alternate_permissions(SNUM(cnum))) {
     if (!((sbuf->st_mode & S_IWOTH) ||
          Connections[cnum].admin_user ||
@@ -222,6 +224,21 @@ int dos_mode(int cnum,char *path,struct stat *sbuf)
        result |= aHIDDEN;
     }
 
+  if (is_hidden_path(SNUM(cnum), path))
+  {
+    result |= aHIDDEN;
+  }
+
+  DEBUG(5,("dos_mode returning "));
+
+  if (result & aHIDDEN) DEBUG(5, ("h"));
+  if (result & aRONLY ) DEBUG(5, ("r"));
+  if (result & aSYSTEM) DEBUG(5, ("s"));
+  if (result & aDIR   ) DEBUG(5, ("d"));
+  if (result & aARCH  ) DEBUG(5, ("a"));
+
+  DEBUG(5,("\n"));
+
   return(result);
 }
 
@@ -361,7 +378,7 @@ static BOOL scan_directory(char *path, char *name,int snum,BOOL docache)
     check_mangled_stack(name);
 
   /* open the directory */
-  if (!(cur_dir = OpenDir(path, True))) 
+  if (!(cur_dir = OpenDir(snum, path, True))) 
     {
       DEBUG(3,("scan dir didn't open dir [%s]\n",path));
       return(False);
@@ -791,7 +808,7 @@ BOOL check_name(char *name,int cnum)
 
   errno = 0;
 
-  if( is_vetoed_path(name)) 
+  if( is_vetoed_name(SNUM(cnum), name)) 
     {
       DEBUG(5,("file path name %s vetoed\n",name));
       return(0);
index 1f727c4ecdf7907c0ba7c8baeb10322ccc4aa29d..6f8fe5121a0d6a7677e197a9083564565ea406b7 100644 (file)
@@ -782,7 +782,7 @@ static int call_trans2findnext(char *inbuf, char *outbuf, int length, int bufsiz
     return(ERROR(ERRDOS,ERRnomem));
 
   /* Check that the dptr is valid */
-  if(!(Connections[cnum].dirptr = dptr_fetch_lanman2(params, dptr_num)))
+  if(!(Connections[cnum].dirptr = dptr_fetch_lanman2(SNUM(cnum), params, dptr_num)))
     return(ERROR(ERRDOS,ERRnofiles));
 
   string_set(&Connections[cnum].dirpath,dptr_path(dptr_num));