diff options
author | Jeremy Allison <jra@samba.org> | 1998-02-12 06:49:56 +0000 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 1998-02-12 06:49:56 +0000 |
commit | b4dd84bce39325325b6bd622c30d61016b559970 (patch) | |
tree | 26693c34391f67a265af626301b8c3e401e4ca40 /source | |
parent | cfc3e6d6b6b8f3ea8aef6ab095694d88096bfd0e (diff) | |
download | samba-b4dd84bce39325325b6bd622c30d61016b559970.tar.gz samba-b4dd84bce39325325b6bd622c30d61016b559970.tar.xz samba-b4dd84bce39325325b6bd622c30d61016b559970.zip |
Sync up with head branch.
chgpasswd.c: Fixed typo in error message.
includes.h: AIX update.
kanji.c: Fix from ado@elsie.nci.nih.gov (Arthur David Olson) to reverse cap->sj correctly.
loadparm.c: Added "networkstation user login" and "win95 bug compatibility" parameters.
local.h: networkstationuserlogon fix.
password.c: Fix for DCE from Brett Wooldridge <brettw@austin.ibm.com>, networkstationuserlogon fix.
printing.c: Support for LPQ_PAUSED on aix.
reply.c: Fix for ulogoff closing too many files.
Added get_access_time().
server.c: Fix for ulogoff closing too many files.
Added get_access_time().
Fix for NT redirector bug.
Fix to close oplocked file when run out of open file handles.
Ask for 10 more fd's than before.
smb.h: Fix for ulogoff closing too many files.
time.c: Added get_access_time().
trans2.c: Added "win95 bug compatibility" fix.
uid.c: Fix for ulogoff closing too many files.
util.c: Extra debug message. Added capability to parse environment variables from Branko Cibej <branko.cibej@hermes.si>.
Jeremy.
Diffstat (limited to 'source')
-rw-r--r-- | source/include/includes.h | 5 | ||||
-rw-r--r-- | source/include/local.h | 10 | ||||
-rw-r--r-- | source/include/proto.h | 3 | ||||
-rw-r--r-- | source/include/smb.h | 4 | ||||
-rw-r--r-- | source/lib/kanji.c | 36 | ||||
-rw-r--r-- | source/lib/time.c | 14 | ||||
-rw-r--r-- | source/lib/util.c | 36 | ||||
-rw-r--r-- | source/param/loadparm.c | 8 | ||||
-rw-r--r-- | source/printing/printing.c | 4 | ||||
-rw-r--r-- | source/smbd/chgpasswd.c | 2 | ||||
-rw-r--r-- | source/smbd/password.c | 61 | ||||
-rw-r--r-- | source/smbd/reply.c | 4 | ||||
-rw-r--r-- | source/smbd/server.c | 68 | ||||
-rw-r--r-- | source/smbd/trans2.c | 41 | ||||
-rw-r--r-- | source/smbd/uid.c | 8 |
15 files changed, 245 insertions, 59 deletions
diff --git a/source/include/includes.h b/source/include/includes.h index 218ce199559..f9c29fd41dc 100644 --- a/source/include/includes.h +++ b/source/include/includes.h @@ -552,9 +552,12 @@ char *mktemp(char *); /* No standard include */ #include <sys/vfs.h> #include <sys/id.h> #include <sys/priv.h> +/* According to AIX 4.1 man pages, inet_ntoa needs the following headers */ +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> #include <netinet/tcp.h> #include <locale.h> -#include <arpa/inet.h> /* needed for inet_ntoa proto */ #define SYSV #define USE_WAITPID #define USE_SIGBLOCK diff --git a/source/include/local.h b/source/include/local.h index 0e2a927d2ee..22862a9a1ff 100644 --- a/source/include/local.h +++ b/source/include/local.h @@ -17,16 +17,6 @@ refer to the special "printers" service */ #define PRINTERS_NAME "printers" -/* this affects server level security. With this set (recommended) - samba will do a full NetWkstaUserLogon to confirm that the client - really should have login rights. This can cause problems with - machines in trust relationships in which case you can disable it - here, but be warned, we have heard that some NT machines will then - allow anyone in with any password! Make sure you test it. */ -#ifndef USE_NETWKSTAUSERLOGON -#define USE_NETWKSTAUSERLOGON 1 -#endif - /* define what facility to use for syslog */ #ifndef SYSLOG_FACILITY #define SYSLOG_FACILITY LOG_DAEMON diff --git a/source/include/proto.h b/source/include/proto.h index fd31db7e629..306d3a42a0c 100644 --- a/source/include/proto.h +++ b/source/include/proto.h @@ -279,6 +279,8 @@ BOOL lp_unix_realname(void); BOOL lp_nis_home_map(void); BOOL lp_time_server(void); BOOL lp_bind_interfaces_only(void); +BOOL lp_net_wksta_user_logon(void); +BOOL lp_win95_bug_compatibility(void); int lp_os_level(void); int lp_max_ttl(void); int lp_max_wins_ttl(void); @@ -1340,6 +1342,7 @@ time_t make_unix_date2(void *date_ptr); time_t make_unix_date3(void *date_ptr); char *timestring(void ); time_t get_create_time(struct stat *st); +time_t get_access_time(struct stat *st); /*The following definitions come from trans2.c */ diff --git a/source/include/smb.h b/source/include/smb.h index 9a7278069d4..77f4006c4aa 100644 --- a/source/include/smb.h +++ b/source/include/smb.h @@ -1366,7 +1366,7 @@ struct cli_state { struct current_user { - int cnum, id; + int cnum, vuid; int uid, gid; int ngroups; gid_t *groups; @@ -1424,7 +1424,7 @@ typedef struct int pos; uint32 size; int mode; - int uid; + int vuid; char *mmap_ptr; uint32 mmap_size; write_bmpx_struct *wbmpx_ptr; diff --git a/source/lib/kanji.c b/source/lib/kanji.c index 2027a344c26..d63798914e9 100644 --- a/source/lib/kanji.c +++ b/source/lib/kanji.c @@ -693,7 +693,39 @@ static char *sj_to_hex(char *from, BOOL overwrite) } /******************************************************************* - kanji/kana -> ":xx" + CAP <-> SJIS +********************************************************************/ +/* ":xx" CAP -> a byte */ +static char *cap_to_sj(char *from, BOOL overwrite) +{ + char *sp, *dp; + + sp = (char *) from; + dp = cvtbuf; + while (*sp) { + /* + * The only change between this and hex_to_sj is here. sj_to_cap only + * translates characters greater or equal to 0x80 - make sure that here + * we only do the reverse (that's why the strchr is used rather than + * isxdigit. Based on fix from ado@elsie.nci.nih.gov (Arthur David Olson). + */ + if (*sp == hex_tag && (strchr ("89abcdefABCDEF", sp[1]) != NULL) && isxdigit (sp[2])) { + *dp++ = (hex2bin (sp[1])<<4) | (hex2bin (sp[2])); + sp += 3; + } else + *dp++ = *sp++; + } + *dp = '\0'; + if (overwrite) { + strcpy ((char *) from, (char *) cvtbuf); + return (char *) from; + } else { + return cvtbuf; + } +} + +/******************************************************************* + kanji/kana -> ":xx" - CAP format. ********************************************************************/ static char *sj_to_cap(char *from, BOOL overwrite) { @@ -778,7 +810,7 @@ static int setup_string_function(int codes) case CAP_CODE: _dos_to_unix = sj_to_cap; - _unix_to_dos = hex_to_sj; + _unix_to_dos = cap_to_sj; break; } return codes; diff --git a/source/lib/time.c b/source/lib/time.c index f60af60c7aa..81e3dcfd8f1 100644 --- a/source/lib/time.c +++ b/source/lib/time.c @@ -499,3 +499,17 @@ time_t get_create_time(struct stat *st) */ return ret; } + +/**************************************************************************** + return the 'access time' under UNIX from a stat structure. + This function exists to allow modifications to be done depending + on what we want to return. Just return the normal atime (for now). +****************************************************************************/ + +time_t get_access_time(struct stat *st) +{ + if (lp_win95_bug_compatibility()) + return st->st_mtime; + else + return st->st_atime; +} diff --git a/source/lib/util.c b/source/lib/util.c index 1b9ed00c31a..3b30f1e6b5b 100644 --- a/source/lib/util.c +++ b/source/lib/util.c @@ -1990,6 +1990,10 @@ int write_socket(int fd,char *buf,int len) ret = write_data(fd,buf,len); DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret)); + if(ret <= 0) + DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n", + len, fd, strerror(errno) )); + return(ret); } @@ -3807,6 +3811,38 @@ void standard_sub_basic(char *str) case 'h' : string_sub(p,"%h", myhostname); break; case 'm' : string_sub(p,"%m", remote_machine); break; case 'v' : string_sub(p,"%v", VERSION); break; + case '$' : /* Expand environment variables */ + { + /* Contributed by Branko Cibej <branko.cibej@hermes.si> */ + fstring envname; + char *envval; + char *q, *r; + int copylen; + + if (*(p+2) != '(') { p+=2; break; } + if ((q = strchr(p,')')) == NULL) + { + DEBUG(0,("standard_sub_basic: Unterminated environment \ +variable [%s]\n", p)); + p+=2; break; + } + + r = p+3; + copylen = MIN((q-r),(sizeof(envname)-1)); + strncpy(envname,r,copylen); + envname[copylen] = '\0'; + if ((envval = getenv(envname)) == NULL) + { + DEBUG(0,("standard_sub_basic: Environment variable [%s] not set\n", + envname)); + p+=2; break; + } + copylen = MIN((q+1-p),(sizeof(envname)-1)); + strncpy(envname,p,copylen); + envname[copylen] = '\0'; + string_sub(p,envname,envval); + break; + } case '\0': p++; break; /* don't run off end if last character is % */ default : p+=2; break; } diff --git a/source/param/loadparm.c b/source/param/loadparm.c index d2db90fd678..82a48514442 100644 --- a/source/param/loadparm.c +++ b/source/param/loadparm.c @@ -188,6 +188,8 @@ typedef struct BOOL bNISHomeMap; BOOL bTimeServer; BOOL bBindInterfacesOnly; + BOOL bNetWkstaUserLogon; + BOOL bWin95BugCompatibility; } global; static global Globals; @@ -444,6 +446,7 @@ static struct parm_struct {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL, NULL}, {"interfaces", P_STRING, P_GLOBAL, &Globals.szInterfaces, NULL, NULL}, {"bind interfaces only", P_BOOL,P_GLOBAL, &Globals.bBindInterfacesOnly,NULL, NULL}, + {"networkstation user login", P_BOOL,P_GLOBAL, &Globals.bNetWkstaUserLogon,NULL, NULL}, {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL}, {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL}, {"netbios name", P_UGSTRING,P_GLOBAL, myname, NULL, NULL}, @@ -528,6 +531,7 @@ static struct parm_struct {"unix realname", P_BOOL, P_GLOBAL, &Globals.bUnixRealname, NULL, NULL}, {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL}, {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL}, + {"win95 bug compatibility", P_BOOL, P_GLOBAL, &Globals.bWin95BugCompatibility,NULL, NULL}, {"printer driver file", P_STRING, P_GLOBAL, &Globals.szDriverFile, NULL, NULL}, {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL}, {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL}, @@ -720,6 +724,8 @@ static void init_globals(void) Globals.client_code_page = DEFAULT_CLIENT_CODE_PAGE; Globals.bTimeServer = False; Globals.bBindInterfacesOnly = False; + Globals.bNetWkstaUserLogon = True; + Globals.bWin95BugCompatibility = False; /* these parameters are set to defaults that are more appropriate for the increasing samba install base: @@ -935,6 +941,8 @@ 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_bind_interfaces_only,&Globals.bBindInterfacesOnly) +FN_GLOBAL_BOOL(lp_net_wksta_user_logon,&Globals.bNetWkstaUserLogon) +FN_GLOBAL_BOOL(lp_win95_bug_compatibility,&Globals.bWin95BugCompatibility) FN_GLOBAL_INTEGER(lp_os_level,&Globals.os_level) FN_GLOBAL_INTEGER(lp_max_ttl,&Globals.max_ttl) diff --git a/source/printing/printing.c b/source/printing/printing.c index 71b89022e6e..bf49a372030 100644 --- a/source/printing/printing.c +++ b/source/printing/printing.c @@ -486,7 +486,7 @@ static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first) /* we must get 6 tokens */ if (count < 10) { - if ((count == 7) && (strcmp(tok[0],"QUEUED") == 0)) + if ((count == 7) && ((strcmp(tok[0],"QUEUED") == 0) || (strcmp(tok[0],"HELD") == 0))) { /* the 2nd and 5th columns must be integer */ if (!isdigit(*tok[1]) || !isdigit(*tok[4])) return(False); @@ -508,7 +508,7 @@ static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first) buf->job = atoi(tok[1]); - buf->status = LPQ_QUEUED; + buf->status = strequal(tok[0],"HELD")?LPQ_PAUSED:LPQ_QUEUED; buf->priority = 0; buf->time = time(NULL); StrnCpy(buf->user,tok[3],sizeof(buf->user)-1); diff --git a/source/smbd/chgpasswd.c b/source/smbd/chgpasswd.c index 80c7a43750f..fb795e973e5 100644 --- a/source/smbd/chgpasswd.c +++ b/source/smbd/chgpasswd.c @@ -437,7 +437,7 @@ BOOL check_lanman_password(char *user, unsigned char *pass1, /* Check that the two old passwords match. */ if(memcmp(smbpw->smb_passwd, unenc_old_pw, 16)) { - DEBUG(0,("check_lanman_password: old password doens't match.\n")); + DEBUG(0,("check_lanman_password: old password doesn't match.\n")); return False; } diff --git a/source/smbd/password.c b/source/smbd/password.c index 0f8705d4be3..607d01d2cfb 100644 --- a/source/smbd/password.c +++ b/source/smbd/password.c @@ -514,9 +514,14 @@ static BOOL dfs_auth(char *this_user,char *password) * Assumes local passwd file is kept in sync w/ DCE RGY! */ - if (!strcmp((char *)crypt(password,this_salt),this_crypted) || - dcelogin_atmost_once) - return(False); + /* Fix for original (broken) code from Brett Wooldridge <brettw@austin.ibm.com> */ + if (dce_login_atmost_once) + return (False); + /* This can be ifdefed as the DCE check below is stricter... */ +#ifndef NO_CRYPT + if ( strcmp((char *)crypt(password,this_salt),this_crypted) ) + return (False); +#endif if (sec_login_setup_identity( (unsigned char *)this_user, @@ -1597,28 +1602,40 @@ BOOL server_validate(char *user, char *domain, return False; } + /* + * This patch from Rob Nielsen <ran@adc.com> makes doing + * the NetWksaUserLogon a dynamic, rather than compile-time + * parameter, defaulting to on. This is somewhat dangerous + * as it allows people to turn off this neccessary check, + * but so many people have had problems with this that I + * think it is a neccessary change. JRA. + */ + + if (lp_net_wksta_user_logon()) { + DEBUG(3,("trying NetWkstaUserLogon with password server %s\n", cli.desthost)); + if (!cli_NetWkstaUserLogon(&cli,user,local_machine)) { + DEBUG(1,("password server %s failed NetWkstaUserLogon\n", cli.desthost)); + cli_tdis(&cli); + return False; + } -#if USE_NETWKSTAUSERLOGON - if (!cli_NetWkstaUserLogon(&cli,user,local_machine)) { - DEBUG(1,("password server %s failed NetWkstaUserLogon\n", cli.desthost)); - cli_tdis(&cli); - return False; - } - - if (cli.privilages == 0) { - DEBUG(1,("password server %s gave guest privilages\n", cli.desthost)); - cli_tdis(&cli); - return False; - } + if (cli.privilages == 0) { + DEBUG(1,("password server %s gave guest privilages\n", cli.desthost)); + cli_tdis(&cli); + return False; + } - if (!strequal(cli.eff_name, user)) { - DEBUG(1,("password server %s gave different username %s\n", - cli.desthost, - cli.eff_name)); - cli_tdis(&cli); - return False; + if (!strequal(cli.eff_name, user)) { + DEBUG(1,("password server %s gave different username %s\n", + cli.desthost, + cli.eff_name)); + cli_tdis(&cli); + return False; + } } -#endif + else { + DEBUG(3,("skipping NetWkstaUserLogon with password server %s\n", cli.desthost)); + } DEBUG(3,("password server %s accepted the password\n", cli.desthost)); diff --git a/source/smbd/reply.c b/source/smbd/reply.c index 4703dea4751..93bb679289c 100644 --- a/source/smbd/reply.c +++ b/source/smbd/reply.c @@ -1385,7 +1385,7 @@ int reply_ulogoffX(char *inbuf,char *outbuf,int length,int bufsize) if ((vuser != 0) && (lp_security() != SEC_SHARE)) { int i; for (i=0;i<MAX_OPEN_FILES;i++) - if (Files[i].uid == vuser->uid && Files[i].open) { + if ((Files[i].vuid == vuid) && Files[i].open) { close_file(i,False); } } @@ -3917,7 +3917,7 @@ int reply_getattrE(char *inbuf,char *outbuf) date to be last modify date as UNIX doesn't save this */ put_dos_date2(outbuf,smb_vwv0,get_create_time(&sbuf)); - put_dos_date2(outbuf,smb_vwv2,sbuf.st_atime); + put_dos_date2(outbuf,smb_vwv2,get_access_time(&sbuf)); put_dos_date2(outbuf,smb_vwv4,sbuf.st_mtime); if (mode & aDIR) { diff --git a/source/smbd/server.c b/source/smbd/server.c index 01d379ebb33..0a6a05fdbfe 100644 --- a/source/smbd/server.c +++ b/source/smbd/server.c @@ -1344,7 +1344,7 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct Connections[cnum].num_files_open++; fsp->mode = sbuf->st_mode; GetTimeOfDay(&fsp->open_time); - fsp->uid = current_user.id; + fsp->vuid = current_user.vuid; fsp->size = 0; fsp->pos = -1; fsp->open = True; @@ -1637,13 +1637,15 @@ BOOL check_file_sharing(int cnum,char *fname, BOOL rename_op) { DEBUG(0,("check_file_sharing: NT redirector workaround - rename attempted on \ batch oplocked file %s, dev = %x, inode = %x\n", fname, dev, inode)); -#if 0 /* * This next line is a test that allows the deny-mode - * processing to be skipped. JRA. + * processing to be skipped. This seems to be needed as + * NT insists on the rename succeeding (in Office 9x no less !). + * This should be removed as soon as (a) MS fix the redirector + * bug or (b) NT SMB support in Samba makes NT not issue the + * call (as is my fervent hope). JRA. */ continue; -#endif } else { @@ -3695,6 +3697,31 @@ int make_connection(char *service,char *user,char *password, int pwlen, char *de return(cnum); } +/**************************************************************************** + Attempt to break an oplock on a file (if oplocked). + Returns True if the file was closed as a result of + the oplock break, False otherwise. + Used as a last ditch attempt to free a space in the + file table when we have run out. +****************************************************************************/ + +static BOOL attempt_close_oplocked_file(files_struct *fp) +{ + + DEBUG(5,("attempt_close_oplocked_file: checking file %s.\n", fp->name)); + + if (fp->open && fp->granted_oplock && !fp->sent_oplock_break) { + + /* Try and break the oplock. */ + file_fd_struct *fsp = fp->fd_ptr; + if(oplock_break( fsp->dev, fsp->inode, &fp->open_time)) { + if(!fp->open) /* Did the oplock break close the file ? */ + return True; + } + } + + return False; +} /**************************************************************************** find first available file slot @@ -3734,6 +3761,32 @@ int find_free_file(void ) return(i); } + /* + * Before we give up, go through the open files + * and see if there are any files opened with a + * batch oplock. If so break the oplock and then + * re-use that entry (if it becomes closed). + * This may help as NT/95 clients tend to keep + * files batch oplocked for quite a long time + * after they have finished with them. + */ + for (i=first_file;i<MAX_OPEN_FILES;i++) { + if(attempt_close_oplocked_file( &Files[i])) { + memset(&Files[i], 0, sizeof(Files[i])); + first_file = i+1; + Files[i].reserved = True; + return(i); + } + } + + for (i=1;i<MAX_OPEN_FILES;i++) { + if(attempt_close_oplocked_file( &Files[i])) { + memset(&Files[i], 0, sizeof(Files[i])); + first_file = i+1; + Files[i].reserved = True; + return(i); + } + } DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n")); return(-1); @@ -5280,7 +5333,12 @@ static void usage(char *pname) { struct rlimit rlp; getrlimit(RLIMIT_NOFILE, &rlp); - rlp.rlim_cur = (MAX_OPEN_FILES>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES; + /* + * Set the fd limit to be MAX_OPEN_FILES + 10 to account for the + * extra fd we need to read directories, as well as the log files + * and standard handles etc. + */ + rlp.rlim_cur = (MAX_OPEN_FILES+10>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES+10; setrlimit(RLIMIT_NOFILE, &rlp); getrlimit(RLIMIT_NOFILE, &rlp); DEBUG(3,("Maximum number of open files per session is %d\n",rlp.rlim_cur)); diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c index a9e15f65c49..2b5d5785fa0 100644 --- a/source/smbd/trans2.c +++ b/source/smbd/trans2.c @@ -32,6 +32,7 @@ extern BOOL case_sensitive; extern int Client; extern int oplock_sock; extern int smb_read_error; +extern fstring local_machine; /**************************************************************************** Send the required number of replies back. @@ -375,7 +376,7 @@ static int get_lanman2_dir_entry(int cnum,char *path_mask,int dirtype,int info_l size = sbuf.st_size; mdate = sbuf.st_mtime; - adate = sbuf.st_atime; + adate = get_access_time(&sbuf); cdate = get_create_time(&sbuf); if(mode & aDIR) size = 0; @@ -940,7 +941,8 @@ static int call_trans2qfsinfo(char *inbuf, char *outbuf, int length, int bufsize int data_len; struct stat st; char *vname = volume_label(SNUM(cnum)); - + int snum = SNUM(cnum); + DEBUG(3,("call_trans2qfsinfo: cnum = %d, level = %d\n", cnum, info_level)); if(sys_stat(".",&st)!=0) { @@ -971,7 +973,11 @@ static int call_trans2qfsinfo(char *inbuf, char *outbuf, int length, int bufsize /* Return volume name */ int volname_len = MIN(strlen(vname),11); data_len = l2_vol_szVolLabel + volname_len + 1; - put_dos_date2(pdata,l2_vol_fdateCreation,st.st_ctime); + /* + * Add volume serial number - hash of a combination of + * the called hostname and the service name. + */ + SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ str_checksum(local_machine) ); SCVAL(pdata,l2_vol_cch,volname_len); StrnCpy(pdata+l2_vol_szVolLabel,vname,volname_len); DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",st.st_ctime, volname_len, @@ -992,6 +998,11 @@ static int call_trans2qfsinfo(char *inbuf, char *outbuf, int length, int bufsize break; case SMB_QUERY_FS_VOLUME_INFO: data_len = 18 + 2*strlen(vname); + /* + * Add volume serial number - hash of a combination of + * the called hostname and the service name. + */ + SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^ str_checksum(local_machine) ); SIVAL(pdata,12,2*strlen(vname)); PutUniCode(pdata+18,vname); DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol = %s\n", strlen(vname), @@ -1128,9 +1139,18 @@ static int call_trans2qfilepathinfo(char *inbuf, char *outbuf, int length, case SMB_INFO_STANDARD: case SMB_INFO_QUERY_EA_SIZE: data_size = (info_level==1?22:26); - put_dos_date2(pdata,l1_fdateCreation,get_create_time(&sbuf)); - put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime); /* access time */ - put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */ + if( lp_win95_bug_compatibility()) + { + put_dos_date(pdata,l1_fdateCreation,get_create_time(&sbuf)); + put_dos_date(pdata,l1_fdateLastAccess,get_access_time(&sbuf)); + put_dos_date(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */ + } + else + { + put_dos_date2(pdata,l1_fdateCreation,get_create_time(&sbuf)); + put_dos_date2(pdata,l1_fdateLastAccess,get_access_time(&sbuf)); + put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */ + } SIVAL(pdata,l1_cbFile,size); SIVAL(pdata,l1_cbFileAlloc,ROUNDUP(size,1024)); SSVAL(pdata,l1_attrFile,mode); @@ -1140,7 +1160,7 @@ static int call_trans2qfilepathinfo(char *inbuf, char *outbuf, int length, case SMB_INFO_QUERY_EAS_FROM_LIST: data_size = 24; put_dos_date2(pdata,0,get_create_time(&sbuf)); - put_dos_date2(pdata,4,sbuf.st_atime); + put_dos_date2(pdata,4,get_access_time(&sbuf)); put_dos_date2(pdata,8,sbuf.st_mtime); SIVAL(pdata,12,size); SIVAL(pdata,16,ROUNDUP(size,1024)); @@ -1158,7 +1178,7 @@ static int call_trans2qfilepathinfo(char *inbuf, char *outbuf, int length, case SMB_QUERY_FILE_BASIC_INFO: data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */ put_long_date(pdata,get_create_time(&sbuf)); - put_long_date(pdata+8,sbuf.st_atime); /* access time */ + put_long_date(pdata+8,get_access_time(&sbuf)); put_long_date(pdata+16,sbuf.st_mtime); /* write time */ put_long_date(pdata+24,sbuf.st_mtime); /* change time */ SIVAL(pdata,32,mode); @@ -1167,8 +1187,9 @@ static int call_trans2qfilepathinfo(char *inbuf, char *outbuf, int length, { time_t create_time = get_create_time(&sbuf); DEBUG(5,("create: %s ", ctime(&create_time))); + create_time = get_access_time(&sbuf); + DEBUG(5,("access: %s ", ctime(&create_time))); } - DEBUG(5,("access: %s ", ctime(&sbuf.st_atime))); DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime))); DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime))); DEBUG(5,("mode: %x\n", mode)); @@ -1222,7 +1243,7 @@ static int call_trans2qfilepathinfo(char *inbuf, char *outbuf, int length, case SMB_QUERY_FILE_ALL_INFO: put_long_date(pdata,get_create_time(&sbuf)); - put_long_date(pdata+8,sbuf.st_atime); /* access time */ + put_long_date(pdata+8,get_access_time(&sbuf)); put_long_date(pdata+16,sbuf.st_mtime); /* write time */ put_long_date(pdata+24,sbuf.st_mtime); /* change time */ SIVAL(pdata,32,mode); diff --git a/source/smbd/uid.c b/source/smbd/uid.c index 176f6ca2404..14b0000f594 100644 --- a/source/smbd/uid.c +++ b/source/smbd/uid.c @@ -53,6 +53,7 @@ void init_uid(void) initial_gid = getegid(); current_user.cnum = -1; + current_user.vuid = UID_FIELD_INVALID; ChDir(OriginalDir); } @@ -174,6 +175,7 @@ BOOL become_guest(void) DEBUG(1,("Failed to become guest. Invalid guest account?\n")); current_user.cnum = -2; + current_user.vuid = UID_FIELD_INVALID; return(ret); } @@ -208,7 +210,8 @@ BOOL become_user(connection_struct *conn, int cnum, uint16 vuid) int snum,gid; int uid; - if (current_user.cnum == cnum && vuser != 0 && current_user.id == vuser->uid) { + if ((current_user.cnum == cnum) && (vuser != 0) && (current_user.vuid == vuid) && + (current_user.uid == vuser->uid)) { DEBUG(4,("Skipping become_user - already user\n")); return(True); } @@ -272,7 +275,7 @@ BOOL become_user(connection_struct *conn, int cnum, uint16 vuid) } current_user.cnum = cnum; - current_user.id = uid; + current_user.vuid = vuid; DEBUG(5,("become_user uid=(%d,%d) gid=(%d,%d)\n", getuid(),geteuid(),getgid(),getegid())); @@ -333,6 +336,7 @@ BOOL unbecome_user(void ) getuid(),geteuid(),getgid(),getegid())); current_user.cnum = -1; + current_user.vuid = UID_FIELD_INVALID; return(True); } |