2001-04-18 20:42:07 +04:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
2001-04-18 20:42:07 +04:00
utmp routines
Copyright ( C ) T . D . Lee @ durham . ac . uk 1999
Heavily modified by Andrew Bartlett and Tridge , April 2001
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
2001-04-18 20:42:07 +04:00
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
2007-07-10 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2001-04-18 20:42:07 +04:00
*/
# include "includes.h"
/****************************************************************************
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 )
2003-05-16 16:15:04 +04:00
to represent the line . This must be unique within and across all
smbd processes . It is the ' id_num ' from Samba ' s session . c code .
2001-04-18 20:42:07 +04:00
The 4 byte ' ut_id ' component is vital to distinguish connections ,
2003-05-16 16:15:04 +04:00
of which there could be several hundred or even thousand .
2001-04-18 20:42:07 +04:00
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 - 9 a - z ]
' tXNN ' : rlogin ; N : [ 0 - 9 ] ; X : [ 0 - 9 a - 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 .
2003-05-16 16:15:04 +04:00
The remaining two bytes encode the session ' id_num ' ( see above ) .
Our caller ( session . c ) should note our 16 - bit limitation .
2001-04-18 20:42:07 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-06-07 02:33:43 +04:00
# ifndef WITH_UTMP
/*
* Not WITH_UTMP ? Simply supply dummy routines .
*/
2007-10-04 00:43:55 +04:00
void sys_utmp_claim ( const char * username , const char * hostname ,
const char * ip_addr_str ,
const char * id_str , int id_num )
2003-06-07 02:33:43 +04:00
{ }
2007-10-04 00:43:55 +04:00
void sys_utmp_yield ( const char * username , const char * hostname ,
const char * ip_addr_str ,
const char * id_str , int id_num )
2003-06-07 02:33:43 +04:00
{ }
# else /* WITH_UTMP */
2001-04-18 20:42:07 +04:00
# 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
/****************************************************************************
2001-12-14 02:43:15 +03:00
Default paths to various { u , w } tmp { , x } files .
2001-04-18 20:42:07 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-12-14 02:43:15 +03:00
2001-04-18 20:42:07 +04:00
# ifdef HAVE_UTMPX_H
2009-01-08 10:51:41 +03:00
static const char * const ux_pathname =
2001-04-18 20:42:07 +04:00
# if defined (UTMPX_FILE)
UTMPX_FILE ;
# elif defined (_UTMPX_FILE)
_UTMPX_FILE ;
# elif defined (_PATH_UTMPX)
_PATH_UTMPX ;
# else
" " ;
# endif
2009-01-08 10:51:41 +03:00
static const char * const wx_pathname =
2001-04-18 20:42:07 +04:00
# if defined (WTMPX_FILE)
WTMPX_FILE ;
# elif defined (_WTMPX_FILE)
_WTMPX_FILE ;
# elif defined (_PATH_WTMPX)
_PATH_WTMPX ;
# else
" " ;
# endif
# endif /* HAVE_UTMPX_H */
2009-01-08 10:51:41 +03:00
static const char * const ut_pathname =
2001-04-18 20:42:07 +04:00
# if defined (UTMP_FILE)
UTMP_FILE ;
# elif defined (_UTMP_FILE)
_UTMP_FILE ;
# elif defined (_PATH_UTMP)
_PATH_UTMP ;
# else
" " ;
# endif
2009-01-08 10:51:41 +03:00
static const char * const wt_pathname =
2001-04-18 20:42:07 +04:00
# 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. */
2008-07-04 09:53:42 +04:00
#if 0 /* *** Not yet implemented */
2001-04-18 20:42:07 +04:00
# 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 */
2008-07-04 09:53:42 +04:00
# endif
2001-04-18 20:42:07 +04:00
/*
* 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 )
*/
2007-11-13 23:51:31 +03:00
static char * uw_pathname ( TALLOC_CTX * ctx ,
const char * uw_name ,
const char * uw_default )
2001-04-18 20:42:07 +04:00
{
2007-11-13 23:51:31 +03:00
char * dirname = NULL ;
2001-04-18 20:42:07 +04:00
/* For w-files, first look for explicit "wtmp dir" */
if ( uw_name [ 0 ] = = ' w ' ) {
2007-11-13 23:51:31 +03:00
dirname = talloc_strdup ( ctx , lp_wtmpdir ( ) ) ;
if ( ! dirname ) {
return NULL ;
}
2003-09-05 23:59:55 +04:00
trim_char ( dirname , ' \0 ' , ' / ' ) ;
2001-04-18 20:42:07 +04:00
}
/* For u-files and non-explicit w-dir, look for "utmp dir" */
2008-01-22 11:13:25 +03:00
if ( ( dirname = = NULL ) | | ( strlen ( dirname ) = = 0 ) ) {
2007-11-13 23:51:31 +03:00
dirname = talloc_strdup ( ctx , lp_utmpdir ( ) ) ;
if ( ! dirname ) {
return NULL ;
}
2003-09-05 23:59:55 +04:00
trim_char ( dirname , ' \0 ' , ' / ' ) ;
2001-04-18 20:42:07 +04:00
}
/* If explicit directory above, use it */
2007-11-13 23:51:31 +03:00
if ( dirname & & strlen ( dirname ) ! = 0 ) {
return talloc_asprintf ( ctx ,
" %s/%s " ,
dirname ,
uw_name ) ;
2001-04-18 20:42:07 +04:00
}
/* 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 " ) ) ;
}
2007-11-13 23:51:31 +03:00
return talloc_strdup ( ctx , uw_default ) ;
2001-04-18 20:42:07 +04:00
}
# ifndef HAVE_PUTUTLINE
/****************************************************************************
2001-12-14 02:43:15 +03:00
Update utmp file directly . No subroutine interface : probably a BSD system .
2001-04-18 20:42:07 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-12-14 02:43:15 +03:00
2007-11-13 23:51:31 +03:00
static void pututline_my ( const char * uname , struct utmp * u , bool claim )
2001-04-18 20:42:07 +04:00
{
DEBUG ( 1 , ( " pututline_my: not yet implemented \n " ) ) ;
/* BSD implementor: may want to consider (or not) adjusting "lastlog" */
}
# endif /* HAVE_PUTUTLINE */
# ifndef HAVE_UPDWTMP
2001-12-14 02:43:15 +03:00
2001-04-18 20:42:07 +04:00
/****************************************************************************
2001-12-14 02:43:15 +03:00
Update wtmp file directly . No subroutine interface : probably a BSD system .
Credit : Michail Vidiassov < master @ iaas . msu . ru >
2001-04-18 20:42:07 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-12-14 02:43:15 +03:00
2007-11-13 23:51:31 +03:00
static void updwtmp_my ( const char * wname , struct utmp * u , bool claim )
2001-04-18 20:42:07 +04:00
{
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
*/
2003-08-03 22:50:00 +04:00
# if defined(HAVE_UT_UT_NAME)
2001-12-18 11:19:02 +03:00
memset ( ( char * ) & u - > ut_name , ' \0 ' , sizeof ( u - > ut_name ) ) ;
2003-08-03 22:50:00 +04:00
# endif
# if defined(HAVE_UT_UT_HOST)
2001-12-18 11:19:02 +03:00
memset ( ( char * ) & u - > ut_host , ' \0 ' , sizeof ( u - > ut_host ) ) ;
2003-08-03 22:50:00 +04:00
# endif
2001-04-18 20:42:07 +04:00
}
/* 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 */
/****************************************************************************
2001-12-14 02:43:15 +03:00
Update via utmp / wtmp ( not utmpx / wtmpx ) .
2001-04-18 20:42:07 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-12-14 02:43:15 +03:00
2007-10-19 04:40:25 +04:00
static void utmp_nox_update ( struct utmp * u , bool claim )
2001-04-18 20:42:07 +04:00
{
2007-11-13 23:51:31 +03:00
char * uname = NULL ;
char * wname = NULL ;
2001-04-18 20:42:07 +04:00
# if defined(PUTUTLINE_RETURNS_UTMP)
struct utmp * urc ;
# endif /* PUTUTLINE_RETURNS_UTMP */
2007-11-13 23:51:31 +03:00
uname = uw_pathname ( talloc_tos ( ) , " utmp " , ut_pathname ) ;
if ( ! uname ) {
return ;
}
2001-04-18 20:42:07 +04:00
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 */
2007-11-13 23:51:31 +03:00
wname = uw_pathname ( talloc_tos ( ) , " wtmp " , wt_pathname ) ;
if ( ! wname ) {
return ;
}
2001-04-18 20:42:07 +04:00
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 */
}
}
/****************************************************************************
2001-12-14 02:43:15 +03:00
Copy a string in the utmp structure .
2001-04-18 20:42:07 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-12-14 02:43:15 +03:00
static void utmp_strcpy ( char * dest , const char * src , size_t n )
{
2001-12-18 11:19:02 +03:00
size_t len = 0 ;
2001-12-14 02:43:15 +03:00
2001-12-18 11:19:02 +03:00
memset ( dest , ' \0 ' , n ) ;
if ( src )
len = strlen ( src ) ;
2001-12-14 02:43:15 +03:00
if ( len > = n ) {
memcpy ( dest , src , n ) ;
} else {
2001-12-18 11:19:02 +03:00
if ( len )
memcpy ( dest , src , len ) ;
2001-12-14 02:43:15 +03:00
}
}
/****************************************************************************
Update via utmpx / wtmpx ( preferred ) or via utmp / wtmp .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-19 04:40:25 +04:00
static void sys_utmp_update ( struct utmp * u , const char * hostname , bool claim )
2001-04-18 20:42:07 +04:00
{
# if !defined(HAVE_UTMPX_H)
/* No utmpx stuff. Drop to non-x stuff */
2001-12-18 11:19:02 +03:00
utmp_nox_update ( u , claim ) ;
2001-04-18 20:42:07 +04:00
# 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 " ) ) ;
2001-12-18 11:19:02 +03:00
utmp_nox_update ( u , claim ) ;
2001-04-18 20:42:07 +04:00
# 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 " ) ) ;
2001-12-18 11:19:02 +03:00
utmp_nox_update ( u , claim ) ;
2008-03-24 22:33:04 +03:00
# elif !defined(HAVE_UPDWTMPX)
/* Have utmpx.h but no "updwtmpx()". Drop to non-x stuff */
DEBUG ( 1 , ( " utmp_update: have utmpx.h but no updwtmpx() function \n " ) ) ;
utmp_nox_update ( u , claim ) ;
2001-04-18 20:42:07 +04:00
# else
2007-11-13 23:51:31 +03:00
char * uname = NULL ;
char * wname = NULL ;
2001-04-18 20:42:07 +04:00
struct utmpx ux , * uxrc ;
getutmpx ( u , & ux ) ;
# if defined(HAVE_UX_UT_SYSLEN)
2001-12-14 02:43:15 +03:00
if ( hostname )
ux . ut_syslen = strlen ( hostname ) + 1 ; /* include end NULL */
else
ux . ut_syslen = 0 ;
2001-04-18 20:42:07 +04:00
# endif
2003-08-03 22:50:00 +04:00
# if defined(HAVE_UT_UT_HOST)
2001-12-14 02:43:15 +03:00
utmp_strcpy ( ux . ut_host , hostname , sizeof ( ux . ut_host ) ) ;
2003-08-03 22:50:00 +04:00
# endif
2001-04-18 20:42:07 +04:00
2007-11-13 23:51:31 +03:00
uname = uw_pathname ( talloc_tos ( ) , " utmpx " , ux_pathname ) ;
wname = uw_pathname ( talloc_tos ( ) , " wtmpx " , wx_pathname ) ;
if ( uname & & wname ) {
DEBUG ( 2 , ( " utmp_update: uname:%s wname:%s \n " , uname , wname ) ) ;
}
2001-04-18 20:42:07 +04:00
/*
* 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 " . )
*/
2007-11-13 23:51:31 +03:00
if ( ! uname | | ! wname | | ( strlen ( uname ) = = 0 ) | | ( strlen ( wname ) = = 0 ) ) {
2001-12-18 11:19:02 +03:00
utmp_nox_update ( u , claim ) ;
2001-04-18 20:42:07 +04:00
} else {
utmpxname ( uname ) ;
setutxent ( ) ;
uxrc = pututxline ( & ux ) ;
endutxent ( ) ;
if ( uxrc = = NULL ) {
DEBUG ( 2 , ( " utmp_update: pututxline() failed \n " ) ) ;
return ;
}
updwtmpx ( wname , & ux ) ;
}
# endif /* HAVE_UTMPX_H */
}
# if defined(HAVE_UT_UT_ID)
/****************************************************************************
2001-12-14 02:43:15 +03:00
Encode the unique connection number into " ut_id " .
2001-04-18 20:42:07 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-12-14 02:43:15 +03:00
2001-04-18 20:42:07 +04:00
static int ut_id_encode ( int i , char * fourbyte )
{
int nbase ;
2003-01-03 11:28:12 +03:00
const char * ut_id_encstr = " 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ " ;
2007-10-04 00:43:55 +04:00
2001-04-18 20:42:07 +04:00
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) */
/*
2007-10-04 00:43:55 +04:00
fill a system utmp structure given all the info we can gather
2001-04-18 20:42:07 +04:00
*/
2007-10-19 04:40:25 +04:00
static bool sys_utmp_fill ( struct utmp * u ,
2007-10-04 00:43:55 +04:00
const char * username , const char * hostname ,
const char * ip_addr_str ,
const char * id_str , int id_num )
{
2001-04-18 20:42:07 +04:00
struct timeval timeval ;
/*
* 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)
2001-12-14 02:43:15 +03:00
utmp_strcpy ( u - > ut_user , username , sizeof ( u - > ut_user ) ) ;
2001-04-18 20:42:07 +04:00
# elif defined(HAVE_UT_UT_NAME)
2001-12-14 02:43:15 +03:00
utmp_strcpy ( u - > ut_name , username , sizeof ( u - > ut_name ) ) ;
2001-04-18 20:42:07 +04:00
# endif
/*
* ut_line :
* If size limit proves troublesome , then perhaps use " ut_id_encode() " .
*/
if ( strlen ( id_str ) > sizeof ( u - > ut_line ) ) {
2003-07-25 08:24:40 +04:00
DEBUG ( 1 , ( " id_str [%s] is too long for %lu char utmp field \n " ,
id_str , ( unsigned long ) sizeof ( u - > ut_line ) ) ) ;
2001-04-18 20:42:07 +04:00
return False ;
}
2001-12-14 02:43:15 +03:00
utmp_strcpy ( u - > ut_line , id_str , sizeof ( u - > ut_line ) ) ;
2001-04-18 20:42:07 +04:00
# if defined(HAVE_UT_UT_PID)
u - > ut_pid = sys_getpid ( ) ;
# endif
/*
2007-10-04 00:43:55 +04:00
* ut_time , ut_tv :
2001-04-18 20:42:07 +04:00
* 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)
2004-07-02 02:55:38 +04:00
GetTimeOfDay ( & timeval ) ;
2001-04-18 20:42:07 +04:00
u - > ut_time = timeval . tv_sec ;
# elif defined(HAVE_UT_UT_TV)
2004-07-02 02:55:38 +04:00
GetTimeOfDay ( & timeval ) ;
2001-04-18 20:42:07 +04:00
u - > ut_tv = timeval ;
# else
# error "with-utmp must have UT_TIME or UT_TV"
# endif
# if defined(HAVE_UT_UT_HOST)
2001-12-14 02:43:15 +03:00
utmp_strcpy ( u - > ut_host , hostname , sizeof ( u - > ut_host ) ) ;
2001-04-18 20:42:07 +04:00
# endif
2007-10-19 17:14:12 +04:00
# if defined(HAVE_IPV6) && defined(HAVE_UT_UT_ADDR_V6)
2007-10-04 00:43:55 +04:00
memset ( & u - > ut_addr_v6 , ' \0 ' , sizeof ( u - > ut_addr_v6 ) ) ;
if ( ip_addr_str ) {
struct in6_addr addr ;
if ( inet_pton ( AF_INET6 , ip_addr_str , & addr ) > 0 ) {
memcpy ( & u - > ut_addr_v6 , & addr , sizeof ( addr ) ) ;
}
}
# elif defined(HAVE_UT_UT_ADDR)
memset ( & u - > ut_addr , ' \0 ' , sizeof ( u - > ut_addr ) ) ;
if ( ip_addr_str ) {
struct in_addr addr ;
if ( inet_pton ( AF_INET , ip_addr_str , & addr ) > 0 ) {
memcpy ( & u - > ut_addr , & addr , sizeof ( addr ) ) ;
}
}
2001-04-18 20:42:07 +04:00
/*
* " (unsigned long) ut_addr " apparently exists on at least HP - UX 10.20 .
* Volunteer to implement , please . . .
*/
# endif
# if defined(HAVE_UT_UT_ID)
if ( ut_id_encode ( id_num , u - > ut_id ) ! = 0 ) {
DEBUG ( 1 , ( " utmp_fill: cannot encode id %d \n " , id_num ) ) ;
return False ;
}
# endif
return True ;
}
/****************************************************************************
2001-12-14 02:43:15 +03:00
Close a connection .
2001-04-18 20:42:07 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-12-14 02:43:15 +03:00
2007-10-04 00:43:55 +04:00
void sys_utmp_yield ( const char * username , const char * hostname ,
const char * ip_addr_str ,
const char * id_str , int id_num )
2001-04-18 20:42:07 +04:00
{
struct utmp u ;
ZERO_STRUCT ( u ) ;
# if defined(HAVE_UT_UT_EXIT)
u . ut_exit . e_termination = 0 ;
u . ut_exit . e_exit = 0 ;
# endif
# if defined(HAVE_UT_UT_TYPE)
u . ut_type = DEAD_PROCESS ;
# endif
2007-10-04 00:43:55 +04:00
if ( ! sys_utmp_fill ( & u , username , hostname , ip_addr_str , id_str , id_num ) )
return ;
2001-04-18 20:42:07 +04:00
sys_utmp_update ( & u , NULL , False ) ;
}
/****************************************************************************
2001-12-14 02:43:15 +03:00
Claim a entry in whatever utmp system the OS uses .
2001-04-18 20:42:07 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-12-14 02:43:15 +03:00
2007-10-04 00:43:55 +04:00
void sys_utmp_claim ( const char * username , const char * hostname ,
const char * ip_addr_str ,
const char * id_str , int id_num )
2001-04-18 20:42:07 +04:00
{
struct utmp u ;
ZERO_STRUCT ( u ) ;
# if defined(HAVE_UT_UT_TYPE)
u . ut_type = USER_PROCESS ;
# endif
2007-10-04 00:43:55 +04:00
if ( ! sys_utmp_fill ( & u , username , hostname , ip_addr_str , id_str , id_num ) )
return ;
2001-04-18 20:42:07 +04:00
sys_utmp_update ( & u , hostname , True ) ;
}
2003-06-07 02:33:43 +04:00
# endif /* WITH_UTMP */