loadparm.c: Changed 'interfaces only' parameter to 'bind interfaces only'. Added
authorJeremy Allison <jra@samba.org>
Mon, 20 Oct 1997 18:52:04 +0000 (18:52 +0000)
committerJeremy Allison <jra@samba.org>
Mon, 20 Oct 1997 18:52:04 +0000 (18:52 +0000)
            'dos filetimes' parameter for UTIME fix.
locking_shm.c: Fixed typo (sorry Andrew :-).
namepacket.c: Changed lp_interfaces_only() to lp_bind_interfaces_only().
proto.h: The usual.
reply.c: Made filetime calls use new file_utime call (wrapper for sys_utime).
server.c: Made filetime calls use new file_utime call (wrapper for sys_utime).
system.c: Added Andrew's sanity checks to times in sys_utime().
time.c: Moved set_filetime() to server.c. Made null_mtime() global.
trans2.c: Made filetime calls use new file_utime call (wrapper for sys_utime).
Jeremy (jallison@whistle.com)

source/include/proto.h
source/lib/system.c
source/lib/time.c
source/locking/locking_shm.c
source/namepacket.c
source/param/loadparm.c
source/smbd/reply.c
source/smbd/server.c
source/smbd/trans2.c

index 97212ff74dac30a5e672a0e2a7f07dab9b86de5b..8e819543130a858ef1f6540cb17e04340c69225b 100644 (file)
@@ -188,7 +188,7 @@ BOOL lp_browse_list(void);
 BOOL lp_unix_realname(void);
 BOOL lp_nis_home_map(void);
 BOOL lp_time_server(void);
-BOOL lp_interfaces_only(void);
+BOOL lp_bind_interfaces_only(void);
 int lp_os_level(void);
 int lp_max_ttl(void);
 int lp_max_log_size(void);
@@ -273,6 +273,7 @@ BOOL lp_map_system(int );
 BOOL lp_delete_readonly(int );
 BOOL lp_fake_oplocks(int );
 BOOL lp_recursive_veto_delete(int );
+BOOL lp_dos_filetimes(int );
 int lp_create_mode(int );
 int lp_force_create_mode(int );
 int lp_dir_mode(int );
@@ -777,6 +778,8 @@ void  killkids(void);
 mode_t unix_mode(int cnum,int dosmode);
 int dos_mode(int cnum,char *path,struct stat *sbuf);
 int dos_chmod(int cnum,char *fname,int dosmode,struct stat *st);
+int file_utime(int cnum, char *fname, struct utimbuf *times);
+BOOL set_filetime(int cnum, char *fname, time_t mtime);
 BOOL unix_convert(char *name,int cnum,pstring saved_last_component, BOOL *bad_path);
 int disk_free(char *path,int *bsize,int *dfree,int *dsize);
 int sys_disk_free(char *path,int *bsize,int *dfree,int *dsize);
@@ -944,13 +947,13 @@ int TimeDiff(time_t t);
 struct tm *LocalTime(time_t *t);
 time_t interpret_long_date(char *p);
 void put_long_date(char *p,time_t t);
+BOOL null_mtime(time_t mtime);
 void put_dos_date(char *buf,int offset,time_t unixdate);
 void put_dos_date2(char *buf,int offset,time_t unixdate);
 void put_dos_date3(char *buf,int offset,time_t unixdate);
 time_t make_unix_date(void *date_ptr);
 time_t make_unix_date2(void *date_ptr);
 time_t make_unix_date3(void *date_ptr);
-BOOL set_filetime(char *fname,time_t mtime);
 char *timestring(void );
 
 /*The following definitions come from  trans2.c  */
index fe8e8004d045197ec9d8468820d4dd7a83a2ad7f..1486600339aec32b1e2f19357dcff30e86678a43 100644 (file)
@@ -194,6 +194,15 @@ now for utime()
 ********************************************************************/
 int sys_utime(char *fname,struct utimbuf *times)
 {
+  /* if the modtime is 0 or -1 then ignore the call and
+     return success */
+  if (times->modtime == (time_t)0 || times->modtime == (time_t)-1)
+    return 0;
+  
+  /* if the access time is 0 or -1 then set it to the modtime */
+  if (times->actime == (time_t)0 || times->actime == (time_t)-1)
+    times->actime = times->modtime;
+   
   return(utime(dos_to_unix(fname,False),times));
 }
 
