From 635b56f19c817527c52e9bbde31faa6a8a47777b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 31 May 1996 15:13:29 +0000 Subject: [PATCH] Lots of changes! - add faq info on NT printer handling - add "delete readonly" option to help rcs users - add stuff to man pages on new printer options - add "proxy name resolution" option - add "command string" -c option to smbclient (thanks Ken) - split time functions into time.c - rearrange the quotas stuff a bit and fix some bugs - complete rehash of the time handling code thanks to Paul Eggert - fix nmblookup output a bit - add plp print queue parsing from Bertrand Wallrich --- docs/manpages/smb.conf.5 | 38 ++- docs/manpages/smbclient.1 | 18 ++ docs/samba.faq | 31 +++ source/client/client.c | 63 ++++- source/client/clitar.c | 4 +- source/include/includes.h | 23 +- source/include/local.h | 6 - source/include/smb.h | 8 +- source/lib/time.c | 495 +++++++++++++++++++++++++++++++++++++ source/lib/util.c | 467 +--------------------------------- source/libsmb/nmblib.c | 16 +- source/loadparm.h | 2 + source/nameserv.c | 5 + source/param/loadparm.c | 11 + source/printing/printing.c | 81 +++++- source/smbd/ipc.c | 8 +- source/smbd/password.c | 6 +- source/smbd/quotas.c | 55 ++++- source/smbd/reply.c | 4 +- source/smbd/server.c | 2 + source/utils/smbpasswd.c | 2 + source/utils/status.c | 5 +- source/utils/testparm.c | 2 + source/utils/testprns.c | 2 + 24 files changed, 811 insertions(+), 543 deletions(-) create mode 100644 source/lib/time.c diff --git a/docs/manpages/smb.conf.5 b/docs/manpages/smb.conf.5 index 933d71ff0c3..f29e7b6b02d 100644 --- a/docs/manpages/smb.conf.5 +++ b/docs/manpages/smb.conf.5 @@ -459,6 +459,8 @@ comment default case +delete readonly + deny hosts directory @@ -831,6 +833,19 @@ things. path = /%S +.SS delete readonly (S) +This parameter allows readonly files to be deleted. This is not normal DOS +semantics, but is allowed by Unix. + +This option may be useful for running applications such as rcs, where unix +file ownership prevents changing file permissions, and dos semantics prevent +deletion of a read only file. + +.B Default: + delete readonly = No + +.B Example: + delete readonly = Yes .SS deny hosts (S) A synonym for this parameter is 'hosts deny'. @@ -1187,9 +1202,9 @@ order to obtain "lpq"-style printer status information. This command should be a program or script which takes a printer name as its only parameter and outputs printer status information. -Currently four styles of printer status information are supported; -BSD, SYSV, AIX and HPUX. This covers most unix systems. You control -which type is expected using the "printing =" option. +Currently six styles of printer status information are supported; BSD, +SYSV, AIX, HPUX, QNX and PLP. This covers most unix systems. You +control which type is expected using the "printing =" option. Some clients (notably Windows for Workgroups) may not correctly send the connection number for the printer they are requesting status information @@ -1235,8 +1250,8 @@ order to delete a print job. This command should be a program or script which takes a printer name and job number, and deletes the print job. -Currently four styles of printer control are supported; BSD, SYSV, AIX -and HPUX. This covers most unix systems. You control which type is +Currently six styles of printer control are supported; BSD, SYSV, AIX +HPUX, QNX and PLP. This covers most unix systems. You control which type is expected using the "printing =" option. If a %p is given then the printername is put in it's place. A %j is @@ -1881,8 +1896,9 @@ This parameters controls how printer status information is interpreted on your system, and also affects the default values for the "print command", "lpq command" and "lprm command". -Currently three printing styles are supported. They are "printing = -bsd", "printing = sysv", "printing = hpux" and "printing = aix". +Currently six printing styles are supported. They are "printing = +bsd", "printing = sysv", "printing = hpux", "printing = aix", +"printing = qnx" and "printing = plp". To see what the defaults are for the other print commands when using these three options use the "testparm" program. @@ -1946,6 +1962,14 @@ merits of each are discussed in the README file. .B Example: protocol = LANMAN1 +.SS proxy name resolution (G) + +This is a boolean that controls if nmbd will respond to broadcast name +queries on behalf of other hosts. You may need to set this to no for +some older clients. + +.B Default: + proxy name resolution = yes .SS public (S) A synonym for this parameter is 'guest ok'. diff --git a/docs/manpages/smbclient.1 b/docs/manpages/smbclient.1 index be3a953266f..e0af67ca1a4 100644 --- a/docs/manpages/smbclient.1 +++ b/docs/manpages/smbclient.1 @@ -44,8 +44,13 @@ smbclient \- ftp-like Lan Manager client program ] [ .B -p .I port number +] [ +.B -c +.I command string +] [ .B -T .I tar options +] [ .B -D .I initial directory ] @@ -438,6 +443,19 @@ Change to initial directory before starting. Probably only of any use with the tar (\-T) option. +.RE + +.B -c +.I command string + +.RS 3 + +command string is a semicolon separated list of commands to be +executed instead of prompting from stdin. -N is implied by -c. + +This is particularly useful in scripts and for printing stdin to +the server, e.g. -c 'print -'. + .RE .SH OPERATIONS diff --git a/docs/samba.faq b/docs/samba.faq index 6e3cf2943aa..86dd48877f8 100644 --- a/docs/samba.faq +++ b/docs/samba.faq @@ -548,6 +548,37 @@ properly. Samba needs to be able to switch uids on the connection and it can't if your OS has a trapdoor uid system. You'll know this because Samba will note it in your logs. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +* 5: Problem with printers under NT + +This info from Stefan Hergeth may be useful: + + A network-printer (with ethernetcard) is connected to the NT-Clients via + our UNIX-Fileserver (SAMBA-Server), like the configuration told by + Matthew Harrell (see WinNT.txt) + + 1.) If a user has choosen this printer as the default printer in his + NT-Session and this printer is not connected to the network + (e.g. switched off) than this user has a problem with the SAMBA- + connection of his filesystems. It's very slow. + + 2.) If the printer is connected to the network everything works fine. + + 3.) When the smbd ist started with debug level 3, you can see that the + NT spooling system try to connect to the printer many times. If the + printer ist not connected to the network this request fails and the + NT spooler is wasting a lot of time to connect to the printer service. + This seems to be the reason for the slow network connection. + + 4.) Maybe it's possible to change this behaviour by setting different printer + properties in the Print-Manager-Menu of NT, but i didn't try it + yet. + + I hope this information will help in some way. + + Stefan Hergeth + + =============================================================================== SECTION FIVE: Specific client application problems ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/source/client/client.c b/source/client/client.c index 5542e2f479d..a40d377955c 100644 --- a/source/client/client.c +++ b/source/client/client.c @@ -38,6 +38,7 @@ pstring myname = ""; pstring password = ""; pstring username=""; pstring workgroup=WORKGROUP; +char *cmdstr=""; BOOL got_pass = False; BOOL connect_as_printer = False; BOOL connect_as_ipc = False; @@ -482,7 +483,7 @@ static void display_finfo(file_info *finfo) CNV_LANG(finfo->name), attrib_string(finfo->mode), finfo->size, - asctime(LocalTime(&t,GMT_TO_LOCAL)))); + asctime(LocalTime(&t)))); } /**************************************************************************** @@ -2669,7 +2670,7 @@ static void cmd_newer(void) { newer_than = sbuf.st_mtime; DEBUG(1,("Getting files newer than %s", - asctime(LocalTime(&newer_than,GMT_TO_LOCAL)))); + asctime(LocalTime(&newer_than)))); } else newer_than = 0; @@ -3031,7 +3032,7 @@ static BOOL send_login(char *inbuf,char *outbuf,BOOL start_session,BOOL use_setu static BOOL done_time = False; if (!done_time) { DEBUG(1,("Server time is %sTimezone is UTC%+02.1f\n", - asctime(LocalTime(&servertime,GMT_TO_LOCAL)), + asctime(LocalTime(&servertime)), -(double)(serverzone/3600.0))); done_time = True; } @@ -4002,6 +4003,7 @@ BOOL process(char *base_directory) { extern FILE *dbf; pstring line; + char *cmd; char *InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN); char *OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN); @@ -4016,7 +4018,44 @@ BOOL process(char *base_directory) if (*base_directory) do_cd(base_directory); - while (!feof(stdin)) + cmd = cmdstr; + if (cmd[0] != '\0') while (cmd[0] != '\0') + { + char *p; + fstring tok; + int i; + + if ((p = strchr(cmd, ';')) == 0) + { + strncpy(line, cmd, 999); + line[1000] = '\0'; + cmd += strlen(cmd); + } + else + { + if (p - cmd > 999) p = cmd + 999; + strncpy(line, cmd, p - cmd); + line[p - cmd] = '\0'; + cmd = p + 1; + } + + /* input language code to internal one */ + CNV_INPUT (line); + + /* and get the first part of the command */ + { + char *ptr = line; + if (!next_token(&ptr,tok,NULL)) continue; + } + + if ((i = process_tok(tok)) >= 0) + commands[i].fn(InBuffer,OutBuffer); + else if (i == -2) + DEBUG(0,("%s: command abbreviation ambiguous\n",CNV_LANG(tok))); + else + DEBUG(0,("%s: command not found\n",CNV_LANG(tok))); + } + else while (!feof(stdin)) { fstring tok; int i; @@ -4099,6 +4138,7 @@ void usage(char *pname) DEBUG(0,("\t-E write messages to stderr instead of stdout\n")); DEBUG(0,("\t-U username set the network username\n")); DEBUG(0,("\t-W workgroup set the workgroup name\n")); + DEBUG(0,("\t-c command string execute semicolon separated commands\n")); #ifdef KANJI DEBUG(0,("\t-t terminal code terminal i/o code {sjis|euc|jis7|jis8|junet|hex}\n")); #endif /* KANJI */ @@ -4195,10 +4235,9 @@ int main(int argc,char *argv[]) #ifdef KANJI setup_term_code (KANJI); - while ((opt = getopt (argc, argv, "B:O:M:i:Nn:d:Pp:l:hI:EB:U:L:t:m:W:T:D:")) != EOF) -#else - while ((opt = getopt (argc, argv, "B:O:M:i:Nn:d:Pp:l:hI:EB:U:L:m:W:T:D:")) != EOF) -#endif /* KANJI */ +#endif + while ((opt = + getopt(argc, argv,"B:O:M:i:Nn:d:Pp:l:hI:EB:U:L:t:m:W:T:D:c:")) != EOF) switch (opt) { case 'm': @@ -4281,19 +4320,23 @@ int main(int argc,char *argv[]) case 'p': port = atoi(optarg); break; + case 'c': + cmdstr = optarg; + got_pass = True; + break; case 'h': usage(pname); exit(0); break; -#ifdef KANJI case 't': +#ifdef KANJI if (!setup_term_code (optarg)) { DEBUG(0, ("%s: unknown terminal code name\n", optarg)); usage (pname); exit (1); } +#endif break; -#endif /* KANJI */ default: usage(pname); exit(1); diff --git a/source/client/clitar.c b/source/client/clitar.c index 1433ec59412..0701aac1cf4 100644 --- a/source/client/clitar.c +++ b/source/client/clitar.c @@ -591,7 +591,7 @@ static BOOL smbshut(file_info finfo, int fnum, char *inbuf, char *outbuf) put_dos_date3(outbuf,smb_vwv1,finfo.mtime); DEBUG(3,("Setting date to %s (0x%X)", - asctime(LocalTime(&finfo.mtime,GMT_TO_LOCAL)), + asctime(LocalTime(&finfo.mtime)), finfo.mtime)); send_smb(Client,outbuf); @@ -1655,7 +1655,7 @@ int tar_parseargs(int argc, char *argv[], char *Optarg, int Optind) if (sys_stat(argv[Optind], &stbuf) == 0) { newer_than = stbuf.st_mtime; DEBUG(1,("Getting files newer than %s", - asctime(LocalTime(&newer_than,GMT_TO_LOCAL)))); + asctime(LocalTime(&newer_than)))); Optind++; } else { DEBUG(0,("Error setting newer-than time\n")); diff --git a/source/include/includes.h b/source/include/includes.h index 2408b3c1949..dc1fe57e71a 100644 --- a/source/include/includes.h +++ b/source/include/includes.h @@ -198,27 +198,6 @@ #include #endif -/* this might be different on different systems */ -#ifdef QUOTAS -#ifdef LINUX -#ifdef __KERNEL__ -#undef __KERNEL__ -#include -#define __KERNEL__ -#else -#include -#endif -#include -#else -#include -#ifndef CRAY -#include -#else -#include -#endif -#endif -#endif - #ifdef SYSLOG #include #endif @@ -499,6 +478,8 @@ char *mktemp(char *); /* No standard include */ #define USE_WAITPID #define SIGNAL_CAST (void (*)()) #define DEFAULT_PRINTING PRINT_AIX +/* we undef this because sys/param.h is broken in aix. uggh. */ +#undef MAXHOSTNAMELEN #endif diff --git a/source/include/local.h b/source/include/local.h index fba79559021..9572243e730 100644 --- a/source/include/local.h +++ b/source/include/local.h @@ -83,12 +83,6 @@ manager window? */ #define FSTYPE_STRING "Samba" -/* we have two time standards - local and GMT. This will try to sort them out. - */ - -#define LOCAL_TO_GMT 1 -#define GMT_TO_LOCAL (-1) - /* do you want smbd to send a 1 byte packet to nmbd to trigger it to start when smbd starts? */ #ifndef PRIME_NMBD diff --git a/source/include/smb.h b/source/include/smb.h index b7faffa9e92..4d99529ef65 100644 --- a/source/include/smb.h +++ b/source/include/smb.h @@ -624,7 +624,6 @@ int smb_numwords(char *buf); int get_share_mode(int cnum,struct stat *sbuf,int *pid); void del_share_mode(int fnum); BOOL set_share_mode(int fnum,int mode); -int DSTDiff(time_t t); void TimeInit(void); void put_long_date(char *p,time_t t); time_t interpret_long_date(char *p); @@ -822,14 +821,12 @@ int chain_reply(int type,char *inbuf,char *inbuf2,char *outbuf,char *outbuf2,int void close_cnum(int cnum,int uid); char *smb_errstr(char *inbuf); void GetTimeOfDay(struct timeval *tval); -struct tm *LocalTime(time_t *t,int); +struct tm *LocalTime(time_t *t); int TimeDiff(time_t t); BOOL set_filetime(char *fname,time_t mtime); char *dirname_dos(char *path,char *buf); BOOL get_myname(char *myname,struct in_addr *ip); void expand_mask(char *Mask, BOOL); -BOOL sane_unix_date(time_t unixdate); -time_t start_of_month(void); char *smb_fn_name(int cnum); void get_machine_info(void); int open_socket_in(int type, int port, int dlevel); @@ -966,7 +963,8 @@ enum protocol_types {PROTOCOL_NONE,PROTOCOL_CORE,PROTOCOL_COREPLUS,PROTOCOL_LANM enum security_types {SEC_SHARE,SEC_USER,SEC_SERVER}; /* printing types */ -enum printing_types {PRINT_BSD,PRINT_SYSV,PRINT_AIX,PRINT_HPUX,PRINT_QNX}; +enum printing_types {PRINT_BSD,PRINT_SYSV,PRINT_AIX,PRINT_HPUX, + PRINT_QNX,PRINT_PLP}; /* case handling */ diff --git a/source/lib/time.c b/source/lib/time.c new file mode 100644 index 00000000000..0b6e6df9b07 --- /dev/null +++ b/source/lib/time.c @@ -0,0 +1,495 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + time handling functions + Copyright (C) Andrew Tridgell 1992-1995 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +/* + This stuff was largely rewritten by Paul Eggert + in May 1996 + */ + + +int serverzone=0; +int extra_time_offset = 0; + +extern int DEBUGLEVEL; + +#ifndef CHAR_BIT +#define CHAR_BIT 8 +#endif + +#ifndef TIME_T_MIN +#define TIME_T_MIN (0 < (time_t) -1 ? (time_t) 0 \ + : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1)) +#endif +#ifndef TIME_T_MAX +#define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN) +#endif + + + +/******************************************************************* +a gettimeofday wrapper +********************************************************************/ +void GetTimeOfDay(struct timeval *tval) +{ +#ifdef GETTIMEOFDAY1 + gettimeofday(tval); +#else + gettimeofday(tval,NULL); +#endif +} + +#define TM_YEAR_BASE 1900 + +/******************************************************************* +yield the difference between *A and *B, in seconds, ignoring leap seconds +********************************************************************/ +static int tm_diff(struct tm *a, struct tm *b) +{ + int ay = a->tm_year + (TM_YEAR_BASE - 1); + int by = b->tm_year + (TM_YEAR_BASE - 1); + int intervening_leap_days = + (ay/4 - by/4) - (ay/100 - by/100) + (ay/400 - by/400); + int years = ay - by; + int days = 365*years + intervening_leap_days + (a->tm_yday - b->tm_yday); + int hours = 24*days + (a->tm_hour - b->tm_hour); + int minutes = 60*hours + (a->tm_min - b->tm_min); + int seconds = 60*minutes + (a->tm_sec - b->tm_sec); + return seconds; +} + +/******************************************************************* + return the UTC offset in seconds west of UTC + ******************************************************************/ +static int TimeZone(time_t t) +{ + struct tm tm_utc = *(gmtime(&t)); + return tm_diff(&tm_utc,localtime(&t)); +} + + +/******************************************************************* +init the time differences +********************************************************************/ +void TimeInit(void) +{ + serverzone = TimeZone(time(NULL)); + DEBUG(4,("Serverzone is %d\n",serverzone)); +} + + +/******************************************************************* +return the same value as TimeZone, but it should be more efficient. + +We keep a table of DST offsets to prevent calling localtime() on each +call of this function. This saves a LOT of time on many unixes. + +Updated by Paul Eggert +********************************************************************/ +static int TimeZoneFaster(time_t t) +{ + static struct dst_table {time_t start,end; int zone;} *dst_table = NULL; + static int table_size = 0; + int i; + int zone = 0; + + if (t == 0) t = time(NULL); + + /* Tunis has a 8 day DST region, we need to be careful ... */ +#define MAX_DST_WIDTH (365*24*60*60) +#define MAX_DST_SKIP (7*24*60*60) + + for (i=0;i= dst_table[i].start && t <= dst_table[i].end) break; + + if (i MAX_DST_SKIP*2) + t = dst_table[i].start - MAX_DST_SKIP; + else + t = low + (dst_table[i].start-low)/2; + if (TimeZone(t) == zone) + dst_table[i].start = t; + else + low = t; + } + + high = low + MAX_DST_WIDTH/2; + if (high < t) + high = TIME_T_MAX; + + while (high-60*60 > dst_table[i].end) { + if (high - dst_table[i].end > MAX_DST_SKIP*2) + t = dst_table[i].end + MAX_DST_SKIP; + else + t = high - (high-dst_table[i].end)/2; + if (TimeZone(t) == zone) + dst_table[i].end = t; + else + high = t; + } +#if 0 + DEBUG(1,("Added DST entry from %s ", + asctime(localtime(&dst_table[i].start)))); + DEBUG(1,("to %s (%d)\n",asctime(localtime(&dst_table[i].end)), + dst_table[i].zone)); +#endif + } + } + return zone; +} + +/**************************************************************************** + return the UTC offset in seconds west of UTC, adjusted for extra time offset + **************************************************************************/ +int TimeDiff(time_t t) +{ + return TimeZoneFaster(t) + 60*extra_time_offset; +} + + +/**************************************************************************** + return the UTC offset in seconds west of UTC, adjusted for extra time + offset, for a local time value. If ut = lt + LocTimeDiff(lt), then + lt = ut - TimeDiff(ut), but the converse does not necessarily hold near + daylight savings transitions because some local times are ambiguous. + LocTimeDiff(t) equals TimeDiff(t) except near daylight savings transitions. + +**************************************************************************/ +static int LocTimeDiff(time_t lte) +{ + time_t lt = lte - 60*extra_time_offset; + int d = TimeZoneFaster(lt); + time_t t = lt + d; + + /* if overflow occurred, ignore all the adjustments so far */ + if (((lte < lt) ^ (extra_time_offset < 0)) | ((t < lt) ^ (d < 0))) + t = lte; + + /* now t should be close enough to the true UTC to yield the right answer */ + return TimeDiff(t); +} + + +/**************************************************************************** +try to optimise the localtime call, it can be quite expenive on some machines +****************************************************************************/ +struct tm *LocalTime(time_t *t) +{ + time_t t2 = *t; + + t2 -= TimeDiff(t2); + + return(gmtime(&t2)); +} + + +#define TIME_FIXUP_CONSTANT (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60)) + +/**************************************************************************** +interpret an 8 byte "filetime" structure to a time_t +It's originally in "100ns units since jan 1st 1601" + +It appears to be kludge-GMT (at least for file listings). This means +its the GMT you get by taking a localtime and adding the +serverzone. This is NOT the same as GMT in some cases. This routine +converts this to real GMT. +****************************************************************************/ +time_t interpret_long_date(char *p) +{ + double d; + time_t ret; + uint32 tlow,thigh; + tlow = IVAL(p,0); + thigh = IVAL(p,4); + + if (thigh == 0) return(0); + + d = ((double)thigh)*4.0*(double)(1<<30); + d += (tlow&0xFFF00000); + d *= 1.0e-7; + + /* now adjust by 369 years to make the secs since 1970 */ + d -= TIME_FIXUP_CONSTANT; + + if (!(TIME_T_MIN <= d && d <= TIME_T_MAX)) + return(0); + + ret = (time_t)(d+0.5); + + /* this takes us from kludge-GMT to real GMT */ + ret -= serverzone; + ret += LocTimeDiff(ret); + + return(ret); +} + + +/**************************************************************************** +put a 8 byte filetime from a time_t +This takes real GMT as input and converts to kludge-GMT +****************************************************************************/ +void put_long_date(char *p,time_t t) +{ + uint32 tlow,thigh; + double d; + + if (t==0) { + SIVAL(p,0,0); SIVAL(p,4,0); + return; + } + + /* this converts GMT to kludge-GMT */ + t -= TimeDiff(t) - serverzone; + + d = (double) (t); + + d += TIME_FIXUP_CONSTANT; + + d *= 1.0e7; + + thigh = (uint32)(d * (1.0/(4.0*(double)(1<<30)))); + tlow = (uint32)(d - ((double)thigh)*4.0*(double)(1<<30)); + + SIVAL(p,0,tlow); + SIVAL(p,4,thigh); +} + + +/**************************************************************************** +check if it's a null mtime +****************************************************************************/ +static BOOL null_mtime(time_t mtime) +{ + if (mtime == 0 || mtime == 0xFFFFFFFF || mtime == (time_t)-1) + return(True); + return(False); +} + +/******************************************************************* + create a 16 bit dos packed date +********************************************************************/ +static uint16 make_dos_date1(time_t unixdate,struct tm *t) +{ + uint16 ret=0; + ret = (((unsigned)(t->tm_mon+1)) >> 3) | ((t->tm_year-80) << 1); + ret = ((ret&0xFF)<<8) | (t->tm_mday | (((t->tm_mon+1) & 0x7) << 5)); + return(ret); +} + +/******************************************************************* + create a 16 bit dos packed time +********************************************************************/ +static uint16 make_dos_time1(time_t unixdate,struct tm *t) +{ + uint16 ret=0; + ret = ((((unsigned)t->tm_min >> 3)&0x7) | (((unsigned)t->tm_hour) << 3)); + ret = ((ret&0xFF)<<8) | ((t->tm_sec/2) | ((t->tm_min & 0x7) << 5)); + return(ret); +} + +/******************************************************************* + create a 32 bit dos packed date/time from some parameters + This takes a GMT time and returns a packed localtime structure +********************************************************************/ +static uint32 make_dos_date(time_t unixdate) +{ + struct tm *t; + uint32 ret=0; + + t = LocalTime(&unixdate); + + ret = make_dos_date1(unixdate,t); + ret = ((ret&0xFFFF)<<16) | make_dos_time1(unixdate,t); + + return(ret); +} + +/******************************************************************* +put a dos date into a buffer (time/date format) +This takes GMT time and puts local time in the buffer +********************************************************************/ +void put_dos_date(char *buf,int offset,time_t unixdate) +{ + uint32 x = make_dos_date(unixdate); + SIVAL(buf,offset,x); +} + +/******************************************************************* +put a dos date into a buffer (date/time format) +This takes GMT time and puts local time in the buffer +********************************************************************/ +void put_dos_date2(char *buf,int offset,time_t unixdate) +{ + uint32 x = make_dos_date(unixdate); + x = ((x&0xFFFF)<<16) | ((x&0xFFFF0000)>>16); + SIVAL(buf,offset,x); +} + +/******************************************************************* +put a dos 32 bit "unix like" date into a buffer. This routine takes +GMT and converts it to LOCAL time before putting it (most SMBs assume +localtime for this sort of date) +********************************************************************/ +void put_dos_date3(char *buf,int offset,time_t unixdate) +{ + if (!null_mtime(unixdate)) + unixdate -= TimeDiff(unixdate); + SIVAL(buf,offset,unixdate); +} + +/******************************************************************* + interpret a 32 bit dos packed date/time to some parameters +********************************************************************/ +static void interpret_dos_date(uint32 date,int *year,int *month,int *day,int *hour,int *minute,int *second) +{ + uint32 p0,p1,p2,p3; + + p0=date&0xFF; p1=((date&0xFF00)>>8)&0xFF; + p2=((date&0xFF0000)>>16)&0xFF; p3=((date&0xFF000000)>>24)&0xFF; + + *second = 2*(p0 & 0x1F); + *minute = ((p0>>5)&0xFF) + ((p1&0x7)<<3); + *hour = (p1>>3)&0xFF; + *day = (p2&0x1F); + *month = ((p2>>5)&0xFF) + ((p3&0x1)<<3) - 1; + *year = ((p3>>1)&0xFF) + 80; +} + +/******************************************************************* + create a unix date (int GMT) from a dos date (which is actually in + localtime) +********************************************************************/ +time_t make_unix_date(void *date_ptr) +{ + uint32 dos_date=0; + struct tm t; + time_t ret; + + dos_date = IVAL(date_ptr,0); + + if (dos_date == 0) return(0); + + interpret_dos_date(dos_date,&t.tm_year,&t.tm_mon, + &t.tm_mday,&t.tm_hour,&t.tm_min,&t.tm_sec); + t.tm_isdst = -1; + + /* mktime() also does the local to GMT time conversion for us */ + ret = mktime(&t); + + return(ret); +} + +/******************************************************************* +like make_unix_date() but the words are reversed +********************************************************************/ +time_t make_unix_date2(void *date_ptr) +{ + uint32 x,x2; + + x = IVAL(date_ptr,0); + x2 = ((x&0xFFFF)<<16) | ((x&0xFFFF0000)>>16); + SIVAL(&x,0,x2); + + return(make_unix_date((void *)&x)); +} + +/******************************************************************* + create a unix GMT date from a dos date in 32 bit "unix like" format + these generally arrive as localtimes, with corresponding DST + ******************************************************************/ +time_t make_unix_date3(void *date_ptr) +{ + time_t t = IVAL(date_ptr,0); + if (!null_mtime(t)) + t += LocTimeDiff(t); + 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,×)) { + DEBUG(4,("set_filetime(%s) failed: %s\n",fname,strerror(errno))); + } + + return(True); +} + + +/**************************************************************************** + return the date and time as a string +****************************************************************************/ +char *timestring(void ) +{ + static char TimeBuf[100]; + time_t t = time(NULL); + struct tm *tm = LocalTime(&t); + +#ifdef NO_STRFTIME + strcpy(TimeBuf, asctime(tm)); +#elif defined(CLIX) || defined(CONVEX) + strftime(TimeBuf,100,"%m/%d/%y %I:%M:%S %p",tm); +#elif defined(AMPM) + strftime(TimeBuf,100,"%D %r",tm); +#elif defined(TZ_TIME) + { + int zone = TimeDiff(t); + int absZoneMinutes = (zone<0 ? -zone : zone) / 60; + size_t len = strftime(TimeBuf,sizeof(TimeBuf)-6,"%D %T",tm); + sprintf(TimeBuf+len," %c%02d%02d", + zone<0?'+':'-',absZoneMinutes/60,absZoneMinutes%60); + } +#else + strftime(TimeBuf,100,"%D %T",tm); +#endif + return(TimeBuf); +} + diff --git a/source/lib/util.c b/source/lib/util.c index e983a746731..2ac64d06487 100644 --- a/source/lib/util.c +++ b/source/lib/util.c @@ -30,8 +30,6 @@ BOOL passive = False; int Protocol = PROTOCOL_COREPLUS; -int serverzone=0; - /* a default finfo structure to ensure all fields are sensible */ file_info def_finfo = {-1,0,0,0,0,0,0,""}; @@ -407,141 +405,6 @@ void file_unlock(int fd) close(fd); } -/******************************************************************* -a gettimeofday wrapper -********************************************************************/ -void GetTimeOfDay(struct timeval *tval) -{ -#ifdef GETTIMEOFDAY1 - gettimeofday(tval); -#else - gettimeofday(tval,NULL); -#endif -} - -int extra_time_offset = 0; - -static int timediff = 0; - -/******************************************************************* -init the time differences -********************************************************************/ -void TimeInit(void) -{ - struct tm tm_utc,tm_local; - time_t t; - - t = time(NULL); - - tm_utc = *(gmtime(&t)); - tm_local = *(localtime(&t)); - -#ifdef HAVE_GMTOFF - timediff = -tm_local.tm_gmtoff; -#else - timediff = mktime(&tm_utc) - mktime(&tm_local); -#endif - - if (serverzone == 0) { - serverzone = timediff - DSTDiff(t); - DEBUG(4,("Serverzone is %d\n",serverzone)); - } -} - - -/******************************************************************* -return the DST offset for a particular time -We keep a table of DST offsets to prevent calling localtime() on each -call of this function. This saves a LOT of time on many unixes. -********************************************************************/ -int DSTDiff(time_t t) -{ - static struct dst_table {time_t start,end; BOOL is_dst;} *dst_table = NULL; - static int table_size = 0; - int i; - BOOL is_dst = False; - - if (t == 0) t = time(NULL); - -#ifndef NO_ISDST - for (i=0;i= dst_table[i].start && t <= dst_table[i].end) break; - - if (itm_isdst?True:False); - dst_table[i].start = dst_table[i].end = t; - - /* no entry will cover more than 6 months */ - low = t - 3*30*24*60*60; - - /* widen the new entry using two bisection searches */ - while (low+60*60 < dst_table[i].start) { - t = low + (dst_table[i].start-low)/2; - if ((localtime(&t)->tm_isdst?True:False) == is_dst) - dst_table[i].start = t; - else - low = t; - } - - high = low + 3*30*24*60*60; - while (high-60*60 > dst_table[i].end) { - t = high - (high-dst_table[i].end)/2; - if ((localtime(&t)->tm_isdst?True:False) == is_dst) - dst_table[i].end = t; - else - high = t; - } - -/* - DEBUG(1,("Added DST entry from %s ", - asctime(localtime(&dst_table[i].start)))); - DEBUG(1,("to %s (%d)\n",asctime(localtime(&dst_table[i].end)), - dst_table[i].is_dst)); -*/ - } -#endif - - return((is_dst?60*60:0) - (extra_time_offset*60)); -} - -/**************************************************************************** -return the difference between local and GMT time -****************************************************************************/ -int TimeDiff(time_t t) -{ - static BOOL initialised = False; - if (!initialised) {initialised=True; TimeInit();} - return(timediff - DSTDiff(t)); -} - -/**************************************************************************** -try to optimise the localtime call, it can be quite expenive on some machines -timemul is normally LOCAL_TO_GMT, GMT_TO_LOCAL or 0 -****************************************************************************/ -struct tm *LocalTime(time_t *t,int timemul) -{ - time_t t2 = *t; - - if (timemul) - t2 += timemul * TimeDiff(t2); - - return(gmtime(&t2)); -} - - /**************************************************************************** determine if a file descriptor is in fact a socket ****************************************************************************/ @@ -821,32 +684,6 @@ void close_sockets(void ) Client = 0; } -/**************************************************************************** - return the date and time as a string -****************************************************************************/ -char *timestring(void ) -{ - static char TimeBuf[100]; - time_t t; - t = time(NULL); -#ifdef NO_STRFTIME - strcpy(TimeBuf, asctime(LocalTime(&t,GMT_TO_LOCAL))); -#elif defined(CLIX) || defined(CONVEX) - strftime(TimeBuf,100,"%m/%d/%y %I:%M:%S %p",LocalTime(&t,GMT_TO_LOCAL)); -#elif defined(AMPM) - strftime(TimeBuf,100,"%D %r",LocalTime(&t,GMT_TO_LOCAL)); -#elif defined(TZ_TIME) - { - strftime(TimeBuf,100,"%D:%T",LocalTime(&t,0)); - sprintf(TimeBuf+strlen(TimeBuf)," %+03d%02d", - -TimeDiff(t)/(60*60),-(TimeDiff(t)/60)%60); - } -#else - strftime(TimeBuf,100,"%D %T",LocalTime(&t,GMT_TO_LOCAL)); -#endif - return(TimeBuf); -} - /**************************************************************************** determine whether we are in the specified group ****************************************************************************/ @@ -1050,159 +887,6 @@ uint32 file_size(char *file_name) return(buf.st_size); } -/**************************************************************************** -check if it's a null mtime -****************************************************************************/ -static BOOL null_mtime(time_t mtime) -{ - if (mtime == 0 || mtime == 0xFFFFFFFF) - return(True); - return(False); -} - -/******************************************************************* - create a 16 bit dos packed date -********************************************************************/ -static uint16 make_dos_date1(time_t unixdate,struct tm *t) -{ - uint16 ret=0; - ret = (((unsigned)(t->tm_mon+1)) >> 3) | ((t->tm_year-80) << 1); - ret = ((ret&0xFF)<<8) | (t->tm_mday | (((t->tm_mon+1) & 0x7) << 5)); - return(ret); -} - -/******************************************************************* - create a 16 bit dos packed time -********************************************************************/ -static uint16 make_dos_time1(time_t unixdate,struct tm *t) -{ - uint16 ret=0; - ret = ((((unsigned)t->tm_min >> 3)&0x7) | (((unsigned)t->tm_hour) << 3)); - ret = ((ret&0xFF)<<8) | ((t->tm_sec/2) | ((t->tm_min & 0x7) << 5)); - return(ret); -} - -/******************************************************************* - create a 32 bit dos packed date/time from some parameters - This takes a GMT time and returns a packed localtime structure -********************************************************************/ -static uint32 make_dos_date(time_t unixdate) -{ - struct tm *t; - uint32 ret=0; - - t = LocalTime(&unixdate,GMT_TO_LOCAL); - - ret = make_dos_date1(unixdate,t); - ret = ((ret&0xFFFF)<<16) | make_dos_time1(unixdate,t); - - return(ret); -} - -/******************************************************************* -put a dos date into a buffer (time/date format) -This takes GMT time and puts local time in the buffer -********************************************************************/ -void put_dos_date(char *buf,int offset,time_t unixdate) -{ - uint32 x = make_dos_date(unixdate); - SIVAL(buf,offset,x); -} - -/******************************************************************* -put a dos date into a buffer (date/time format) -This takes GMT time and puts local time in the buffer -********************************************************************/ -void put_dos_date2(char *buf,int offset,time_t unixdate) -{ - uint32 x = make_dos_date(unixdate); - x = ((x&0xFFFF)<<16) | ((x&0xFFFF0000)>>16); - SIVAL(buf,offset,x); -} - -/******************************************************************* -put a dos 32 bit "unix like" date into a buffer. This routine takes -GMT and converts it to LOCAL time before putting it (most SMBs assume -localtime for this sort of date) -********************************************************************/ -void put_dos_date3(char *buf,int offset,time_t unixdate) -{ - if (!null_mtime(unixdate)) - unixdate += GMT_TO_LOCAL*TimeDiff(unixdate); - SIVAL(buf,offset,unixdate); -} - -/******************************************************************* - interpret a 32 bit dos packed date/time to some parameters -********************************************************************/ -static void interpret_dos_date(uint32 date,int *year,int *month,int *day,int *hour,int *minute,int *second) -{ - uint32 p0,p1,p2,p3; - - p0=date&0xFF; p1=((date&0xFF00)>>8)&0xFF; - p2=((date&0xFF0000)>>16)&0xFF; p3=((date&0xFF000000)>>24)&0xFF; - - *second = 2*(p0 & 0x1F); - *minute = ((p0>>5)&0xFF) + ((p1&0x7)<<3); - *hour = (p1>>3)&0xFF; - *day = (p2&0x1F); - *month = ((p2>>5)&0xFF) + ((p3&0x1)<<3) - 1; - *year = ((p3>>1)&0xFF) + 80; -} - -/******************************************************************* - create a unix date (int GMT) from a dos date (which is actually in - localtime) -********************************************************************/ -time_t make_unix_date(void *date_ptr) -{ - uint32 dos_date=0; - struct tm t; - time_t ret; - - dos_date = IVAL(date_ptr,0); - - if (dos_date == 0) return(0); - - interpret_dos_date(dos_date,&t.tm_year,&t.tm_mon, - &t.tm_mday,&t.tm_hour,&t.tm_min,&t.tm_sec); - t.tm_wday = 1; - t.tm_yday = 1; - t.tm_isdst = -1; - - /* mktime() also does the local to GMT time conversion for us. XXXXX - Do all unixes do this the same?? */ - ret = mktime(&t); - - return(ret); -} - -/******************************************************************* -like make_unix_date() but the words are reversed -********************************************************************/ -time_t make_unix_date2(void *date_ptr) -{ - uint32 x,x2; - - x = IVAL(date_ptr,0); - x2 = ((x&0xFFFF)<<16) | ((x&0xFFFF0000)>>16); - SIVAL(&x,0,x2); - - return(make_unix_date((void *)&x)); -} - -/******************************************************************* - create a unix GMT date from a dos date in 32 bit "unix like" format -these generally arrive as localtimes, with corresponding DST -********************************************************************/ -time_t make_unix_date3(void *date_ptr) -{ - time_t t = IVAL(date_ptr,0); - if (!null_mtime(t)) - t += LOCAL_TO_GMT*TimeDiff(t); - return(t); -} - /******************************************************************* return a string representing an attribute for a file ********************************************************************/ @@ -3528,6 +3212,13 @@ expand a pointer to be a particular size void *Realloc(void *p,int size) { void *ret=NULL; + + if (size == 0) { + if (p) free(p); + DEBUG(5,("Realloc asked for 0 bytes\n")); + return NULL; + } + if (!p) ret = (void *)malloc(size); else @@ -3539,25 +3230,6 @@ void *Realloc(void *p,int size) return(ret); } -/**************************************************************************** -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); -} - - #ifdef NOSTRDUP /**************************************************************************** duplicate a string @@ -3598,57 +3270,6 @@ int Strlen(char *s) #endif -/**************************************************************************** -return a time at the start of the current month -****************************************************************************/ -time_t start_of_month(void) -{ - time_t t = time(NULL); - struct tm *t2; - - t2 = gmtime(&t); - - t2->tm_mday = 1; - t2->tm_hour = 0; - t2->tm_min = 0; - t2->tm_sec = 0; - - return(mktime(t2)); -} - - -/******************************************************************* - check for a sane unix date -********************************************************************/ -BOOL sane_unix_date(time_t unixdate) -{ - struct tm t,today; - time_t t_today = time(NULL); - - t = *(LocalTime(&unixdate,LOCAL_TO_GMT)); - today = *(LocalTime(&t_today,LOCAL_TO_GMT)); - - if (t.tm_year < 80) - return(False); - - if (t.tm_year > today.tm_year) - return(False); - - if (t.tm_year == today.tm_year && - t.tm_mon > today.tm_mon) - return(False); - - - if (t.tm_year == today.tm_year && - t.tm_mon == today.tm_mon && - t.tm_mday > (today.tm_mday+1)) - return(False); - - return(True); -} - - - #ifdef NO_FTRUNCATE /******************************************************************* ftruncate for operating systems that don't have it @@ -3730,11 +3351,7 @@ int open_socket_in(int type, int port, int dlevel) int res; /* get my host name */ -#ifdef MAXHOSTNAMELEN if (gethostname(host_name, MAXHOSTNAMELEN) == -1) -#else - if (gethostname(host_name, sizeof(host_name)) == -1) -#endif { DEBUG(0,("gethostname failed\n")); return -1; } /* get host info */ @@ -3909,76 +3526,6 @@ BOOL zero_ip(struct in_addr ip) return(a == 0); } -#define TIME_FIXUP_CONSTANT (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60)) - -/**************************************************************************** -interpret an 8 byte "filetime" structure to a time_t -It's originally in "100ns units since jan 1st 1601" - -It appears to be kludge-GMT (at least for file listings). This means -its the GMT you get by taking a localtime and adding the -serverzone. This is NOT the same as GMT in some cases. This routine -converts this to real GMT. -****************************************************************************/ -time_t interpret_long_date(char *p) -{ - double d; - time_t ret; - uint32 tlow,thigh; - tlow = IVAL(p,0); - thigh = IVAL(p,4); - - if (thigh == 0) return(0); - - d = ((double)thigh)*4.0*(double)(1<<30); - d += (tlow&0xFFF00000); - d *= 1.0e-7; - - /* now adjust by 369 years to make the secs since 1970 */ - d -= TIME_FIXUP_CONSTANT; - - if (d>=MAXINT) - return(0); - - ret = (time_t)(d+0.5); - - /* this takes us from kludge-GMT to real GMT */ - ret += TimeDiff(ret) - serverzone; - - return(ret); -} - - -/**************************************************************************** -put a 8 byte filetime from a time_t -This takes real GMT as input and converts to kludge-GMT -****************************************************************************/ -void put_long_date(char *p,time_t t) -{ - uint32 tlow,thigh; - double d; - - if (t==0) { - SIVAL(p,0,0); SIVAL(p,4,0); - return; - } - - /* this converts GMT to kludge-GMT */ - t -= TimeDiff(t) - serverzone; - - d = (double) (t); - - d += TIME_FIXUP_CONSTANT; - - d *= 1.0e7; - - thigh = (uint32)(d * (1.0/(4.0*(double)(1<<30)))); - tlow = (uint32)(d - ((double)thigh)*4.0*(double)(1<<30)); - - SIVAL(p,0,tlow); - SIVAL(p,4,thigh); -} - /******************************************************************* sub strings with useful parameters ********************************************************************/ diff --git a/source/libsmb/nmblib.c b/source/libsmb/nmblib.c index 67432271737..1f789961560 100644 --- a/source/libsmb/nmblib.c +++ b/source/libsmb/nmblib.c @@ -625,16 +625,17 @@ static void interpret_node_status(char *p, char *master,char *rname) char qname[17]; int type; fstring flags; + int i; *flags = 0; StrnCpy(qname,p,15); type = CVAL(p,15); p += 16; - if (p[0] & 0x80) strcat(flags," "); - if ((p[0] & 0x60) == 0) strcat(flags,"B "); - if ((p[0] & 0x60) == 1) strcat(flags,"P "); - if ((p[0] & 0x60) == 2) strcat(flags,"M "); - if ((p[0] & 0x60) == 3) strcat(flags,"_ "); + strcat(flags, (p[0] & 0x80) ? " " : " "); + if ((p[0] & 0x60) == 0x00) strcat(flags,"B "); + if ((p[0] & 0x60) == 0x20) strcat(flags,"P "); + if ((p[0] & 0x60) == 0x40) strcat(flags,"M "); + if ((p[0] & 0x60) == 0x60) strcat(flags,"_ "); if (p[0] & 0x10) strcat(flags," "); if (p[0] & 0x08) strcat(flags," "); if (p[0] & 0x04) strcat(flags," "); @@ -650,7 +651,10 @@ static void interpret_node_status(char *p, char *master,char *rname) trim_string(rname,NULL," "); } - DEBUG(level,("\t%s (type=0x%x)\t%s\n",qname,type,flags)); + for (i = strlen( qname) ; --i >= 0 ; ) { + if (!isprint(qname[i])) qname[i] = '.'; + } + DEBUG(level,("\t%-15s <%02x> - %s\n",qname,type,flags)); p+=2; } DEBUG(level,("num_good_sends=%d num_good_receives=%d\n", diff --git a/source/loadparm.h b/source/loadparm.h index 513dbcd636b..143c8a2fcab 100644 --- a/source/loadparm.h +++ b/source/loadparm.h @@ -79,6 +79,7 @@ extern BOOL lp_strip_dot(void); extern BOOL lp_encrypted_passwords(void); extern BOOL lp_syslog_only(void); extern BOOL lp_browse_list(void); +extern BOOL lp_proxy_name_resolution(void); extern int lp_numservices(void); extern int lp_keepalive(void); extern int lp_passwordlevel(void); @@ -154,6 +155,7 @@ extern char lp_magicchar(int iService); extern int lp_max_connections(int iService); extern BOOL lp_add_home(char *pservice,int ifrom,char *phome); extern char *lp_string(char *s); +extern BOOL lp_delete_readonly(int iService); char *my_workgroup(void); #endif diff --git a/source/nameserv.c b/source/nameserv.c index 802b98ec0a0..b64a9345726 100644 --- a/source/nameserv.c +++ b/source/nameserv.c @@ -1798,6 +1798,11 @@ static void reply_name_query(struct packet_struct *p) return; } + if (!lp_proxy_name_resolution() && n->source != SELF) { + DEBUG(3,("no proxy resolution\n")); + return; + } + /* don't respond to bcast queries for addresses on the same net as the machine doing the querying unless its our IP */ if (bcast && diff --git a/source/param/loadparm.c b/source/param/loadparm.c index c61ab26781f..e7b9d2d9b8f 100644 --- a/source/param/loadparm.c +++ b/source/param/loadparm.c @@ -161,6 +161,7 @@ typedef struct BOOL bReadbmpx; BOOL bSyslogOnly; BOOL bBrowseList; + BOOL bProxyNameResolution; } global; static global Globals; @@ -236,6 +237,7 @@ typedef struct BOOL bSyncAlways; char magic_char; BOOL *copymap; + BOOL bDeleteReadonly; char dummy[3]; /* for alignment */ } service; @@ -307,6 +309,7 @@ static service sDefault = False, /* bSyncAlways */ '~', /* magic char */ NULL, /* copymap */ + False, /* bDeleteReadonly */ "" /* dummy */ }; @@ -413,6 +416,7 @@ struct parm_struct {"domain master", P_BOOL, P_GLOBAL, &Globals.bDomainMaster, NULL}, {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL}, {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL}, + {"proxy name resolution",P_BOOL,P_GLOBAL,&Globals.bProxyNameResolution,NULL}, {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL}, {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL}, @@ -493,6 +497,7 @@ struct parm_struct {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL}, {"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}, {NULL, P_BOOL, P_NONE, NULL, NULL} }; @@ -568,6 +573,7 @@ static void init_globals(void) Globals.bDomainMaster = False; Globals.bDomainLogons = False; Globals.bBrowseList = True; + Globals.bProxyNameResolution = True; #ifdef KANJI coding_system = interpret_coding_system (KANJI, SJIS_CODE); @@ -595,6 +601,7 @@ static void init_locals(void) { case PRINT_BSD: case PRINT_AIX: + case PRINT_PLP: string_initial(&sDefault.szLpqcommand,"lpq -P%p"); string_initial(&sDefault.szLprmcommand,"lprm -P%p %j"); string_initial(&sDefault.szPrintcommand,"lpr -r -P%p %s"); @@ -705,6 +712,7 @@ FN_GLOBAL_BOOL(lp_strip_dot,&Globals.bStripDot) FN_GLOBAL_BOOL(lp_encrypted_passwords,&Globals.bEncryptPasswords) FN_GLOBAL_BOOL(lp_syslog_only,&Globals.bSyslogOnly) FN_GLOBAL_BOOL(lp_browse_list,&Globals.bBrowseList) +FN_GLOBAL_BOOL(lp_proxy_name_resolution,&Globals.bProxyNameResolution) FN_GLOBAL_INTEGER(lp_os_level,&Globals.os_level) FN_GLOBAL_INTEGER(lp_max_ttl,&Globals.max_ttl) @@ -778,6 +786,7 @@ FN_LOCAL_BOOL(lp_manglednames,bMangledNames) FN_LOCAL_BOOL(lp_widelinks,bWidelinks) FN_LOCAL_BOOL(lp_syncalways,bSyncAlways) FN_LOCAL_BOOL(lp_map_system,bMap_system) +FN_LOCAL_BOOL(lp_delete_readonly,bDeleteReadonly) FN_LOCAL_INTEGER(lp_create_mode,iCreate_mode) FN_LOCAL_INTEGER(lp_max_connections,iMaxConnections) @@ -1291,6 +1300,8 @@ static BOOL handle_printing(char *pszParmValue,int *val) *val = PRINT_BSD; else if (strequal(pszParmValue,"qnx")) *val = PRINT_QNX; + else if (strequal(pszParmValue,"plp")) + *val = PRINT_PLP; return(True); } diff --git a/source/printing/printing.c b/source/printing/printing.c index 1dd8921800a..2aa27926d9b 100644 --- a/source/printing/printing.c +++ b/source/printing/printing.c @@ -149,7 +149,7 @@ process time fields ********************************************************************/ static time_t EntryTime(string tok[], int ptr, int count, int minimum) { - time_t jobtime; + time_t jobtime,jobtime1; jobtime = time(NULL); /* default case: take current time */ if (count >= minimum) { @@ -181,7 +181,9 @@ static time_t EntryTime(string tok[], int ptr, int count, int minimum) t->tm_hour = hour; t->tm_min = min; t->tm_sec = sec; - jobtime = mktime(t); + jobtime1 = mktime(t); + if (jobtime1 != (time_t)-1) + jobtime = jobtime1; } } return jobtime; @@ -596,6 +598,78 @@ static BOOL parse_lpq_qnx(char *line,print_queue_struct *buf,BOOL first) } +/**************************************************************************** + parse a lpq line for the plp printing system + Bertrand Wallrich +****************************************************************************/ +static BOOL parse_lpq_plp(char *line,print_queue_struct *buf,BOOL first) +{ + string tok[5]; + int count=0; + + /* handle the case of "(standard input)" as a filename */ + string_sub(line,"stdin","STDIN"); + string_sub(line,"(","\""); + string_sub(line,")","\""); + + for (count=0; count<8 && next_token(&line,tok[count],NULL); count++) ; + + /* we must get 5 tokens */ + if (count < 8) + return(False); + + /* the 4rd must be integer */ + if (!isdigit(*tok[3])) return(False); + + /* if the fname contains a space then use STDIN */ + if (strchr(tok[3],' ')) + strcpy(tok[3],"STDIN"); + + /* only take the last part of the filename */ + { + string tmp; + char *p = strrchr(tok[5],'/'); + if (p) + { + strcpy(tmp,p+1); + strcpy(tok[5],tmp); + } + } + + + buf->job = atoi(tok[3]); + + /* calcul de la taille du fichier */ + if (!isdigit(*tok[7])) { buf->size = atoi(tok[7]) * 1.0 ; } + else { + string tmp; + strcpy(tmp,tok[7]); + if (strchr(tok[7],'K')) { + strncpy(tok[7],tmp,strlen(tmp)-1); + buf->size = atoi(tok[7]); + buf->size = buf->size * 1024; + } + if (strchr(tok[7],'M')) { + strncpy(tok[7],tmp,strlen(tmp)-1); + buf->size = atoi(tok[7]); + buf->size = buf->size * 1024.0 * 1000.0; + } + if (strchr(tok[7],'G')) { + strncpy(tok[7],tmp,strlen(tmp)-1); + buf->size = atoi(tok[7]); + buf->size = buf->size * 1024.0 * 1000000.0; + } + + } + buf->status = strequal(tok[0],"active")?LPQ_PRINTING:LPQ_QUEUED; + buf->priority = 0; + buf->time = time(NULL); + StrnCpy(buf->user,tok[1],sizeof(buf->user)-1); + StrnCpy(buf->file,tok[5],sizeof(buf->file)-1); + return(True); +} + + char *stat0_strings[] = { "enabled", "online", "idle", "no entries", "free", "ready", NULL }; char *stat1_strings[] = { "offline", "disabled", "down", "off", "waiting", "no daemon", NULL }; @@ -624,6 +698,9 @@ static BOOL parse_lpq_entry(int snum,char *line, case PRINT_QNX: ret = parse_lpq_qnx(line,buf,first); break; + case PRINT_PLP: + ret = parse_lpq_plp(line,buf,first); + break; default: ret = parse_lpq_bsd(line,buf,first); break; diff --git a/source/smbd/ipc.c b/source/smbd/ipc.c index 34210f2db70..3b2c55dc46b 100644 --- a/source/smbd/ipc.c +++ b/source/smbd/ipc.c @@ -467,7 +467,7 @@ static void fill_printjob_info(int cnum, int snum, int uLevel, time_t t = queue->time; /* the client expects localtime */ - t += GMT_TO_LOCAL*TimeDiff(t); + t -= TimeDiff(t); PACKI(desc,"W",((snum%0xFF)<<8) | (queue->job%0xFF)); /* uJobId */ if (uLevel == 1) { @@ -479,7 +479,7 @@ static void fill_printjob_info(int cnum, int snum, int uLevel, PACKI(desc,"W",n+1); /* uPosition */ PACKI(desc,"W",queue->status); /* fsStatus */ PACKS(desc,"z",""); /* pszStatus */ - PACKI(desc,"D",queue->time); /* ulSubmitted */ + PACKI(desc,"D",t); /* ulSubmitted */ PACKI(desc,"D",queue->size); /* ulSize */ PACKS(desc,"z",queue->file); /* pszComment */ } @@ -488,7 +488,7 @@ static void fill_printjob_info(int cnum, int snum, int uLevel, PACKS(desc,"z",queue->user); /* pszUserName */ PACKI(desc,"W",n+1); /* uPosition */ PACKI(desc,"W",queue->status); /* fsStatus */ - PACKI(desc,"D",queue->time); /* ulSubmitted */ + PACKI(desc,"D",t); /* ulSubmitted */ PACKI(desc,"D",queue->size); /* ulSize */ PACKS(desc,"z","Samba"); /* pszComment */ PACKS(desc,"z",queue->file); /* pszDocument */ @@ -1289,7 +1289,7 @@ static BOOL api_NetRemoteTOD(int cnum,int uid, char *param,char *data, /* the client expects to get localtime, not GMT, in this bit (I think, this needs testing) */ - t = LocalTime(&unixdate,GMT_TO_LOCAL); + t = LocalTime(&unixdate); SIVAL(p,4,0); /* msecs ? */ CVAL(p,8) = t->tm_hour; diff --git a/source/smbd/password.c b/source/smbd/password.c index 6031daf5f16..b8111fc739a 100644 --- a/source/smbd/password.c +++ b/source/smbd/password.c @@ -287,15 +287,13 @@ static void update_protected_database( char *user, BOOL result) #ifdef OSF1_ENH_SEC struct pr_passwd *mypasswd; time_t starttime; - long tz; mypasswd = getprpwnam (user); starttime = time (NULL); - tz = mktime ( localtime ( &starttime ) ); if (result) { - mypasswd->ufld.fd_slogin = tz; + mypasswd->ufld.fd_slogin = starttime; mypasswd->ufld.fd_nlogins = 0; putprpwnam(user,mypasswd); @@ -304,7 +302,7 @@ static void update_protected_database( char *user, BOOL result) } else { - mypasswd->ufld.fd_ulogin = tz; + mypasswd->ufld.fd_ulogin = starttime; mypasswd->ufld.fd_nlogins = mypasswd->ufld.fd_nlogins + 1; if ( mypasswd->ufld.fd_max_tries != 0 && mypasswd->ufld.fd_nlogins > mypasswd->ufld.fd_max_tries ) { diff --git a/source/smbd/quotas.c b/source/smbd/quotas.c index 32c9fc35d30..81f2dcaab5a 100644 --- a/source/smbd/quotas.c +++ b/source/smbd/quotas.c @@ -1,3 +1,4 @@ +#ifdef QUOTAS /* Unix SMB/Netbios implementation. Version 1.9. @@ -19,12 +20,28 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "includes.h" +/* + * This is one of the most system dependent parts of Samba, and its + * done a litle differently. Each system has its own way of doing + * things :-( + */ + +#include "includes.h" -#ifdef QUOTAS #ifdef LINUX + +#ifdef __KERNEL__ +# undef __KERNEL__ +# include +# define __KERNEL__ +#else +# include +#endif + +#include + /**************************************************************************** try to get the disk space from disk quotas (LINUX version) ****************************************************************************/ @@ -115,6 +132,10 @@ static BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize) } #elif defined(CRAY) + +#include +#include + /**************************************************************************** try to get the disk space from disk quotas (CRAY VERSION) ****************************************************************************/ @@ -214,6 +235,7 @@ static BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize) #elif defined(SUNOS5) +#include #include #include @@ -228,30 +250,33 @@ static BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize) struct dqblk D; struct quotctl command; int file; + int ret; if((file=open(path, O_RDONLY))<0) return(False); euser_id = geteuid(); user_id = getuid(); - setuid(0); /* Solaris seems to want to give info only to super-user */ - seteuid(0); - command.op = Q_GETQUOTA; command.uid = euser_id; command.addr = (caddr_t) &D; - if(ioctl(file, Q_QUOTACTL, &command)<0) - { - close(file); - DEBUG(2,("disk_quotas ioctl (Solaris) failed\n")); - return(False); - } - close(file); + setuid(0); /* Solaris seems to want to give info only to super-user */ + seteuid(0); + + ret = ioctl(file, Q_QUOTACTL, &command); setuid(user_id); /* Restore the original UID status */ seteuid(euser_id); + if (ret < 0) { + close(file); + DEBUG(2,("disk_quotas ioctl (Solaris) failed\n")); + return(False); + } + close(file); + + /* Use softlimit to determine disk space. A user exceeding the quota is told * that there's no space left. Writes might actually work for a bit if the * hardlimit is set higher than softlimit. Effectively the disk becomes @@ -275,6 +300,9 @@ DEBUG(5,("disk_quotas for path \"%s\" returning bsize %d, dfree %d, dsize %d\n" #else +#include +#include + /**************************************************************************** try to get the disk space from disk quotas - default version ****************************************************************************/ @@ -327,4 +355,5 @@ static BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize) } #endif -#endif +#endif /* QUOTAS */ + diff --git a/source/smbd/reply.c b/source/smbd/reply.c index b5fa86a8d7d..68376baaf38 100644 --- a/source/smbd/reply.c +++ b/source/smbd/reply.c @@ -1181,7 +1181,9 @@ static BOOL can_delete(char *fname,int cnum,int dirtype) if (sys_lstat(fname,&sbuf) != 0) return(False); fmode = dos_mode(cnum,fname,&sbuf); if (fmode & aDIR) return(False); - if (fmode & aRONLY) return(False); + if (!lp_delete_readonly(SNUM(cnum))) { + if (fmode & aRONLY) return(False); + } if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM)) return(False); if (!check_file_sharing(cnum,fname)) return(False); diff --git a/source/smbd/server.c b/source/smbd/server.c index 5ef92777b24..3140d3ff84c 100644 --- a/source/smbd/server.c +++ b/source/smbd/server.c @@ -2456,6 +2456,8 @@ int make_connection(char *service,char *user,char *password, int pwlen, char *de int find_free_file(void ) { int i; + /* we start at 1 here for an obscure reason I can't now remember, + but I think is important :-) */ for (i=1;i