summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
Diffstat (limited to 'source3')
-rw-r--r--source3/Makefile.in1
-rw-r--r--source3/auth/pampass.c6
-rw-r--r--source3/include/local.h8
-rw-r--r--source3/include/proto.h23
-rw-r--r--source3/include/smb.h2
-rw-r--r--source3/param/loadparm.c37
-rw-r--r--source3/passdb/pampass.c6
-rw-r--r--source3/passdb/pdb_smbpasswd.c6
-rw-r--r--source3/smbd/connection.c773
-rw-r--r--source3/smbd/password.c50
-rw-r--r--source3/smbd/reply.c7
-rw-r--r--source3/smbd/server.c4
-rw-r--r--source3/tdb/tdbutil.c1
13 files changed, 91 insertions, 833 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 5c9e817776..a639f9d3dc 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -185,6 +185,7 @@ OPLOCK_OBJ = smbd/oplock.o smbd/oplock_irix.o smbd/oplock_linux.o
NOTIFY_OBJ = smbd/notify.o smbd/notify_hash.o smbd/notify_kernel.o
SMBD_OBJ1 = smbd/server.o smbd/files.o smbd/chgpasswd.o smbd/connection.o \
+ smbd/utmp.o smbd/session.o \
smbd/dfree.o smbd/dir.o smbd/password.o smbd/conn.o smbd/fileio.o \
smbd/ipc.o smbd/lanman.o smbd/mangle.o smbd/negprot.o \
smbd/message.o smbd/nttrans.o smbd/pipes.o \
diff --git a/source3/auth/pampass.c b/source3/auth/pampass.c
index 271c46045b..d9137045e2 100644
--- a/source3/auth/pampass.c
+++ b/source3/auth/pampass.c
@@ -337,12 +337,12 @@ static BOOL proc_pam_session(pam_handle_t *pamh, char *user, char *tty, BOOL fla
/*
* PAM Externally accessible Session handler
*/
-BOOL pam_session(BOOL flag, const connection_struct *conn, char *tty)
+BOOL pam_session(BOOL flag, const char *in_user, char *tty)
{
pam_handle_t *pamh = NULL;
char * user;
- user = malloc(strlen(conn->user)+1);
+ user = malloc(strlen(in_user)+1);
if ( user == NULL )
{
DEBUG(0, ("PAM: PAM_session Malloc Failed!\n"));
@@ -350,7 +350,7 @@ BOOL pam_session(BOOL flag, const connection_struct *conn, char *tty)
}
/* This is freed by PAM */
- StrnCpy(user, conn->user, strlen(conn->user)+1);
+ StrnCpy(user, in_user, strlen(in_user)+1);
if (!proc_pam_start(&pamh, user))
{
diff --git a/source3/include/local.h b/source3/include/local.h
index f693d18623..e534f39306 100644
--- a/source3/include/local.h
+++ b/source3/include/local.h
@@ -173,4 +173,12 @@
/* Minimum length of allowed password when changing UNIX password. */
#define MINPASSWDLENGTH 5
+/* maximum ID number used for session control. This cannot be larger
+ than 62*62 for the current code */
+#define MAX_SESSION_ID 3000
+
+#ifndef SESSION_TEMPLATE
+#define SESSION_TEMPLATE "smb/%d"
+#endif
+
#endif
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 2497169677..a02349a075 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -1627,7 +1627,7 @@ char *lp_lockdir(void);
char *lp_utmpdir(void);
char *lp_wtmpdir(void);
char *lp_utmp_hostname(void);
-BOOL lp_utmp_consolidate(void);
+BOOL lp_utmp(void);
char *lp_rootdir(void);
char *lp_source_environment(void);
char *lp_defaultservice(void);
@@ -1717,7 +1717,6 @@ BOOL lp_debug_hires_timestamp(void);
BOOL lp_debug_pid(void);
BOOL lp_debug_uid(void);
BOOL lp_browse_list(void);
-BOOL lp_unix_realname(void);
BOOL lp_nis_home_map(void);
BOOL lp_bind_interfaces_only(void);
BOOL lp_unix_password_sync(void);
@@ -1824,7 +1823,6 @@ BOOL lp_map_archive(int );
BOOL lp_locking(int );
BOOL lp_strict_locking(int );
BOOL lp_posix_locking(int );
-BOOL lp_utmp(int );
BOOL lp_share_modes(int );
BOOL lp_oplocks(int );
BOOL lp_level2_oplocks(int );
@@ -1911,7 +1909,7 @@ BOOL pdb_generate_sam_sid(void);
/*The following definitions come from passdb/pampass.c */
-BOOL pam_session(BOOL flag, const connection_struct *conn, char *tty);
+BOOL pam_session(BOOL flag, const char *in_user, char *tty);
BOOL pam_accountcheck(char * user);
BOOL pam_passcheck(char * user, char * password);
@@ -4105,11 +4103,12 @@ void generate_next_challenge(char *challenge);
BOOL set_challenge(unsigned char *challenge);
user_struct *get_valid_user_struct(uint16 vuid);
void invalidate_vuid(uint16 vuid);
+void invalidate_all_vuids(void);
char *validated_username(uint16 vuid);
char *validated_domain(uint16 vuid);
NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, BOOL is_guest);
-uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name,
- char *domain,BOOL guest);
+int register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name,
+ char *domain,BOOL guest);
void add_session_user(char *user);
BOOL smb_password_check(char *password, unsigned char *part_passwd, unsigned char *c8);
BOOL smb_password_ok(SAM_ACCOUNT *sampass, uchar chal[8],
@@ -4260,6 +4259,11 @@ int find_service(char *service);
connection_struct *make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid, int *ecode);
void close_cnum(connection_struct *conn, uint16 vuid);
+/*The following definitions come from smbd/session.c */
+
+BOOL session_claim(uint16 vuid);
+void session_yield(uint16 vuid);
+
/*The following definitions come from smbd/srvstr.c */
int srvstr_push(void *outbuf, void *dest, const char *src, int dest_len, int flags);
@@ -4311,6 +4315,13 @@ DOM_SID *gid_to_sid(DOM_SID *psid, gid_t gid);
BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype);
BOOL sid_to_gid(DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype);
+/*The following definitions come from smbd/utmp.c */
+
+void sys_utmp_yield(const char *username, const char *hostname,
+ const char *id_str, int id_num);
+void sys_utmp_claim(const char *username, const char *hostname,
+ const char *id_str, int id_num);
+
/*The following definitions come from smbd/vfs-wrap.c */
int vfswrap_dummy_connect(connection_struct *conn, char *service, char *user);
diff --git a/source3/include/smb.h b/source3/include/smb.h
index eae19921f8..aa1356d821 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -1629,6 +1629,8 @@ typedef struct user_struct
gid_t *groups;
NT_USER_TOKEN *nt_user_token;
+
+ int session_id; /* used by utmp and pam session code */
} user_struct;
#include "ntdomain.h"
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index 11697b5044..c29418ee87 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -173,8 +173,8 @@ typedef struct
char *szUtmpDir;
char *szWtmpDir;
char *szUtmpHostname;
- BOOL bUtmpConsolidate;
-#endif /* WITH_UTMP */
+ BOOL bUtmp;
+#endif
char *szSourceEnv;
char *szWinbindUID;
char *szWinbindGID;
@@ -257,7 +257,6 @@ typedef struct
BOOL bReadbmpx;
BOOL bSyslogOnly;
BOOL bBrowseList;
- BOOL bUnixRealname;
BOOL bNISHomeMap;
BOOL bTimeServer;
BOOL bBindInterfacesOnly;
@@ -374,9 +373,6 @@ typedef struct
BOOL bLocking;
BOOL bStrictLocking;
BOOL bPosixLocking;
-#ifdef WITH_UTMP
- BOOL bUtmp;
-#endif
BOOL bShareModes;
BOOL bOpLocks;
BOOL bLevel2OpLocks;
@@ -490,9 +486,6 @@ static service sDefault = {
True, /* bLocking */
False, /* bStrictLocking */
True, /* bPosixLocking */
-#ifdef WITH_UTMP
- False, /* bUtmp */
-#endif
True, /* bShareModes */
True, /* bOpLocks */
True, /* bLevel2OpLocks */
@@ -942,9 +935,6 @@ static struct parm_struct parm_table[] = {
{"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, FLAG_SHARE},
{"kernel oplocks", P_BOOL, P_GLOBAL, &Globals.bKernelOplocks, NULL, NULL, FLAG_GLOBAL},
{"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
-#ifdef WITH_UTMP
- {"utmp", P_BOOL, P_LOCAL, &sDefault.bUtmp, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
-#endif
{"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
{"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
@@ -976,16 +966,13 @@ static struct parm_struct parm_table[] = {
{"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0},
{"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0},
#ifdef WITH_UTMP
- {"utmp dir", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, 0},
{"utmp directory", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, 0},
- {"wtmp dir", P_STRING, P_GLOBAL, &Globals.szWtmpDir, NULL, NULL, 0},
{"wtmp directory", P_STRING, P_GLOBAL, &Globals.szWtmpDir, NULL, NULL, 0},
{"utmp hostname", P_STRING, P_GLOBAL, &Globals.szUtmpHostname, NULL, NULL, 0},
- {"utmp consolidate", P_BOOL, P_GLOBAL, &Globals.bUtmpConsolidate, NULL, NULL, 0},
-#endif /* WITH_UTMP */
+ {"utmp", P_BOOL, P_GLOBAL, &Globals.bUtmp, NULL, NULL, 0},
+#endif
- {"default service", P_STRING, P_GLOBAL,
- &Globals.szDefaultService, NULL, NULL, 0},
+ {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, 0},
{"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, 0},
{"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, 0},
{"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL, NULL, 0},
@@ -995,7 +982,6 @@ static struct parm_struct parm_table[] = {
{"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, 0},
{"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, 0},
{"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, 0},
- {"unix realname", P_BOOL, P_GLOBAL, &Globals.bUnixRealname, NULL, NULL, 0},
{"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, 0},
{"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
@@ -1215,8 +1201,8 @@ static void init_globals(void)
string_set(&Globals.szUtmpDir, "");
string_set(&Globals.szWtmpDir, "");
string_set(&Globals.szUtmpHostname, "%m");
- Globals.bUtmpConsolidate = False;
-#endif /* WITH_UTMP */
+ Globals.bUtmp = False;
+#endif
string_set(&Globals.szSmbrun, SMBRUN);
string_set(&Globals.szSocketAddress, "0.0.0.0");
pstrcpy(s, "Samba ");
@@ -1277,7 +1263,6 @@ static void init_globals(void)
Globals.lm_interval = 60;
Globals.stat_cache_size = 50; /* Number of stat translations we'll keep */
Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
- Globals.bUnixRealname = True;
#if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
Globals.bNISHomeMap = False;
#ifdef WITH_NISPLUS_HOME
@@ -1450,8 +1435,8 @@ FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
FN_GLOBAL_STRING(lp_utmp_hostname, &Globals.szUtmpHostname)
-FN_GLOBAL_BOOL(lp_utmp_consolidate, &Globals.bUtmpConsolidate)
-#endif /* WITH_UTMP */
+FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
+#endif
FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
FN_GLOBAL_STRING(lp_source_environment, &Globals.szSourceEnv)
FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
@@ -1552,7 +1537,6 @@ FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
-FN_GLOBAL_BOOL(lp_unix_realname, &Globals.bUnixRealname)
FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
@@ -1665,9 +1649,6 @@ FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
FN_LOCAL_BOOL(lp_locking, bLocking)
FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking)
-#ifdef WITH_UTMP
-FN_LOCAL_BOOL(lp_utmp, bUtmp)
-#endif
FN_LOCAL_BOOL(lp_share_modes, bShareModes)
FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
diff --git a/source3/passdb/pampass.c b/source3/passdb/pampass.c
index 271c46045b..d9137045e2 100644
--- a/source3/passdb/pampass.c
+++ b/source3/passdb/pampass.c
@@ -337,12 +337,12 @@ static BOOL proc_pam_session(pam_handle_t *pamh, char *user, char *tty, BOOL fla
/*
* PAM Externally accessible Session handler
*/
-BOOL pam_session(BOOL flag, const connection_struct *conn, char *tty)
+BOOL pam_session(BOOL flag, const char *in_user, char *tty)
{
pam_handle_t *pamh = NULL;
char * user;
- user = malloc(strlen(conn->user)+1);
+ user = malloc(strlen(in_user)+1);
if ( user == NULL )
{
DEBUG(0, ("PAM: PAM_session Malloc Failed!\n"));
@@ -350,7 +350,7 @@ BOOL pam_session(BOOL flag, const connection_struct *conn, char *tty)
}
/* This is freed by PAM */
- StrnCpy(user, conn->user, strlen(conn->user)+1);
+ StrnCpy(user, in_user, strlen(in_user)+1);
if (!proc_pam_start(&pamh, user))
{
diff --git a/source3/passdb/pdb_smbpasswd.c b/source3/passdb/pdb_smbpasswd.c
index 2449eec1f0..a814c8da8e 100644
--- a/source3/passdb/pdb_smbpasswd.c
+++ b/source3/passdb/pdb_smbpasswd.c
@@ -1285,11 +1285,7 @@ static BOOL build_sam_account (SAM_ACCOUNT *sam_pass,
standard_sub_advanced(-1, pw_buf->smb_name, "", gid, str);
pdb_set_homedir(sam_pass, str);
- if (lp_unix_realname())
- pdb_set_fullname(sam_pass, pwfile->pw_gecos);
- else
- pdb_set_fullname(sam_pass, "<Full Name>");
-
+ pdb_set_fullname(sam_pass, pwfile->pw_gecos);
/* set other user information that we have */
pdb_set_group_rid (sam_pass, pdb_gid_to_group_rid(pdb_get_gid(&global_sam_pass)) );
diff --git a/source3/smbd/connection.c b/source3/smbd/connection.c
index 125b2fbbe5..43e89abfbf 100644
--- a/source3/smbd/connection.c
+++ b/source3/smbd/connection.c
@@ -27,11 +27,6 @@ static TDB_CONTEXT *tdb;
extern int DEBUGLEVEL;
-#ifdef WITH_UTMP
-static void utmp_yield(pid_t pid, const connection_struct *conn);
-static void utmp_claim(const struct connections_data *crec, const connection_struct *conn);
-#endif
-
/****************************************************************************
Return the connection tdb context (used for message send all).
****************************************************************************/
@@ -64,11 +59,6 @@ BOOL yield_connection(connection_struct *conn,char *name,int max_connections)
tdb_delete(tdb, kbuf);
-#ifdef WITH_UTMP
- if(conn)
- utmp_yield(key.pid, conn);
-#endif
-
return(True);
}
@@ -120,769 +110,6 @@ BOOL claim_connection(connection_struct *conn,char *name,int max_connections,BOO
if (tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) != 0) return False;
-#ifdef WITH_UTMP
- if (conn)
- utmp_claim(&crec, conn);
-#endif
-
return True;
}
-#ifdef WITH_UTMP
-
-/****************************************************************************
-Reflect connection status in utmp/wtmp files.
- T.D.Lee@durham.ac.uk September 1999
-
- With grateful thanks since then to many who have helped port it to
- different operating systems. The variety of OS quirks thereby
- uncovered is amazing...
-
-Hints for porting:
- o Always attempt to use programmatic interface (pututline() etc.)
- Indeed, at present only programmatic use is supported.
- o The only currently supported programmatic interface to "wtmp{,x}"
- is through "updwtmp*()" routines.
- o The "x" (utmpx/wtmpx; HAVE_UTMPX_H) seems preferable.
- o The HAVE_* items should identify supported features.
- o If at all possible, avoid "if defined(MY-OS)" constructions.
-
-OS observations and status:
- Almost every OS seems to have its own quirks.
-
- Solaris 2.x:
- Tested on 2.6 and 2.7; should be OK on other flavours.
- AIX:
- Apparently has utmpx.h but doesn't implement.
- OSF:
- Has utmpx.h, but (e.g.) no "getutmpx()". (Is this like AIX ?)
- Redhat 6:
- utmpx.h seems not to set default filenames. non-x better.
- IRIX 6.5:
- Not tested. Appears to have "x".
- HP-UX 9.x:
- Not tested. Appears to lack "x".
- HP-UX 10.x:
- Not tested.
- "updwtmp*()" routines seem absent, so no current wtmp* support.
- Has "ut_addr": probably trivial to implement (although remember
- that IPv6 is coming...).
-
- FreeBSD:
- No "putut*()" type of interface.
- No "ut_type" and associated defines.
- Write files directly. Alternatively use its login(3)/logout(3).
- SunOS 4:
- Not tested. Resembles FreeBSD, but no login()/logout().
-
-lastlog:
- Should "lastlog" files, if any, be updated?
- BSD systems (SunOS 4, FreeBSD):
- o Prominent mention on man pages.
- System-V (e.g. Solaris 2):
- o No mention on man pages, even under "man -k".
- o Has a "/var/adm/lastlog" file, but pututxline() etc. seem
- not to touch it.
- o Despite downplaying (above), nevertheless has <lastlog.h>.
- So perhaps UN*X "lastlog" facility is intended for tty/terminal only?
-
-Notes:
- Each connection requires a small number (starting at 0, working up)
- to represent the line (unum). This must be unique within and across
- all smbd processes.
-
- The 4 byte 'ut_id' component is vital to distinguish connections,
- of which there could be several hundered or even thousand.
- Entries seem to be printable characters, with optional NULL pads.
-
- We need to be distinct from other entries in utmp/wtmp.
-
- Observed things: therefore avoid them. Add to this list please.
- From Solaris 2.x (because that's what I have):
- 'sN' : run-levels; N: [0-9]
- 'co' : console
- 'CC' : arbitrary things; C: [a-z]
- 'rXNN' : rlogin; N: [0-9]; X: [0-9a-z]
- 'tXNN' : rlogin; N: [0-9]; X: [0-9a-z]
- '/NNN' : Solaris CDE
- 'ftpZ' : ftp (Z is the number 255, aka 0377, aka 0xff)
- Mostly a record uses the same 'ut_id' in both "utmp" and "wtmp",
- but differences have been seen.
-
- Arbitrarily I have chosen to use a distinctive 'SM' for the
- first two bytes.
-
- The remaining two encode the "unum" (see above).
-
- For "utmp consolidate" the suggestion was made to encode the pid into
- those remaining two bytes (16 bits). But recent UNIX (e.g Solaris 8)
- is migrating to pids > 16 bits, so we ought not to do this.
-
-****************************************************************************/
-
-#include <utmp.h>
-
-#ifdef HAVE_UTMPX_H
-#include <utmpx.h>
-#endif
-
-/* BSD systems: some may need lastlog.h (SunOS 4), some may not (FreeBSD) */
-/* Some System-V systems (e.g. Solaris 2) declare this too. */
-#ifdef HAVE_LASTLOG_H
-#include <lastlog.h>
-#endif
-
-/****************************************************************************
-obtain/release a small number (0 upwards) unique within and across smbds
-****************************************************************************/
-/*
- * Need a "small" number to represent this connection, unique within this
- * smbd and across all smbds.
- *
- * claim:
- * Start at 0, hunt up for free, unique number "unum" by attempting to
- * store it as a key in a tdb database:
- * key: unum data: pid+conn
- * Also store its inverse, ready for yield function:
- * key: pid+conn data: unum
- *
- * yield:
- * Find key: pid+conn; data is unum; delete record
- * Find key: unum ; delete record.
- *
- * Comment:
- * The claim algorithm (a "for" loop attempting to store numbers in a tdb
- * database) will be increasingly inefficient with larger numbers of
- * connections. Is it possible to write a suitable primitive within tdb?
- *
- * However, by also storing the inverse key/data pair, we at least make
- * the yield algorithm efficient.
- */
-
-static TDB_CONTEXT *tdb_utmp;
-
-struct utmp_tdb_data {
- pid_t pid;
- int cnum;
-};
-
-static int utmp_claim_tdb(const connection_struct *conn)
-{
- struct utmp_tdb_data udata;
- int i, slotnum;
- TDB_DATA kbuf, dbuf;
-
- if (!tdb_utmp) {
- tdb_utmp = tdb_open(lock_path("utmp.tdb"), 0,
- TDB_CLEAR_IF_FIRST, O_RDWR | O_CREAT, 0644);
- }
- if (!tdb_utmp) return(-1);
-
- DEBUG(2,("utmp_claim_tdb: entered\n"));
-
- ZERO_STRUCT(udata);
- udata.pid = sys_getpid();
- udata.cnum = conn ? conn->cnum : -1;
-
- dbuf.dptr = (char *) &udata;
- dbuf.dsize = sizeof(udata);
-
- /* The key is simply a number as close as possible to zero: find it */
- slotnum = -1;
- /* stop loop when overflow +ve integers (a huge, busy machine!) */
- for (i = 0; i >= 0 ; i++) {
- kbuf.dptr = (char *) &i;
- kbuf.dsize = sizeof(i);
-
- if (tdb_store(tdb_utmp, kbuf, dbuf, TDB_INSERT) == 0) {
- /* have successfully grabbed a free slot */
- slotnum = i;
-
- /* store the inverse for faster utmp_yield_tdb() */
- tdb_store(tdb_utmp, dbuf, kbuf, TDB_INSERT);
-
- break; /* Got it; escape */
- }
- }
- if (slotnum < 0) { /* more connections than positive integers! */
- DEBUG(2,("utmp_claim_tdb: failed\n"));
- return(-1);
- }
-
- DEBUG(2,("utmp_claim_tdb: leaving with %d\n", slotnum));
-
- return(slotnum);
-}
-
-static int utmp_yield_tdb(const connection_struct *conn)
-{
- struct utmp_tdb_data revkey;
- int i, slotnum;
- TDB_DATA kbuf, dbuf;
-
- if (!tdb_utmp) {
- return(-1);
- }
-
- DEBUG(2,("utmp_yield_tdb: entered\n"));
-
- ZERO_STRUCT(revkey);
- revkey.pid = sys_getpid();
- revkey.cnum = conn ? conn->cnum : -1;
-
- kbuf.dptr = (char *) &revkey;
- kbuf.dsize = sizeof(revkey);
-
- dbuf = tdb_fetch(tdb_utmp, kbuf);
- if (dbuf.dptr == NULL) {
- DEBUG(2,("utmp_yield_tdb: failed\n"));
- return(-1); /* shouldn't happen */
- }
-
- /* Save our result */
- slotnum = (int) dbuf.dptr;
-
- /* Tidy up */
- tdb_delete(tdb_utmp, kbuf);
- tdb_delete(tdb_utmp, dbuf);
-
- free(dbuf.dptr);
- DEBUG(2,("utmp_yield_tdb: leaving with %d\n", slotnum));
-
- return(slotnum);
-}
-
-#if defined(HAVE_UT_UT_ID)
-/****************************************************************************
-encode the unique connection number into "ut_id"
-****************************************************************************/
-static const char *ut_id_encstr =
- "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
-
-static
-int
-ut_id_encode(int i, char *fourbyte)
-{
- int nbase;
-
- fourbyte[0] = 'S';
- fourbyte[1] = 'M';
-
-/*
- * Encode remaining 2 bytes from 'i'.
- * 'ut_id_encstr' is the character set on which modulo arithmetic is done.
- * Example: digits would produce the base-10 numbers from '001'.
- */
- nbase = strlen(ut_id_encstr);
-
- fourbyte[3] = ut_id_encstr[i % nbase];
- i /= nbase;
- fourbyte[2] = ut_id_encstr[i % nbase];
- i /= nbase;
-
- return(i); /* 0: good; else overflow */
-}
-#endif /* defined(HAVE_UT_UT_ID) */
-
-/*
- * ut_line:
- * size small, e.g. Solaris: 12; FreeBSD: 8
- * pattern conventions differ across systems.
- * So take care in tweaking the template below.
- * Arguably, this could be yet another smb.conf parameter.
- */
-static const char *ut_line_template =
-#if defined(__FreeBSD__)
- "smb%d" ;
-#else
- "smb/%d" ;
-#endif
-
-/****************************************************************************
-Fill in a utmp (not utmpx) template
-****************************************************************************/
-static int utmp_fill(struct utmp *u, const connection_struct *conn, pid_t pid,
- int i, pstring host)
-{
-#if defined(HAVE_UT_UT_TIME)
- struct timeval timeval;
-#endif /* defined(HAVE_UT_UT_TIME) */
- char line_tmp[1024]; /* plenty big enough for slprintf() */
- int line_len;
- int rc = 0;
-
-/*
- * ut_name, ut_user:
- * Several (all?) systems seems to define one as the other.
- * It is easier and clearer simply to let the following take its course,
- * rather than to try to detect and optimise.
- */
-#if defined(HAVE_UT_UT_USER)
- pstrcpy(u->ut_user, conn->user);
-#endif /* defined(HAVE_UT_UT_USER) */
-
-#if defined(HAVE_UT_UT_NAME)
- pstrcpy(u->ut_name, conn->user);
-#endif /* defined(HAVE_UT_UT_NAME) */
-
-/*
- * ut_line:
- * If size limit proves troublesome, then perhaps use "ut_id_encode()".
- *
- * Temporary variable "line_tmp" avoids trouble:
- * o with unwanted trailing NULL if ut_line full;
- * o with overflow if ut_line would be more than full.
- */
- memset(line_tmp, '\0', sizeof(line_tmp));
- slprintf(line_tmp, sizeof(line_tmp)-1, (char *) ut_line_template, i);
- line_len = strlen(line_tmp);
- if (line_len <= sizeof(u->ut_line)) {
- memcpy(u->ut_line, line_tmp, sizeof(u->ut_line));
- }
- else {
- DEBUG(1,("utmp_fill: ut_line exceeds field length(%d > %d)\n",
- line_len, sizeof(u->ut_line)));
- return(1);
- }
-
-#if defined(HAVE_UT_UT_PID)
- u->ut_pid = pid;
-#endif /* defined(HAVE_UT_UT_PID) */
-
-/*
- * ut_time, ut_tv:
- * Some have one, some the other. Many have both, but defined (aliased).
- * It is easier and clearer simply to let the following take its course.
- * But note that we do the more precise ut_tv as the final assignment.
- */
-#if defined(HAVE_UT_UT_TIME)
- gettimeofday(&timeval, NULL);
- u->ut_time = timeval.tv_sec;
-#endif /* defined(HAVE_UT_UT_TIME) */
-
-#if defined(HAVE_UT_UT_TV)
- gettimeofday(&timeval, NULL);
- u->ut_tv = timeval;
-#endif /* defined(HAVE_UT_UT_TV) */
-
-#if defined(HAVE_UT_UT_HOST)
- if (host) {
- pstrcpy(u->ut_host, host);
- }
-#endif /* defined(HAVE_UT_UT_HOST) */
-
-#if defined(HAVE_UT_UT_ADDR)
- /*
- * "(unsigned long) ut_addr" apparently exists on at least HP-UX 10.20.
- * Volunteer to implement, please ...
- */
-#endif /* defined(HAVE_UT_UT_ADDR) */
-
-#if defined(HAVE_UT_UT_ID)
- rc = ut_id_encode(i, u->ut_id);
-#endif /* defined(HAVE_UT_UT_ID) */
-
- return(rc);
-}
-
-/****************************************************************************
-Default paths to various {u,w}tmp{,x} files
-****************************************************************************/
-#ifdef HAVE_UTMPX_H
-
-static const char *ux_pathname =
-# if defined (UTMPX_FILE)
- UTMPX_FILE ;
-# elif defined (_UTMPX_FILE)
- _UTMPX_FILE ;
-# elif defined (_PATH_UTMPX)
- _PATH_UTMPX ;
-# else
- "" ;
-# endif
-
-static const char *wx_pathname =
-# if defined (WTMPX_FILE)
- WTMPX_FILE ;
-# elif defined (_WTMPX_FILE)
- _WTMPX_FILE ;
-# elif defined (_PATH_WTMPX)
- _PATH_WTMPX ;
-# else
- "" ;
-# endif
-
-#endif /* HAVE_UTMPX_H */
-
-static const char *ut_pathname =
-# if defined (UTMP_FILE)
- UTMP_FILE ;
-# elif defined (_UTMP_FILE)
- _UTMP_FILE ;
-# elif defined (_PATH_UTMP)
- _PATH_UTMP ;
-# else
- "" ;
-# endif
-
-static const char *wt_pathname =
-# if defined (WTMP_FILE)
- WTMP_FILE ;
-# elif defined (_WTMP_FILE)
- _WTMP_FILE ;
-# elif defined (_PATH_WTMP)
- _PATH_WTMP ;
-# else
- "" ;
-# endif
-
-/* BSD-like systems might want "lastlog" support. */
-/* *** Not yet implemented */
-#ifndef HAVE_PUTUTLINE /* see "pututline_my()" */
-static const char *ll_pathname =
-# if defined (_PATH_LASTLOG) /* what other names (if any?) */
- _PATH_LASTLOG ;
-# else
- "" ;
-# endif /* _PATH_LASTLOG */
-#endif /* HAVE_PUTUTLINE */
-
-/*
- * Get name of {u,w}tmp{,x} file.
- * return: fname contains filename
- * Possibly empty if this code not yet ported to this system.
- *
- * utmp{,x}: try "utmp dir", then default (a define)
- * wtmp{,x}: try "wtmp dir", then "utmp dir", then default (a define)
- */
-static void uw_pathname(pstring fname, const char *uw_name, const char *uw_default)
-{
- pstring dirname;
-
- pstrcpy(dirname, "");
-
- /* For w-files, first look for explicit "wtmp dir" */
- if (uw_name[0] == 'w') {
- pstrcpy(dirname,lp_wtmpdir());
- trim_string(dirname,"","/");
- }
-
- /* For u-files and non-explicit w-dir, look for "utmp dir" */
- if (dirname == 0 || strlen(dirname) == 0) {
- pstrcpy(dirname,lp_utmpdir());
- trim_string(dirname,"","/");
- }
-
- /* If explicit directory above, use it */
- if (dirname != 0 && strlen(dirname) != 0) {
- pstrcpy(fname, dirname);
- pstrcat(fname, "/");
- pstrcat(fname, uw_name);
- return;
- }
-
- /* No explicit directory: attempt to use default paths */
- if (strlen(uw_default) == 0) {
- /* No explicit setting, no known default.
- * Has it yet been ported to this OS?
- */
- DEBUG(2,("uw_pathname: unable to determine pathname\n"));
- }
- pstrcpy(fname, uw_default);
-}
-
-#ifndef HAVE_PUTUTLINE
-/****************************************************************************
-Update utmp file directly. No subroutine interface: probably a BSD system.
-****************************************************************************/
-static void pututline_my(pstring uname, struct utmp *u, BOOL claim)
-{
- DEBUG(1,("pututline_my: not yet implemented\n"));
- /* BSD implementor: may want to consider (or not) adjusting "lastlog" */
-}
-#endif /* HAVE_PUTUTLINE */
-
-#ifndef HAVE_UPDWTMP
-/****************************************************************************
-Update wtmp file directly. No subroutine interface: probably a BSD system.
-Credit: Michail Vidiassov <master@iaas.msu.ru>
-****************************************************************************/
-static void updwtmp_my(pstring wname, struct utmp *u, BOOL claim)
-{
- int fd;
- struct stat buf;
-
- if (! claim) {
- /*
- * BSD-like systems:
- * may use empty ut_name to distinguish a logout record.
- *
- * May need "if defined(SUNOS4)" etc. around some of these,
- * but try to avoid if possible.
- *
- * SunOS 4:
- * man page indicates ut_name and ut_host both NULL
- * FreeBSD 4.0:
- * man page appears not to specify (hints non-NULL)
- * A correspondent suggest at least ut_name should be NULL
- */
- memset((char *)&(u->ut_name), '\0', sizeof(u->ut_name));
- memset((char *)&(u->ut_host), '\0', sizeof(u->ut_host));
- }
- /* Stolen from logwtmp function in libutil.
- * May be more locking/blocking is needed?
- */
- if ((fd = open(wname, O_WRONLY|O_APPEND, 0)) < 0)
- return;
- if (fstat(fd, &buf) == 0) {
- if (write(fd, (char *)u, sizeof(struct utmp)) != sizeof(struct utmp))
- (void) ftruncate(fd, buf.st_size);
- }
- (void) close(fd);
-}
-#endif /* HAVE_UPDWTMP */
-
-/****************************************************************************
-Update via utmp/wtmp (not utmpx/wtmpx)
-****************************************************************************/
-static void utmp_nox_update(struct utmp *u, pstring host, BOOL claim)
-{
- pstring uname, wname;
-#if defined(PUTUTLINE_RETURNS_UTMP)
- struct utmp *urc;
-#endif /* PUTUTLINE_RETURNS_UTMP */
-
- uw_pathname(uname, "utmp", ut_pathname);
- DEBUG(2,("utmp_nox_update: uname:%s\n", uname));
-
-#ifdef HAVE_PUTUTLINE
- if (strlen(uname) != 0) {
- utmpname(uname);
- }
-
-# if defined(PUTUTLINE_RETURNS_UTMP)
- setutent();
- urc = pututline(u);
- endutent();
- if (urc == NULL) {
- DEBUG(2,("utmp_nox_update: pututline() failed\n"));
- return;
- }
-# else /* PUTUTLINE_RETURNS_UTMP */
- setutent();
- pututline(u);
- endutent();
-# endif /* PUTUTLINE_RETURNS_UTMP */
-
-#else /* HAVE_PUTUTLINE */
- if (strlen(uname) != 0) {
- pututline_my(uname, u, claim);
- }
-#endif /* HAVE_PUTUTLINE */
-
- uw_pathname(wname, "wtmp", wt_pathname);
- DEBUG(2,("utmp_nox_update: wname:%s\n", wname));
- if (strlen(wname) != 0) {
-#ifdef HAVE_UPDWTMP
- updwtmp(wname, u);
- /*
- * updwtmp() and the newer updwtmpx() may be unsymmetrical.
- * At least one OS, Solaris 2.x declares the former in the
- * "utmpx" (latter) file and context.
- * In the Solaris case this is irrelevant: it has both and
- * we always prefer the "x" case, so doesn't come here.
- * But are there other systems, with no "x", which lack
- * updwtmp() perhaps?
- */
-#else
- updwtmp_my(wname, u, claim);
-#endif /* HAVE_UPDWTMP */
- }
-}
-
-/****************************************************************************
-Update via utmpx/wtmpx (preferred) or via utmp/wtmp
-****************************************************************************/
-static void utmp_update(struct utmp *u, pstring host, BOOL claim)
-{
-#if !defined(HAVE_UTMPX_H)
- /* No utmpx stuff. Drop to non-x stuff */
- utmp_nox_update(u, host, claim);
-#elif !defined(HAVE_PUTUTXLINE)
- /* Odd. Have utmpx.h but no "pututxline()". Drop to non-x stuff */
- DEBUG(1,("utmp_update: have utmpx.h but no pututxline() function\n"));
- utmp_nox_update(u, host, claim);
-#elif !defined(HAVE_GETUTMPX)
- /* Odd. Have utmpx.h but no "getutmpx()". Drop to non-x stuff */
- DEBUG(1,("utmp_update: have utmpx.h but no getutmpx() function\n"));
- utmp_nox_update(u, host, claim);
-#else
- pstring uname, wname;
- struct utmpx ux, *uxrc;
-
- getutmpx(u, &ux);
- if (host) {
-#if defined(HAVE_UX_UT_SYSLEN)
- ux.ut_syslen = strlen(host) + 1; /* include end NULL */
-#endif /* defined(HAVE_UX_UT_SYSLEN) */
- pstrcpy(ux.ut_host, host);
- }
-
- uw_pathname(uname, "utmpx", ux_pathname);
- uw_pathname(wname, "wtmpx", wx_pathname);
- DEBUG(2,("utmp_update: uname:%s wname:%s\n", uname, wname));
- /*
- * Check for either uname or wname being empty.
- * Some systems, such as Redhat 6, have a "utmpx.h" which doesn't
- * define default filenames.
- * Also, our local installation has not provided an override.
- * Drop to non-x method. (E.g. RH6 has good defaults in "utmp.h".)
- */
- if ((strlen(uname) == 0) || (strlen(wname) == 0)) {
- utmp_nox_update(u, host, claim);
- }
- else {
- utmpxname(uname);
- setutxent();
- uxrc = pututxline(&ux);
- endutxent();
- if (uxrc == NULL) {
- DEBUG(2,("utmp_update: pututxline() failed\n"));
- return;
- }
-#ifdef HAVE_UPDWTMPX
- updwtmpx(wname, &ux);
-#else
- /* Have utmpx.h but no "updwtmpx()". */
- DEBUG(1,("utmp_update: no updwtmpx() function\n"));
-#endif /* HAVE_UPDWTMPX */
- }
-#endif /* HAVE_UTMPX_H */
-}
-
-/*
- * "utmp consolidate": some background:
- * False (default):
- * In "utmp" files note every connection via this process.
- * Argument "i" is simply a tty-like number we can use as-is.
- * True:
- * In "utmp" files, only note first open and final close. Keep:
- * o count of open processes;
- * o record value of first "i", to use as "i" in final close.
- */
-static int utmp_count = 0;
-static int utmp_consolidate_conn_num;
-
-/****************************************************************************
-close a connection
-****************************************************************************/
-static void utmp_yield(pid_t pid, const connection_struct *conn)
-{
- struct utmp u;
- int conn_num, i;
-
- if (! lp_utmp(SNUM(conn))) {
- DEBUG(2,("utmp_yield: lp_utmp() NULL\n"));
- return;
- }
-
- i = utmp_yield_tdb(conn);
- if (i < 0) {
- DEBUG(2,("utmp_yield: utmp_yield_tdb() failed\n"));
- return;
- }
- conn_num = i;
- DEBUG(2,("utmp_yield: conn: user:%s cnum:%d i:%d (utmp_count:%d)\n",
- conn->user, conn->cnum, i, utmp_count));
-
- utmp_count -= 1;
- if (lp_utmp_consolidate()) {
- if (utmp_count > 0) {
- DEBUG(2,("utmp_yield: utmp consolidate: %d entries still open\n", utmp_count));
- return;
- }
- else {
- /* consolidate; final close: override conn_num */
- conn_num = utmp_consolidate_conn_num;
- }
- }
-
- memset((char *)&u, '\0', sizeof(struct utmp));
-
-#if defined(HAVE_UT_UT_EXIT)
- u.ut_exit.e_termination = 0;
- u.ut_exit.e_exit = 0;
-#endif /* defined(HAVE_UT_UT_EXIT) */
-
-#if defined(HAVE_UT_UT_TYPE)
- u.ut_type = DEAD_PROCESS;
-#endif /* defined(HAVE_UT_UT_TYPE) */
-
- if (utmp_fill(&u, conn, pid, conn_num, NULL) == 0) {
- utmp_update(&u, NULL, False);
- }
-}
-
-/****************************************************************************
-open a connection
-****************************************************************************/
-static void utmp_claim(const struct connections_data *crec, const connection_struct *conn)
-{
- struct utmp u;
- pstring host;
- int i;
-
- if (conn == NULL) {
- DEBUG(2,("utmp_claim: conn NULL\n"));
- return;
- }
-
- if (! lp_utmp(SNUM(conn))) {
- DEBUG(2,("utmp_claim: lp_utmp() NULL\n"));
- return;
- }
-
- i = utmp_claim_tdb(conn);
- if (i < 0) {
- DEBUG(2,("utmp_claim: utmp_claim_tdb() failed\n"));
- return;
- }
-
- pstrcpy(host, lp_utmp_hostname());
- if (host == 0 || strlen(host) == 0) {
- pstrcpy(host, crec->machine);
- }
- else {
- /* explicit "utmp host": expand for any "%" variables */
- standard_sub_basic(host);
- }
-
- DEBUG(2,("utmp_claim: conn: user:%s cnum:%d i:%d (utmp_count:%d)\n",
- conn->user, conn->cnum, i, utmp_count));
- DEBUG(2,("utmp_claim: crec: pid:%d, cnum:%d name:%s addr:%s mach:%s DNS:%s host:%s\n",
- crec->pid, crec->cnum, crec->name, crec->addr, crec->machine, client_name(), host));
-
- utmp_count += 1;
- if (lp_utmp_consolidate()) {
- if (utmp_count > 1) {
- DEBUG(2,("utmp_claim: utmp consolidate: %d entries already open\n", (utmp_count-1)));
- return;
- }
- else {
- /* consolidate; first open: keep record of "i" */
- utmp_consolidate_conn_num = i;
- }
- }
-
- memset((char *)&u, '\0', sizeof(struct utmp));
-
-#if defined(HAVE_UT_UT_TYPE)
- u.ut_type = USER_PROCESS;
-#endif /* defined(HAVE_UT_UT_TYPE) */
-
- if (utmp_fill(&u, conn, crec->pid, i, host) == 0) {
- utmp_update(&u, host, True);
- }
-}
-
-#endif /* WITH_UTMP */
diff --git a/source3/smbd/password.c b/source3/smbd/password.c
index fa973dd720..6c0fe79845 100644
--- a/source3/smbd/password.c
+++ b/source3/smbd/password.c
@@ -110,8 +110,9 @@ user_struct *get_valid_user_struct(uint16 vuid)
for (usp=validated_users;usp;usp=usp->next,count++) {
if (vuid == usp->vuid) {
- if (count > 10)
- DLIST_PROMOTE(validated_users, usp);
+ if (count > 10) {
+ DLIST_PROMOTE(validated_users, usp);
+ }
return usp;
}
}
@@ -129,6 +130,8 @@ void invalidate_vuid(uint16 vuid)
if (vuser == NULL)
return;
+ session_yield(vuid);
+
DLIST_REMOVE(validated_users, vuser);
safe_free(vuser->groups);
@@ -138,6 +141,20 @@ void invalidate_vuid(uint16 vuid)
}
/****************************************************************************
+invalidate all vuid entries for this process
+****************************************************************************/
+void invalidate_all_vuids(void)
+{
+ user_struct *usp, *next=NULL;
+
+ for (usp=validated_users;usp;usp=next) {
+ next = usp->next;
+
+ invalidate_vuid(usp->vuid);
+ }
+}
+
+/****************************************************************************
return a validated username
****************************************************************************/
char *validated_username(uint16 vuid)
@@ -244,8 +261,8 @@ has been given. vuid is biased by an offset. This allows us to
tell random client vuid's (normally zero) from valid vuids.
****************************************************************************/
-uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name,
- char *domain,BOOL guest)
+int register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name,
+ char *domain,BOOL guest)
{
user_struct *vuser = NULL;
struct passwd *pwfile; /* for getting real name from passwd file */
@@ -305,12 +322,15 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name,
DEBUG(3,("uid %d registered to name %s\n",(int)uid,unix_name));
DEBUG(3, ("Clearing default real name\n"));
- fstrcpy(vuser->user.full_name, "<Full Name>");
- if (lp_unix_realname()) {
- if ((pwfile=sys_getpwnam(vuser->user.unix_name))!= NULL) {
- DEBUG(3, ("User name: %s\tReal name: %s\n",vuser->user.unix_name,pwfile->pw_gecos));
- fstrcpy(vuser->user.full_name, pwfile->pw_gecos);
- }
+ if ((pwfile=sys_getpwnam(vuser->user.unix_name))!= NULL) {
+ DEBUG(3, ("User name: %s\tReal name: %s\n",vuser->user.unix_name,pwfile->pw_gecos));
+ fstrcpy(vuser->user.full_name, pwfile->pw_gecos);
+ }
+
+ if (!session_claim(vuser->vuid)) {
+ DEBUG(1,("Failed to claim session for vuid=%d\n", vuser->vuid));
+ invalidate_vuid(vuser->vuid);
+ return -1;
}
return vuser->vuid;
@@ -737,6 +757,13 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen,
BOOL *guest,BOOL *force,uint16 vuid)
{
BOOL ok = False;
+ user_struct *vuser = get_valid_user_struct(vuid);
+
+ if (lp_security() > SEC_SHARE && !vuser) {
+ DEBUG(1,("authorise_login: refusing user %s with no session setup\n",
+ user));
+ return False;
+ }
*guest = False;
@@ -760,9 +787,6 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen,
if (!(GUEST_ONLY(snum) && GUEST_OK(snum)))
{
-
- user_struct *vuser = get_valid_user_struct(vuid);
-
/* check the given username and password */
if (!ok && (*user) && user_ok(user,snum)) {
ok = password_ok(user,password, pwlen, NULL);
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 82ac230764..15e8e9537e 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -671,7 +671,7 @@ reply to a session setup command
int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
{
- uint16 sess_vuid;
+ int sess_vuid;
gid_t gid;
uid_t uid;
int smb_bufsize;
@@ -1037,6 +1037,11 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
to a uid can get through without a password, on the same VC */
sess_vuid = register_vuid(uid,gid,user,current_user_info.smb_name,domain,guest);
+
+ if (sess_vuid == -1) {
+ return(ERROR(ERRDOS,ERRnoaccess));
+ }
+
SSVAL(outbuf,smb_uid,sess_vuid);
SSVAL(inbuf,smb_uid,sess_vuid);
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index 84b7109294..d2a9a64966 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -441,12 +441,14 @@ void exit_server(char *reason)
conn_close_all();
+ invalidate_all_vuids();
+
/* delete our entry in the connections database. */
if (lp_status(-1)) {
yield_connection(NULL,"",MAXSTATUS);
}
- respond_to_all_remaining_local_messages();
+ respond_to_all_remaining_local_messages();
decrement_smbd_process_count();
#ifdef WITH_DFS
diff --git a/source3/tdb/tdbutil.c b/source3/tdb/tdbutil.c
index 95c90efeed..c387644efc 100644
--- a/source3/tdb/tdbutil.c
+++ b/source3/tdb/tdbutil.c
@@ -207,6 +207,7 @@ size_t tdb_pack(char *buf, int bufsize, char *fmt, ...)
/* useful pair of routines for packing/unpacking data consisting of
integers and strings */
+
int tdb_unpack(char *buf, int bufsize, char *fmt, ...)
{
va_list ap;