index 4f688d2214a5602a01662f09e613082022195e65..ad6b04484c59254fc66879e2516c9d29b21ca281 100644 (file)
@@ -298,7 +298,7 @@ void put_long_date(char *p,time_t t)
 /****************************************************************************
 check if it's a null mtime
 ****************************************************************************/
-static BOOL null_mtime(time_t mtime)
+BOOL null_mtime(time_t mtime)
 {
   if (mtime == 0 || mtime == 0xFFFFFFFF || mtime == (time_t)-1)
     return(True);
@@ -445,25 +445,6 @@ time_t make_unix_date3(void *date_ptr)
   return(t);
 }
 
-/****************************************************************************
-set the time on a file
-****************************************************************************/
-BOOL set_filetime(char *fname,time_t mtime)
-{  
-  struct utimbuf times;
-
-  if (null_mtime(mtime)) return(True);
-
-  times.modtime = times.actime = mtime;
-
-  if (sys_utime(fname,&times)) {
-    DEBUG(4,("set_filetime(%s) failed: %s\n",fname,strerror(errno)));
-  }
-    
-  return(True);
-}
-
-
 /****************************************************************************
   return the date and time as a string
 ****************************************************************************/
index 99d981ed20016670e6331feac2a98f3d5253eeed..47074cff6bc8e9fbb1601722e0984bd354f0d4dd 100644 (file)
@@ -636,7 +636,7 @@ mode record found dev = %d, inode = %d in hash bucket %d\n", dev, inode, hash_en
 
 /*******************************************************************
 call the specified function on each entry under management by the
-share ode system
+share mode system
 ********************************************************************/
 static int shm_share_forall(void (*fn)(share_mode_entry *, char *))
 {
index ba1c4044a3b2295485e22c1d7754141630046060..3a23806a9c4cb808f5edcf2656e13e03a7489c81 100644 (file)
@@ -626,7 +626,7 @@ BOOL listen_for_packets(BOOL run_election)
              * If we got a packet on the broadcast socket and interfaces
              * only is set then check it came from one of our local nets. 
              */
-            if(lp_interfaces_only() && (sock_array[i] == ClientNMB) && 
+            if(lp_bind_interfaces_only() && (sock_array[i] == ClientNMB) && 
                (!is_local_net(packet->ip)))
             {
               DEBUG(7,("discarding nmb packet sent to broadcast socket from %s:%d\n",
@@ -660,7 +660,7 @@ BOOL listen_for_packets(BOOL run_election)
              * If we got a packet on the broadcast socket and interfaces
              * only is set then check it came from one of our local nets. 
              */
-            if(lp_interfaces_only() && (sock_array[i] == ClientDGRAM) && 
+            if(lp_bind_interfaces_only() && (sock_array[i] == ClientDGRAM) && 
                  (!is_local_net(packet->ip)))
             {
               DEBUG(7,("discarding dgram packet sent to broadcast socket from %s:%d\n",
index 32fc538886a1a866c80aee23ff4960b4b277f518..d0dfe4ace74e8aacf0d68217235b948730641940 100644 (file)
@@ -186,7 +186,7 @@ typedef struct
   BOOL bUnixRealname;
   BOOL bNISHomeMap;
   BOOL bTimeServer;
-  BOOL bInterfacesOnly;
+  BOOL bBindInterfacesOnly;
 } global;
 
 static global Globals;
@@ -273,6 +273,7 @@ typedef struct
   BOOL bDeleteReadonly;
   BOOL bFakeOplocks;
   BOOL bDeleteVetoFiles;
+  BOOL bDosFiletimes;
   char dummy[3]; /* for alignment */
 } service;
 
@@ -355,6 +356,7 @@ static service sDefault =
   False, /* bDeleteReadonly */
   False, /* bFakeOplocks */
   False, /* bDeleteVetoFiles */
+  False, /* bDosFiletimes */
   ""     /* dummy */
 };
 
@@ -414,7 +416,7 @@ struct parm_struct
   {"null passwords",   P_BOOL,    P_GLOBAL, &Globals.bNullPasswords,    NULL},
   {"strip dot",        P_BOOL,    P_GLOBAL, &Globals.bStripDot,         NULL},
   {"interfaces",       P_STRING,  P_GLOBAL, &Globals.szInterfaces,      NULL},
-  {"interfaces only",  P_BOOL,    P_GLOBAL, &Globals.bInterfacesOnly,   NULL},
+  {"bind interfaces only", P_BOOL,P_GLOBAL, &Globals.bBindInterfacesOnly,NULL},
   {"password server",  P_STRING,  P_GLOBAL, &Globals.szPasswordServer,  NULL},
   {"socket options",   P_GSTRING, P_GLOBAL, user_socket_options,        NULL},
   {"netbios name",     P_UGSTRING,P_GLOBAL, myname,                     NULL},
@@ -577,6 +579,7 @@ struct parm_struct
   {"magic output",     P_STRING,  P_LOCAL,  &sDefault.szMagicOutput,    NULL},
   {"mangled map",      P_STRING,  P_LOCAL,  &sDefault.szMangledMap,     NULL},
   {"delete readonly",  P_BOOL,    P_LOCAL,  &sDefault.bDeleteReadonly,  NULL},
+  {"dos filetimes",    P_BOOL,    P_LOCAL,  &sDefault.bDosFiletimes,    NULL},
 
   {NULL,               P_BOOL,    P_NONE,   NULL,                       NULL}
 };
@@ -669,7 +672,7 @@ static void init_globals(void)
   coding_system = interpret_coding_system (KANJI, SJIS_CODE);
   Globals.client_code_page = DEFAULT_CLIENT_CODE_PAGE;
   Globals.bTimeServer = False;
-  Globals.bInterfacesOnly = False;
+  Globals.bBindInterfacesOnly = False;
 
 /* these parameters are set to defaults that are more appropriate
    for the increasing samba install base:
@@ -885,7 +888,7 @@ FN_GLOBAL_BOOL(lp_browse_list,&Globals.bBrowseList)
 FN_GLOBAL_BOOL(lp_unix_realname,&Globals.bUnixRealname)
 FN_GLOBAL_BOOL(lp_nis_home_map,&Globals.bNISHomeMap)
 FN_GLOBAL_BOOL(lp_time_server,&Globals.bTimeServer)
-FN_GLOBAL_BOOL(lp_interfaces_only,&Globals.bInterfacesOnly)
+FN_GLOBAL_BOOL(lp_bind_interfaces_only,&Globals.bBindInterfacesOnly)
 
 FN_GLOBAL_INTEGER(lp_os_level,&Globals.os_level)
 FN_GLOBAL_INTEGER(lp_max_ttl,&Globals.max_ttl)
@@ -973,6 +976,7 @@ FN_LOCAL_BOOL(lp_map_system,bMap_system)
 FN_LOCAL_BOOL(lp_delete_readonly,bDeleteReadonly)
 FN_LOCAL_BOOL(lp_fake_oplocks,bFakeOplocks)
 FN_LOCAL_BOOL(lp_recursive_veto_delete,bDeleteVetoFiles)
+FN_LOCAL_BOOL(lp_dos_filetimes,bDosFiletimes)
 
 FN_LOCAL_INTEGER(lp_create_mode,iCreate_mask)
 FN_LOCAL_INTEGER(lp_force_create_mode,iCreate_force_mode)
index 7576ee323b0dadc1ad305cfba42d17728e444d31..424c7d818321a5c6c7212f1abe483434ccf20980 100644 (file)
@@ -789,7 +789,7 @@ int reply_setatr(char *inbuf,char *outbuf)
   if (check_name(fname,cnum))
     ok =  (dos_chmod(cnum,fname,mode,NULL) == 0);
   if (ok)
-    ok = set_filetime(fname,mtime);
+    ok = set_filetime(cnum,fname,mtime);
   
   if (!ok)
   {
@@ -2270,7 +2270,7 @@ int reply_close(char *inbuf,char *outbuf)
   mtime = make_unix_date3(inbuf+smb_vwv1);
 
   /* try and set the date */
-  set_filetime(Files[fnum].name,mtime);
+  set_filetime(cnum, Files[fnum].name,mtime);
 
   close_file(fnum,True);
 
@@ -2317,7 +2317,7 @@ int reply_writeclose(char *inbuf,char *outbuf)
       
   nwritten = write_file(fnum,data,numtowrite);
 
-  set_filetime(Files[fnum].name,mtime);
+  set_filetime(cnum, Files[fnum].name,mtime);
   
   close_file(fnum,True);
 
@@ -3787,7 +3787,7 @@ not setting timestamps of 0\n",
   }
 
   /* Set the date on this file */
-  if(sys_utime(Files[fnum].name, &unix_times))
+  if(file_utime(cnum, Files[fnum].name, &unix_times))
     return(ERROR(ERRDOS,ERRnoaccess));
   
   DEBUG(3,("%s reply_setattrE fnum=%d cnum=%d actime=%d modtime=%d\n",
index 7d9638f01e86267ecd8cb15d0c559792a1cf7db1..7639c5940be1f2542b96974213a6d590a85ab709 100644 (file)
@@ -254,7 +254,6 @@ int dos_mode(int cnum,char *path,struct stat *sbuf)
   return(result);
 }
 
-
 /*******************************************************************
 chmod a file - but preserve some bits
 ********************************************************************/
@@ -308,6 +307,70 @@ int dos_chmod(int cnum,char *fname,int dosmode,struct stat *st)
   return(sys_chmod(fname,unixmode));
 }
 
+/*******************************************************************
+Wrapper around sys_utime that possibly allows DOS semantics rather
+than POSIX.
+*******************************************************************/
+
+int file_utime(int cnum, char *fname, struct utimbuf *times)
+{
+  extern struct current_user current_user;
+  struct stat sb;
+  int ret = -1;
+
+  if(sys_utime(fname, times) == 0)
+    return 0;
+
+  if((errno != EPERM) || !lp_dos_filetimes(SNUM(cnum)))
+    return -1;
+
+  /* We have permission (given by the Samba admin) to
+     break POSIX semantics and allow a user to change
+     the time on a file they don't own but can write to
+     (as DOS does).
+   */
+
+  if(sys_stat(fname,&sb) != 0)
+    return -1;
+
+  /* Check if we have write access. */
+  if (CAN_WRITE(cnum) && !lp_alternate_permissions(SNUM(cnum))) 
+  {
+    if (((sb.st_mode & S_IWOTH) ||
+        Connections[cnum].admin_user ||
+        ((sb.st_mode & S_IWUSR) && current_user.uid==sb.st_uid) ||
+        ((sb.st_mode & S_IWGRP) &&
+        in_group(sb.st_gid,current_user.gid,
+             current_user.ngroups,current_user.igroups))))
+    {
+      /* We are allowed to become root and change the filetime. */
+      become_root(False);
+      ret = sys_utime(fname, times);
+      unbecome_root(False);
+    }
+  }
+
+  return ret;
+}
+  
+/*******************************************************************
+Change a filetime - possibly allowing DOS semantics.
+*******************************************************************/
+
+BOOL set_filetime(int cnum, char *fname, time_t mtime)
+{
+  struct utimbuf times;
+
+  if (null_mtime(mtime)) return(True);
+
+  times.modtime = times.actime = mtime;
+
+  if (file_utime(cnum, fname, &times)) {
+    DEBUG(4,("set_filetime(%s) failed: %s\n",fname,strerror(errno)));
+  }
+  
+  return(True);
+} 
 
 /****************************************************************************
 check if two filenames are equal
@@ -1099,13 +1162,6 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct
     DEBUG(3,("Bug in client? Set O_WRONLY without O_CREAT\n"));
 */
 
-#if UTIME_WORKAROUND
-  /* XXXX - is this OK?? */
-  /* this works around a utime bug but can cause other problems */
-  if ((flags & (O_WRONLY|O_RDWR)) && (flags & O_CREAT) && !(flags & O_APPEND))
-    sys_unlink(fname);
-#endif
-
   /*
    * Ensure we have a valid struct stat so we can search the
    * open fd table.
index e484b3b2e1a767eaa6a8cff4132c65a88b39b72c..6a7fc292fae023b1ce2a176c0dd1908d7d4fb2dd 100644 (file)
@@ -1433,7 +1433,7 @@ static int call_trans2setfilepathinfo(char *inbuf, char *outbuf, int length,
    */
   if (st.st_mtime != tvs.modtime || st.st_atime != tvs.actime)
   {
-    if(sys_utime(fname, &tvs)!=0)
+    if(file_utime(cnum, fname, &tvs)!=0)
     {
       return(ERROR(ERRDOS,ERRnoaccess));
     }