diff options
-rw-r--r-- | source3/include/proto.h | 7 | ||||
-rw-r--r-- | source3/lib/system.c | 9 | ||||
-rw-r--r-- | source3/lib/time.c | 21 | ||||
-rw-r--r-- | source3/locking/locking_shm.c | 2 | ||||
-rw-r--r-- | source3/namepacket.c | 4 | ||||
-rw-r--r-- | source3/param/loadparm.c | 12 | ||||
-rw-r--r-- | source3/smbd/reply.c | 8 | ||||
-rw-r--r-- | source3/smbd/server.c | 72 | ||||
-rw-r--r-- | source3/smbd/trans2.c | 2 |
9 files changed, 95 insertions, 42 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index 97212ff74d..8e81954313 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -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 */ diff --git a/source3/lib/system.c b/source3/lib/system.c index fe8e8004d0..1486600339 100644 --- a/source3/lib/system.c +++ b/source3/lib/system.c @@ -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)); } diff --git a/source3/lib/time.c b/source3/lib/time.c index 4f688d2214..ad6b04484c 100644 --- a/source3/lib/time.c +++ b/source3/lib/time.c @@ -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); @@ -446,25 +446,6 @@ time_t make_unix_date3(void *date_ptr) } /**************************************************************************** -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,×)) { - DEBUG(4,("set_filetime(%s) failed: %s\n",fname,strerror(errno))); - } - - return(True); -} - - -/**************************************************************************** return the date and time as a string ****************************************************************************/ char *timestring(void ) diff --git a/source3/locking/locking_shm.c b/source3/locking/locking_shm.c index 99d981ed20..47074cff6b 100644 --- a/source3/locking/locking_shm.c +++ b/source3/locking/locking_shm.c @@ -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 *)) { diff --git a/source3/namepacket.c b/source3/namepacket.c index ba1c4044a3..3a23806a9c 100644 --- a/source3/namepacket.c +++ b/source3/namepacket.c @@ -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", diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 32fc538886..d0dfe4ace7 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -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) diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 7576ee323b..424c7d8183 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -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", diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 7d9638f01e..7639c5940b 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -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, ×)) { + 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. diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index e484b3b2e1..6a7fc292fa 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -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)); } |