interface.c: Fix for AIX4.x finding interfaces.
[samba.git] / source3 / smbd / server.c
index c808eac06ac96c0c6bb4c4c41c8db9e8dac9218d..528e4769ea42df64c94e9c0dfddc827a2c286c41 100644 (file)
@@ -130,8 +130,12 @@ void  killkids(void)
          dos archive is represented in unix by the user's execute bit
          dos system is represented in unix by the group's execute bit
          dos hidden is represented in unix by the other's execute bit
+         Then apply create mask,
+         then add force bits.
     base permission for directories:
          dos directory is represented in unix by unix's dir bit and the exec bit
+         Then apply create mask,
+         then add force bits.
 ****************************************************************************/
 mode_t unix_mode(int cnum,int dosmode)
 {
@@ -144,7 +148,10 @@ mode_t unix_mode(int cnum,int dosmode)
     /* We never make directories read only for the owner as under DOS a user
        can always create a file in a read-only directory. */
     result |= (S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH | S_IWUSR);
+    /* Apply directory mask */
     result &= lp_dir_mode(SNUM(cnum));
+    /* Add in force bits */
+    result |= lp_force_dir_mode(SNUM(cnum));
   } else { 
     if (MAP_ARCHIVE(cnum) && IS_DOS_ARCHIVE(dosmode))
       result |= S_IXUSR;
@@ -155,7 +162,10 @@ mode_t unix_mode(int cnum,int dosmode)
     if (MAP_HIDDEN(cnum) && IS_DOS_HIDDEN(dosmode))
       result |= S_IXOTH;  
  
-    result &= CREATE_MODE(cnum);
+    /* Apply mode mask */
+    result &= lp_create_mode(SNUM(cnum));
+    /* Add in force bits */
+    result |= lp_force_create_mode(SNUM(cnum));
   }
   return(result);
 }
@@ -169,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 ||
@@ -212,6 +224,23 @@ int dos_mode(int cnum,char *path,struct stat *sbuf)
        result |= aHIDDEN;
     }
 
+  /* Optimization : Only call is_hidden_path if it's not already
+     hidden. */
+  if (!(result & aHIDDEN) && 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);
 }
 
