mirror of
https://github.com/samba-team/samba.git
synced 2025-12-21 20:23:50 +03:00
@@ -5,4 +5,4 @@ The Samba Consultants List
|
||||
==========================
|
||||
|
||||
This list has now moved to the support page of the
|
||||
Samba web pages at http://samba.org.au/samba/
|
||||
Samba web pages at http://samba.org/samba/
|
||||
|
||||
@@ -762,6 +762,10 @@ it() link(bf(username level))(usernamelevel)
|
||||
|
||||
it() link(bf(username map))(usernamemap)
|
||||
|
||||
it() link(bf(utmp))(utmp)
|
||||
|
||||
it() link(bf(utmp directory))(utmpdirectory)
|
||||
|
||||
it() link(bf(valid chars))(validchars)
|
||||
|
||||
it() link(bf(wins proxy))(winsproxy)
|
||||
@@ -6357,6 +6361,39 @@ tt( no username map)
|
||||
bf(Example:)
|
||||
tt( username map = /usr/local/samba/lib/users.map)
|
||||
|
||||
label(utmp)
|
||||
dit(bf(utmp (G)))
|
||||
|
||||
This boolean parameter is only available if Samba has been configured and compiled
|
||||
with the option tt(--with-utmp). If set to True then Samba will attempt
|
||||
to add utmp or utmpx records (depending on the UNIX system) whenever a
|
||||
connection is made to a Samba server. Sites may use this to record the
|
||||
user connecting to a Samba share.
|
||||
|
||||
See also the link(bf("utmp directory"))(utmpdirectory) parameter.
|
||||
|
||||
bf(Default:)
|
||||
tt(utmp = False)
|
||||
|
||||
bf(Example:)
|
||||
tt(utmp = True)
|
||||
|
||||
label(utmpdirectory)
|
||||
dit(bf(utmp directory(G)))
|
||||
|
||||
This parameter is only available if Samba has been configured and compiled
|
||||
with the option tt(--with-utmp). It specifies a directory pathname that is
|
||||
used to store the utmp or utmpx files (depending on the UNIX system) that
|
||||
record user connections to a Samba server. See also the link(bf("utmp"))(utmp)
|
||||
parameter. By default this is not set, meaning the system will use whatever
|
||||
utmp file the native system is set to use (usually /var/run/utmp on Linux).
|
||||
|
||||
bf(Default:)
|
||||
tt(no utmp directory)
|
||||
|
||||
bf(Example:)
|
||||
tt(utmp directory = /var/adm/)
|
||||
|
||||
label(validchars)
|
||||
dit(bf(valid chars (G)))
|
||||
|
||||
|
||||
@@ -74,6 +74,7 @@
|
||||
#undef HAVE_SETRESUID_DECL
|
||||
#undef HAVE_SETRESUID
|
||||
#undef WITH_NETATALK
|
||||
#undef WITH_UTMP
|
||||
#undef HAVE_INO64_T
|
||||
#undef HAVE_STRUCT_FLOCK64
|
||||
#undef SIZEOF_INO_T
|
||||
|
||||
1221
source/configure
vendored
1221
source/configure
vendored
File diff suppressed because it is too large
Load Diff
@@ -198,6 +198,9 @@ AC_CHECK_HEADERS(stropts.h poll.h readline.h history.h readline/readline.h)
|
||||
AC_CHECK_HEADERS(readline/history.h sys/capability.h syscall.h sys/syscall.h)
|
||||
AC_CHECK_HEADERS(sys/acl.h sys/cdefs.h glob.h)
|
||||
|
||||
# For experimental utmp support
|
||||
AC_CHECK_HEADERS(utmp.h utmpx.h)
|
||||
|
||||
AC_CHECK_SIZEOF(int,cross)
|
||||
AC_CHECK_SIZEOF(long,cross)
|
||||
AC_CHECK_SIZEOF(short,cross)
|
||||
@@ -1385,6 +1388,25 @@ AC_ARG_WITH(quotas,
|
||||
)
|
||||
AC_SUBST(QUOTAOBJS)
|
||||
|
||||
#################################################
|
||||
# check for experimental utmp accounting
|
||||
|
||||
AC_MSG_CHECKING(whether to support utmp accounting)
|
||||
AC_ARG_WITH(utmp,
|
||||
[ --with-utmp Include experimental utmp accounting
|
||||
--without-utmp Don't include experimental utmp accounting (default)],
|
||||
[ case "$withval" in
|
||||
yes)
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(WITH_UTMP)
|
||||
;;
|
||||
*)
|
||||
AC_MSG_RESULT(no)
|
||||
;;
|
||||
esac ],
|
||||
AC_MSG_RESULT(no)
|
||||
)
|
||||
|
||||
#################################################
|
||||
# set private directory location
|
||||
AC_ARG_WITH(privatedir,
|
||||
|
||||
@@ -140,6 +140,7 @@
|
||||
#undef HAVE_SETRESUID_DECL
|
||||
#undef HAVE_SETRESUID
|
||||
#undef WITH_NETATALK
|
||||
#undef WITH_UTMP
|
||||
#undef HAVE_INO64_T
|
||||
#undef HAVE_STRUCT_FLOCK64
|
||||
#undef SIZEOF_INO_T
|
||||
@@ -870,6 +871,12 @@
|
||||
/* Define if you have the <utime.h> header file. */
|
||||
#undef HAVE_UTIME_H
|
||||
|
||||
/* Define if you have the <utmp.h> header file. */
|
||||
#undef HAVE_UTMP_H
|
||||
|
||||
/* Define if you have the <utmpx.h> header file. */
|
||||
#undef HAVE_UTMPX_H
|
||||
|
||||
/* Define if you have the cups library (-lcups). */
|
||||
#undef HAVE_LIBCUPS
|
||||
|
||||
|
||||
@@ -1127,6 +1127,7 @@ char *lp_smb_passwd_file(void);
|
||||
char *lp_serverstring(void);
|
||||
char *lp_printcapname(void);
|
||||
char *lp_lockdir(void);
|
||||
char *lp_utmpdir(void);
|
||||
char *lp_rootdir(void);
|
||||
char *lp_defaultservice(void);
|
||||
char *lp_msg_command(void);
|
||||
@@ -1300,6 +1301,7 @@ BOOL lp_map_hidden(int );
|
||||
BOOL lp_map_archive(int );
|
||||
BOOL lp_locking(int );
|
||||
BOOL lp_strict_locking(int );
|
||||
BOOL lp_utmp(int );
|
||||
BOOL lp_share_modes(int );
|
||||
BOOL lp_oplocks(int );
|
||||
BOOL lp_level2_oplocks(int );
|
||||
|
||||
@@ -159,6 +159,9 @@ typedef struct
|
||||
char *szAddUserScript;
|
||||
char *szDelUserScript;
|
||||
char *szWINSHook;
|
||||
#ifdef WITH_UTMP
|
||||
char *szUtmpDir;
|
||||
#endif /* WITH_UTMP */
|
||||
int max_log_size;
|
||||
int mangled_stack;
|
||||
int max_xmit;
|
||||
@@ -333,6 +336,9 @@ typedef struct
|
||||
BOOL bMap_archive;
|
||||
BOOL bLocking;
|
||||
BOOL bStrictLocking;
|
||||
#ifdef WITH_UTMP
|
||||
BOOL bUtmp;
|
||||
#endif
|
||||
BOOL bShareModes;
|
||||
BOOL bOpLocks;
|
||||
BOOL bLevel2OpLocks;
|
||||
@@ -435,6 +441,9 @@ static service sDefault =
|
||||
True, /* bMap_archive */
|
||||
True, /* bLocking */
|
||||
False, /* bStrictLocking */
|
||||
#ifdef WITH_UTMP
|
||||
False, /* bUtmp */
|
||||
#endif
|
||||
True, /* bShareModes */
|
||||
True, /* bOpLocks */
|
||||
True, /* bLevel2OpLocks */
|
||||
@@ -773,6 +782,9 @@ 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
|
||||
{"ole locking compatibility", P_BOOL, P_GLOBAL, &Globals.bOleLockingCompat, NULL, NULL, FLAG_GLOBAL},
|
||||
{"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},
|
||||
@@ -799,6 +811,10 @@ static struct parm_struct parm_table[] =
|
||||
{"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, 0},
|
||||
{"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},
|
||||
#endif /* WITH_UTMP */
|
||||
{"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},
|
||||
@@ -882,6 +898,7 @@ static void init_globals(void)
|
||||
string_set(&Globals.szDriverFile, DRIVERFILE);
|
||||
string_set(&Globals.szLockDir, LOCKDIR);
|
||||
string_set(&Globals.szRootdir, "/");
|
||||
string_set(&Globals.szUtmpDir, "");
|
||||
string_set(&Globals.szSmbrun, SMBRUN);
|
||||
string_set(&Globals.szSocketAddress, "0.0.0.0");
|
||||
pstrcpy(s, "Samba ");
|
||||
@@ -1162,6 +1179,9 @@ FN_GLOBAL_STRING(lp_smb_passwd_file,&Globals.szSMBPasswdFile)
|
||||
FN_GLOBAL_STRING(lp_serverstring,&Globals.szServerString)
|
||||
FN_GLOBAL_STRING(lp_printcapname,&Globals.szPrintcapname)
|
||||
FN_GLOBAL_STRING(lp_lockdir,&Globals.szLockDir)
|
||||
#ifdef WITH_UTMP
|
||||
FN_GLOBAL_STRING(lp_utmpdir,&Globals.szUtmpDir)
|
||||
#endif /* WITH_UTMP */
|
||||
FN_GLOBAL_STRING(lp_rootdir,&Globals.szRootdir)
|
||||
FN_GLOBAL_STRING(lp_defaultservice,&Globals.szDefaultService)
|
||||
FN_GLOBAL_STRING(lp_msg_command,&Globals.szMsgCommand)
|
||||
@@ -1355,6 +1375,9 @@ FN_LOCAL_BOOL(lp_map_hidden,bMap_hidden)
|
||||
FN_LOCAL_BOOL(lp_map_archive,bMap_archive)
|
||||
FN_LOCAL_BOOL(lp_locking,bLocking)
|
||||
FN_LOCAL_BOOL(lp_strict_locking,bStrictLocking)
|
||||
#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)
|
||||
|
||||
@@ -27,6 +27,11 @@ 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
|
||||
|
||||
/****************************************************************************
|
||||
delete a connection record
|
||||
****************************************************************************/
|
||||
@@ -48,6 +53,12 @@ BOOL yield_connection(connection_struct *conn,char *name,int max_connections)
|
||||
kbuf.dsize = sizeof(key);
|
||||
|
||||
tdb_delete(tdb, kbuf);
|
||||
|
||||
#ifdef WITH_UTMP
|
||||
if(conn)
|
||||
utmp_yield(key.pid, conn);
|
||||
#endif
|
||||
|
||||
return(True);
|
||||
}
|
||||
|
||||
@@ -102,5 +113,206 @@ 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
|
||||
|
||||
Hints for porting:
|
||||
o Always attempt to use programmatic interface (pututline() etc.)
|
||||
o The "x" (utmpx/wtmpx; HAVE_UTMPX_H) seems preferable.
|
||||
|
||||
OS status:
|
||||
Solaris 2.x: Tested on 2.6 and 2.7; should be OK on other flavours.
|
||||
T.D.Lee@durham.ac.uk
|
||||
HPUX 9.x: Not tested. Appears not to have "x".
|
||||
IRIX 6.5: Not tested. Appears to have "x".
|
||||
|
||||
Notes:
|
||||
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 connection number used in samba locking
|
||||
functions "claim_connection() and "yield_connection()". This seems
|
||||
to be a "nicely behaved" number: starting from 0 then working up
|
||||
looking for an available slot.
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#include <utmp.h>
|
||||
|
||||
#ifdef HAVE_UTMPX_H
|
||||
#include <utmpx.h>
|
||||
#endif
|
||||
|
||||
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 */
|
||||
}
|
||||
|
||||
static int utmp_fill(struct utmp *u, const connection_struct *conn, pid_t pid, int i)
|
||||
{
|
||||
struct timeval timeval;
|
||||
int rc;
|
||||
|
||||
pstrcpy(u->ut_user, conn->user);
|
||||
rc = ut_id_encode(i, u->ut_id);
|
||||
slprintf(u->ut_line, 12, "smb/%d", i);
|
||||
|
||||
u->ut_pid = pid;
|
||||
|
||||
gettimeofday(&timeval, NULL);
|
||||
u->ut_time = timeval.tv_sec;
|
||||
|
||||
return(rc);
|
||||
}
|
||||
|
||||
static void utmp_update(const pstring dirname, const struct utmp *u, const char *host)
|
||||
{
|
||||
pstring fname;
|
||||
|
||||
#ifdef HAVE_UTMPX_H
|
||||
struct utmpx ux, *uxrc;
|
||||
|
||||
getutmpx(u, &ux);
|
||||
if (host) {
|
||||
ux.ut_syslen = strlen(host);
|
||||
pstrcpy(ux.ut_host, host);
|
||||
}
|
||||
|
||||
pstrcpy(fname, dirname);
|
||||
pstrcat(fname, "utmpx");
|
||||
utmpxname(fname);
|
||||
uxrc = pututxline(&ux);
|
||||
if (uxrc == NULL) {
|
||||
DEBUG(2,("utmp_update: pututxline() failed\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
pstrcpy(fname, dirname);
|
||||
pstrcat(fname, "wtmpx");
|
||||
updwtmpx(fname, &ux);
|
||||
#else
|
||||
pstrcpy(fname, dirname);
|
||||
pstrcat(fname, "utmp");
|
||||
|
||||
utmpname(fname);
|
||||
pututline(u);
|
||||
|
||||
pstrcpy(fname, dirname);
|
||||
pstrcat(fname, "wtmp");
|
||||
|
||||
/* *** OK. Appending wtmp (as distinct from overwriting utmp) has
|
||||
me baffled. How is it to be done? *** */
|
||||
#endif
|
||||
}
|
||||
|
||||
static void utmp_yield(int pid, const connection_struct *conn)
|
||||
{
|
||||
struct utmp u;
|
||||
pstring dirname;
|
||||
|
||||
if (! lp_utmp(SNUM(conn))) {
|
||||
DEBUG(2,("utmp_yield: lp_utmp() NULL\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
pstrcpy(dirname,lp_utmpdir());
|
||||
trim_string(dirname,"","/");
|
||||
pstrcat(dirname,"/");
|
||||
|
||||
DEBUG(2,("utmp_yield: dir:%s conn: user:%s cnum:%d i:%d\n",
|
||||
dirname, conn->user, conn->cnum, conn->cnum));
|
||||
|
||||
memset((char *)&u, '\0', sizeof(struct utmp));
|
||||
u.ut_type = DEAD_PROCESS;
|
||||
u.ut_exit.e_termination = 0;
|
||||
u.ut_exit.e_exit = 0;
|
||||
if (utmp_fill(&u, conn, pid, conn->cnum) == 0) {
|
||||
utmp_update(dirname, &u, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void utmp_claim(const struct connections_data *crec, const connection_struct *conn)
|
||||
{
|
||||
extern int Client;
|
||||
struct utmp u;
|
||||
pstring dirname;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
pstrcpy(dirname,lp_utmpdir());
|
||||
trim_string(dirname,"","/");
|
||||
pstrcat(dirname,"/");
|
||||
|
||||
DEBUG(2,("utmp_claim: dir:%s conn: user:%s cnum:%d i:%d\n",
|
||||
dirname, conn->user, conn->cnum, conn->cnum));
|
||||
DEBUG(2,("utmp_claim: crec: pid:%d, cnum:%d name:%s addr:%s mach:%s DNS:%s\n",
|
||||
crec->pid, crec->cnum, crec->name, crec->addr, crec->machine, client_name(Client)));
|
||||
|
||||
|
||||
memset((char *)&u, '\0', sizeof(struct utmp));
|
||||
u.ut_type = USER_PROCESS;
|
||||
if (utmp_fill(&u, conn, crec->pid, conn->cnum) == 0) {
|
||||
utmp_update(dirname, &u, crec->machine);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user