summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/include/proto.h7
-rw-r--r--source/lib/system.c9
-rw-r--r--source/lib/time.c21
-rw-r--r--source/locking/locking_shm.c2
-rw-r--r--source/namepacket.c4
-rw-r--r--source/param/loadparm.c12
-rw-r--r--source/smbd/reply.c8
-rw-r--r--source/smbd/server.c72
-rw-r--r--source/smbd/trans2.c2
9 files changed, 95 insertions, 42 deletions
diff --git a/source/include/proto.h b/source/include/proto.h
index 97212ff74da..8e819543130 100644
--- a/source/include/proto.h
+++ b/source/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/source/lib/system.c b/source/lib/system.c
index fe8e8004d04..1486600339a 100644
--- a/source/lib/system.c
+++ b/source/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/source/lib/time.c b/source/lib/time.c
index 4f688d2214a..ad6b04484c5 100644
--- a/source/lib/time.c
+++ b/source/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,&times)) {
- 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/source/locking/locking_shm.c b/source/locking/locking_shm.c
index 99d981ed200..47074cff6bc 100644
--- a/source/locking/locking_shm.c
+++ b/source/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/source/namepacket.c b/source/namepacket.c
index ba1c4044a3b..3a23806a9c4 100644
--- a/source/namepacket.c
+++ b/source/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/source/param/loadparm.c b/source/param/loadparm.c
index 32fc538886a..d0dfe4ace74 100644
--- a/source/param/loadparm.c
+++ b/source/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/source/smbd/reply.c b/source/smbd/reply.c
index 7576ee323b0..424c7d81832 100644
--- a/source/smbd/reply.c
+++ b/source/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/source/smbd/server.c b/source/smbd/server.c
index 7d9638f01e8..7639c5940be 100644
--- a/source/smbd/server.c
+++ b/source/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, &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.
diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c
index e484b3b2e1a..6a7fc292fae 100644
--- a/source/smbd/trans2.c
+++ b/source/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));
}