summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>1998-02-12 06:49:56 +0000
committerJeremy Allison <jra@samba.org>1998-02-12 06:49:56 +0000
commitb4dd84bce39325325b6bd622c30d61016b559970 (patch)
tree26693c34391f67a265af626301b8c3e401e4ca40 /source
parentcfc3e6d6b6b8f3ea8aef6ab095694d88096bfd0e (diff)
downloadsamba-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.h5
-rw-r--r--source/include/local.h10
-rw-r--r--source/include/proto.h3
-rw-r--r--source/include/smb.h4
-rw-r--r--source/lib/kanji.c36
-rw-r--r--source/lib/time.c14
-rw-r--r--source/lib/util.c36
-rw-r--r--source/param/loadparm.c8
-rw-r--r--source/printing/printing.c4
-rw-r--r--source/smbd/chgpasswd.c2
-rw-r--r--source/smbd/password.c61
-rw-r--r--source/smbd/reply.c4
-rw-r--r--source/smbd/server.c68
-rw-r--r--source/smbd/trans2.c41
-rw-r--r--source/smbd/uid.c8
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);
}