@@ -351,7 +380,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))) 
+  if (!(cur_dir = OpenDir(snum, path, True))) 
     {
       DEBUG(3,("scan dir didn't open dir [%s]\n",path));
       return(False);
@@ -368,7 +397,7 @@ static BOOL scan_directory(char *path, char *name,int snum,BOOL docache)
       if (!name_map_mangle(name2,False,snum)) continue;
 
       if ((mangled && mangled_equal(name,name2))
-         || fname_equal(name, name2))
+         || fname_equal(name, dname))
        {
          /* we've found the file, change it's name and return */
          if (docache) DirCacheAdd(path,name,dname,snum);
@@ -593,6 +622,14 @@ static void disk_norm(int *bsize,int *dfree,int *dsize)
 int disk_free(char *path,int *bsize,int *dfree,int *dsize)
 {
   char *df_command = lp_dfree_command();
+  int dfree_retval;
+#ifdef QUOTAS
+  int dfreeq_retval;
+  int dfreeq = 0;
+  int bsizeq = *bsize;
+  int dsizeq = *dsize;
+#endif
+
 #ifndef NO_STATFS
 #ifdef USE_STATVFS
   struct statvfs fs;
@@ -605,15 +642,6 @@ int disk_free(char *path,int *bsize,int *dfree,int *dsize)
 #endif
 #endif
 
-#ifdef QUOTAS
-  if (disk_quotas(path, bsize, dfree, dsize))
-    {
-      disk_norm(bsize,dfree,dsize);
-      return(((*bsize)/1024)*(*dfree));
-    }
-#endif
-
-
   /* possibly use system() to get the result */
   if (df_command && *df_command)
     {
@@ -629,22 +657,42 @@ int disk_free(char *path,int *bsize,int *dfree,int *dsize)
       DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
          
       {
-       FILE *f = fopen(outfile,"r");   
-       *dsize = 0;
-       *dfree = 0;
-       *bsize = 1024;
-       if (f)
-         {
-           fscanf(f,"%d %d %d",dsize,dfree,bsize);
-           fclose(f);
-         }
-       else
-         DEBUG(0,("Can't open %s\n",outfile));
+        FILE *f = fopen(outfile,"r");  
+        *dsize = 0;
+        *dfree = 0;
+        *bsize = 1024;
+        if (f)
+          {
+            fscanf(f,"%d %d %d",dsize,dfree,bsize);
+            fclose(f);
+          }
+        else
+          DEBUG(0,("Can't open %s\n",outfile));
       }
          
       unlink(outfile);
       disk_norm(bsize,dfree,dsize);
-      return(((*bsize)/1024)*(*dfree));
+      dfree_retval = ((*bsize)/1024)*(*dfree);
+#ifdef QUOTAS
+      /* Ensure we return the min value between the users quota and
+         what's free on the disk. Thanks to Albrecht Gebhardt 
+         <albrecht.gebhardt@uni-klu.ac.at> for this fix.
+      */
+      if (disk_quotas(path, &bsizeq, &dfreeq, &dsizeq))
+        {
+          disk_norm(&bsizeq, &dfreeq, &dsizeq);
+          dfreeq_retval = ((bsizeq)/1024)*(dfreeq);
+          dfree_retval =  ( dfree_retval < dfreeq_retval ) ? 
+                           dfree_retval : dfreeq_retval ;
+          /* maybe dfree and dfreeq are calculated using different bsizes 
+             so convert dfree from bsize into bsizeq */
+          *dfree = ((*dfree) * (*bsize)) / (bsizeq);
+          *dfree = ( *dfree < dfreeq ) ? *dfree : dfreeq ; 
+          *bsize = bsizeq;
+          *dsize = dsizeq;
+        }
+#endif
+      return(dfree_retval);
     }
 
 #ifdef NO_STATFS
@@ -714,7 +762,27 @@ if ((*bsize) < 512 || (*bsize)>0xFFFF) *bsize = 1024;
       *dsize = 20*1024*1024/(*bsize);
       *dfree = MAX(1,*dfree);
     }
-  return(((*bsize)/1024)*(*dfree));
+  dfree_retval = ((*bsize)/1024)*(*dfree);
+#ifdef QUOTAS
+  /* Ensure we return the min value between the users quota and
+     what's free on the disk. Thanks to Albrecht Gebhardt 
+     <albrecht.gebhardt@uni-klu.ac.at> for this fix.
+  */
+  if (disk_quotas(path, &bsizeq, &dfreeq, &dsizeq))
+    {
+      disk_norm(&bsizeq, &dfreeq, &dsizeq);
+      dfreeq_retval = ((bsizeq)/1024)*(dfreeq);
+      dfree_retval = ( dfree_retval < dfreeq_retval ) ? 
+                       dfree_retval : dfreeq_retval ;
+      /* maybe dfree and dfreeq are calculated using different bsizes 
+         so convert dfree from bsize into bsizeq */
+      *dfree = ((*dfree) * (*bsize)) / (bsizeq);
+      *dfree = ( *dfree < dfreeq ) ? *dfree : dfreeq ;
+      *bsize = bsizeq;
+      *dsize = dsizeq;
+    }
+#endif
+  return(dfree_retval);
 #endif
 }
 
@@ -742,7 +810,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);
@@ -2034,7 +2102,7 @@ static BOOL open_sockets(BOOL is_daemon,int port)
       /* ready to listen */
       if (listen(s, 5) == -1) 
        {
-         DEBUG(0,("listen: %s",strerror(errno)));
+         DEBUG(0,("listen: %s\n",strerror(errno)));
          close(s);
          return False;
        }
@@ -2054,7 +2122,7 @@ static BOOL open_sockets(BOOL is_daemon,int port)
 
          if (Client == -1)
            {
-             DEBUG(0,("accept: %s",strerror(errno)));
+             DEBUG(0,("accept: %s\n",strerror(errno)));
              continue;
            }
 
@@ -4123,7 +4191,7 @@ static void usage(char *pname)
   reopen_logs();
 
   DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION));
-  DEBUG(2,("Copyright Andrew Tridgell 1992-1995\n"));
+  DEBUG(2,("Copyright Andrew Tridgell 1992-1997\n"));
 
 #ifndef NO_GETRLIMIT
 #ifdef RLIMIT_NOFILE