1996-05-04 11:50:46 +04:00
/*
Unix SMB / Netbios implementation .
Version 1.9 .
status reporting
1997-05-08 05:14:17 +04:00
Copyright ( C ) Andrew Tridgell 1994 - 1997
1996-05-04 11:50:46 +04:00
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
the Free Software Foundation ; either version 2 of the License , or
( 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
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
1996-08-15 19:11:34 +04:00
Revision History :
12 aug 96 : Erik . Devriendt @ te6 . siemens . be
added support for shared memory implementation of share mode locking
1996-05-04 11:50:46 +04:00
*/
/*
* This program reports current SMB connections
*/
# ifdef SYSLOG
# undef SYSLOG
# endif
# include "includes.h"
struct connect_record crec ;
1997-05-09 01:17:59 +04:00
struct session_record {
int pid ;
int uid ;
char machine [ 31 ] ;
time_t start ;
struct session_record * next ;
} * srecs ;
1996-05-04 11:50:46 +04:00
extern int DEBUGLEVEL ;
extern FILE * dbf ;
1996-05-05 15:34:03 +04:00
extern pstring myhostname ;
1996-05-04 11:50:46 +04:00
static pstring Ucrit_username = " " ; /* added by OH */
int Ucrit_pid [ 100 ] ; /* Ugly !!! */ /* added by OH */
int Ucrit_MaxPid = 0 ; /* added by OH */
unsigned int Ucrit_IsActive = 0 ; /* added by OH */
1997-05-20 04:32:51 +04:00
# ifndef FAST_SHARE_MODES
static char * read_share_file ( int fd , char * fname , char * progname )
{
struct stat sb ;
char * buf ;
int size ;
if ( fstat ( fd , & sb ) ! = 0 )
{
printf ( " %s: ERROR: read_share_file: Failed to do stat on share file %s (%s) \n " ,
progname , fname , strerror ( errno ) ) ;
return 0 ;
}
if ( sb . st_size = = 0 )
{
return 0 ;
}
/* Allocate space for the file */
if ( ( buf = ( char * ) malloc ( sb . st_size ) ) = = NULL )
{
printf ( " %s: read_share_file: malloc for file size %d fail ! \n " ,
progname , ( int ) sb . st_size ) ;
return 0 ;
}
if ( lseek ( fd , 0 , SEEK_SET ) ! = 0 )
{
printf ( " %s: ERROR: read_share_file: Failed to reset position to 0 \
for share file % s ( % s ) \ n " , progname, fname, strerror(errno));
if ( buf )
free ( buf ) ;
return 0 ;
}
if ( read ( fd , buf , sb . st_size ) ! = sb . st_size )
{
printf ( " %s: ERROR: read_share_file: Failed to read share file %s (%s) \n " ,
progname , fname , strerror ( errno ) ) ;
if ( buf )
free ( buf ) ;
return 0 ;
}
if ( IVAL ( buf , 0 ) ! = LOCKING_VERSION ) {
printf ( " %s: ERROR: read_share_file: share file %s has incorrect \
locking version ( was % d , should be % d ) . \ n " ,fname,
progname , IVAL ( buf , 0 ) , LOCKING_VERSION ) ;
if ( buf )
free ( buf ) ;
return 0 ;
}
/* Sanity check for file contents */
size = sb . st_size ;
size - = 10 ; /* Remove the header */
/* Remove the filename component. */
size - = SVAL ( buf , 8 ) ;
/* The remaining size must be a multiple of 16 - error if not. */
if ( ( size % 16 ) ! = 0 )
{
printf ( " %s: ERROR: read_share_file: share file %s is an incorrect length. \n " ,
progname , fname ) ;
if ( buf )
free ( buf ) ;
return 0 ;
}
return buf ;
}
# endif /* FAST_SHARE_MODES */
1996-06-04 10:42:03 +04:00
int main ( int argc , char * argv [ ] )
1996-05-04 11:50:46 +04:00
{
FILE * f ;
pstring fname ;
1996-08-15 19:11:34 +04:00
int uid , c ;
1996-05-04 11:50:46 +04:00
static pstring servicesf = CONFIGFILE ;
extern char * optarg ;
1997-05-09 01:17:59 +04:00
int verbose = 0 , brief = 0 ;
1996-05-04 11:50:46 +04:00
BOOL firstopen = True ;
BOOL processes_only = False ;
int last_pid = 0 ;
1997-05-20 04:32:51 +04:00
# ifdef FAST_SHARE_MODES
1996-08-15 19:11:34 +04:00
pstring shmem_file_name ;
1997-05-20 04:32:51 +04:00
share_mode_record * file_scanner_p ;
smb_shm_offset_t * mode_array ;
1996-08-15 19:11:34 +04:00
int bytes_free , bytes_used , bytes_overhead , bytes_total ;
1997-05-20 04:32:51 +04:00
# else /* FAST_SHARE_MODES */
1996-08-15 19:11:34 +04:00
void * dir ;
char * s ;
1997-05-20 04:32:51 +04:00
# endif /* FAST_SHARE_MODES */
int i ;
1997-05-09 01:17:59 +04:00
struct session_record * ptr ;
1996-08-15 19:11:34 +04:00
1996-05-04 11:50:46 +04:00
1996-05-31 19:13:29 +04:00
TimeInit ( ) ;
1996-05-04 11:50:46 +04:00
setup_logging ( argv [ 0 ] , True ) ;
1997-07-19 00:21:32 +04:00
charset_initialise ( ) ;
1996-05-04 11:50:46 +04:00
DEBUGLEVEL = 0 ;
dbf = fopen ( " /dev/null " , " w " ) ;
if ( getuid ( ) ! = geteuid ( ) ) {
printf ( " smbstatus should not be run setuid \n " ) ;
return ( 1 ) ;
}
1997-05-09 01:17:59 +04:00
while ( ( c = getopt ( argc , argv , " pds:u:b " ) ) ! = EOF ) {
1996-05-04 11:50:46 +04:00
switch ( c ) {
1997-05-09 01:17:59 +04:00
case ' b ' :
brief = 1 ;
break ;
1996-05-04 11:50:46 +04:00
case ' d ' :
verbose = 1 ;
break ;
case ' p ' :
processes_only = 1 ;
break ;
case ' s ' :
strcpy ( servicesf , optarg ) ;
break ;
case ' u ' : /* added by OH */
Ucrit_addUsername ( optarg ) ; /* added by OH */
break ;
default :
fprintf ( stderr , " Usage: %s [-d] [-p] [-s configfile] [-u username] \n " , * argv ) ; /* changed by OH */
return ( - 1 ) ;
}
}
if ( ! lp_load ( servicesf , False ) ) {
fprintf ( stderr , " Can't load %s - run testparm to debug it \n " , servicesf ) ;
return ( - 1 ) ;
}
1996-05-05 15:34:03 +04:00
get_myname ( myhostname , NULL ) ;
1996-05-04 11:50:46 +04:00
if ( verbose ) {
printf ( " using configfile = %s \n " , servicesf ) ;
printf ( " lockdir = %s \n " , * lp_lockdir ( ) ? lp_lockdir ( ) : " NULL " ) ;
}
strcpy ( fname , lp_lockdir ( ) ) ;
standard_sub_basic ( fname ) ;
trim_string ( fname , " " , " / " ) ;
strcat ( fname , " /STATUS..LCK " ) ;
f = fopen ( fname , " r " ) ;
if ( ! f ) {
printf ( " Couldn't open status file %s \n " , fname ) ;
if ( ! lp_status ( - 1 ) )
printf ( " You need to have status=yes in your smb config file \n " ) ;
return ( 0 ) ;
}
1996-05-05 15:34:03 +04:00
else if ( verbose ) {
printf ( " Opened status file %s \n " , fname ) ;
}
1996-05-04 11:50:46 +04:00
uid = getuid ( ) ;
if ( ! processes_only ) {
printf ( " \n Samba version %s \n " , VERSION ) ;
1997-05-09 01:17:59 +04:00
if ( brief )
{
printf ( " PID Username Machine Time logged in \n " ) ;
printf ( " ------------------------------------------------------------------- \n " ) ;
}
else
{
printf ( " Service uid gid pid machine \n " ) ;
printf ( " ---------------------------------------------- \n " ) ;
}
1996-05-04 11:50:46 +04:00
}
while ( ! feof ( f ) )
{
if ( fread ( & crec , sizeof ( crec ) , 1 , f ) ! = 1 )
break ;
if ( crec . magic = = 0x280267 & & process_exists ( crec . pid )
& & Ucrit_checkUsername ( uidtoname ( crec . uid ) ) /* added by OH */
)
{
1997-05-09 01:17:59 +04:00
if ( brief )
{
ptr = srecs ;
while ( ptr ! = NULL )
{
if ( ( ptr - > pid = = crec . pid ) & & ( strncmp ( ptr - > machine , crec . machine , 30 ) = = 0 ) )
{
if ( ptr - > start > crec . start )
ptr - > start = crec . start ;
break ;
}
ptr = ptr - > next ;
}
if ( ptr = = NULL )
{
ptr = ( struct session_record * ) malloc ( sizeof ( struct session_record ) ) ;
ptr - > uid = crec . uid ;
ptr - > pid = crec . pid ;
ptr - > start = crec . start ;
strncpy ( ptr - > machine , crec . machine , 30 ) ;
ptr - > machine [ 30 ] = ' \0 ' ;
ptr - > next = srecs ;
srecs = ptr ;
}
}
else
{
Ucrit_addPid ( crec . pid ) ; /* added by OH */
if ( processes_only ) {
if ( last_pid ! = crec . pid )
printf ( " %d \n " , crec . pid ) ;
last_pid = crec . pid ; /* XXXX we can still get repeats, have to
add a sort at some time */
}
else
printf ( " %-10.10s %-8s %-8s %5d %-8s (%s) %s " ,
crec . name , uidtoname ( crec . uid ) , gidtoname ( crec . gid ) , crec . pid ,
crec . machine , crec . addr ,
asctime ( LocalTime ( & crec . start ) ) ) ;
}
1996-05-04 11:50:46 +04:00
}
}
fclose ( f ) ;
if ( processes_only ) exit ( 0 ) ;
1997-05-09 01:17:59 +04:00
if ( brief )
{
ptr = srecs ;
while ( ptr ! = NULL )
{
printf ( " %-8d%-10.10s%-30.30s%s " , ptr - > pid , uidtoname ( ptr - > uid ) , ptr - > machine , asctime ( LocalTime ( & ( ptr - > start ) ) ) ) ;
ptr = ptr - > next ;
}
printf ( " \n " ) ;
exit ( 0 ) ;
}
1996-05-04 11:50:46 +04:00
printf ( " \n " ) ;
1997-05-20 04:32:51 +04:00
# ifdef FAST_SHARE_MODES
1996-08-15 19:11:34 +04:00
/*******************************************************************
initialize the shared memory for share_mode management
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
strcpy ( shmem_file_name , lp_lockdir ( ) ) ;
trim_string ( shmem_file_name , " " , " / " ) ;
if ( ! * shmem_file_name ) exit ( - 1 ) ;
strcat ( shmem_file_name , " /SHARE_MEM_FILE " ) ;
1997-05-20 04:32:51 +04:00
if ( ! smb_shm_open ( shmem_file_name , lp_shmem_size ( ) ) ) exit ( - 1 ) ;
1996-08-15 19:11:34 +04:00
1997-05-20 04:32:51 +04:00
mode_array = ( smb_shm_offset_t * ) smb_shm_offset2addr ( smb_shm_get_userdef_off ( ) ) ;
if ( mode_array = = NULL )
1996-08-15 19:11:34 +04:00
{
1997-05-20 04:32:51 +04:00
printf ( " %s: base of shared memory hash array == 0! Exiting. \n " , argv [ 0 ] ) ;
smb_shm_close ( ) ;
exit ( - 1 ) ;
1996-08-15 19:11:34 +04:00
}
1997-05-20 04:32:51 +04:00
for ( i = 0 ; i < lp_shmem_hash_size ( ) ; i + + )
1996-08-15 19:11:34 +04:00
{
1997-05-20 04:32:51 +04:00
smb_shm_lock_hash_entry ( i ) ;
if ( mode_array [ i ] = = NULL_OFFSET )
{
smb_shm_unlock_hash_entry ( i ) ;
continue ;
}
file_scanner_p = ( share_mode_record * ) smb_shm_offset2addr ( mode_array [ i ] ) ;
while ( ( file_scanner_p ! = 0 ) & & ( file_scanner_p - > num_share_mode_entries ! = 0 ) )
{
share_mode_entry * entry_scanner_p =
( share_mode_entry * ) smb_shm_offset2addr (
file_scanner_p - > share_mode_entries ) ;
while ( entry_scanner_p ! = 0 )
{
struct timeval t ;
int pid = entry_scanner_p - > pid ;
int mode = entry_scanner_p - > share_mode ;
1996-08-15 19:11:34 +04:00
1997-05-20 04:32:51 +04:00
t . tv_sec = entry_scanner_p - > time . tv_sec ;
t . tv_usec = entry_scanner_p - > time . tv_usec ;
strcpy ( fname , file_scanner_p - > file_name ) ;
# else /* FAST_SHARE_MODES */
/* For slow share modes go through all the files in
the share mode directory and read the entries in
each .
*/
dir = opendir ( lp_lockdir ( ) ) ;
if ( ! dir )
1996-08-15 19:11:34 +04:00
{
1997-05-20 04:32:51 +04:00
printf ( " %s: Unable to open lock directory %s. \n " , argv [ 0 ] , lp_lockdir ( ) ) ;
return ( 0 ) ;
1996-08-15 19:11:34 +04:00
}
while ( ( s = readdirname ( dir ) ) ) {
1997-05-20 04:32:51 +04:00
char * buf ;
char * base ;
1996-08-15 19:11:34 +04:00
int fd ;
pstring lname ;
1997-05-20 04:32:51 +04:00
uint32 dev , inode ;
1996-08-15 19:11:34 +04:00
1997-05-20 04:32:51 +04:00
if ( sscanf ( s , " share.%u.%u " , & dev , & inode ) ! = 2 ) continue ;
1996-08-15 19:11:34 +04:00
strcpy ( lname , lp_lockdir ( ) ) ;
trim_string ( lname , NULL , " / " ) ;
strcat ( lname , " / " ) ;
strcat ( lname , s ) ;
1997-05-20 04:32:51 +04:00
fd = open ( lname , O_RDWR , 0 ) ;
if ( fd < 0 )
{
printf ( " %s: Unable to open share file %s. \n " , argv [ 0 ] , lname ) ;
continue ;
1996-08-15 19:11:34 +04:00
}
1997-05-20 04:32:51 +04:00
/* Lock the share mode file while we read it. */
if ( fcntl_lock ( fd , F_SETLKW , 0 , 1 , F_WRLCK ) = = False )
{
printf ( " %s: Unable to lock open share file %s. \n " , argv [ 0 ] , lname ) ;
close ( fd ) ;
continue ;
}
if ( ( buf = read_share_file ( fd , lname , argv [ 0 ] ) ) = = NULL )
{
close ( fd ) ;
continue ;
}
strcpy ( fname , & buf [ 10 ] ) ;
close ( fd ) ;
base = buf + 10 + SVAL ( buf , 8 ) ;
for ( i = 0 ; i < IVAL ( buf , 4 ) ; i + + )
{
char * p = base + ( i * 16 ) ;
struct timeval t ;
int pid = IVAL ( p , 12 ) ;
int mode = IVAL ( p , 8 ) ;
t . tv_sec = IVAL ( p , 0 ) ;
t . tv_usec = IVAL ( p , 4 ) ;
# endif /* FAST_SHARE_MODES */
1996-05-04 11:50:46 +04:00
fname [ sizeof ( fname ) - 1 ] = 0 ;
if ( firstopen ) {
firstopen = False ;
printf ( " Locked files: \n " ) ;
printf ( " Pid DenyMode R/W Name \n " ) ;
printf ( " ------------------------------ \n " ) ;
}
printf ( " %-5d " , pid ) ;
switch ( ( mode > > 4 ) & 0xF )
{
case DENY_NONE : printf ( " DENY_NONE " ) ; break ;
case DENY_ALL : printf ( " DENY_ALL " ) ; break ;
case DENY_DOS : printf ( " DENY_DOS " ) ; break ;
case DENY_READ : printf ( " DENY_READ " ) ; break ;
case DENY_WRITE : printf ( " DENY_WRITE " ) ; break ;
}
switch ( mode & 0xF )
{
case 0 : printf ( " RDONLY " ) ; break ;
case 1 : printf ( " WRONLY " ) ; break ;
case 2 : printf ( " RDWR " ) ; break ;
}
1997-01-09 21:02:17 +03:00
printf ( " %s %s " , fname , asctime ( LocalTime ( ( time_t * ) & t . tv_sec ) ) ) ;
1996-08-15 19:11:34 +04:00
1997-05-20 04:32:51 +04:00
# ifdef FAST_SHARE_MODES
entry_scanner_p = ( share_mode_entry * ) smb_shm_offset2addr (
entry_scanner_p - > next_share_mode_entry ) ;
} /* end while entry_scanner_p */
file_scanner_p = ( share_mode_record * ) smb_shm_offset2addr (
file_scanner_p - > next_offset ) ;
} /* end while file_scanner_p */
smb_shm_unlock_hash_entry ( i ) ;
} /* end for */
1996-08-15 19:11:34 +04:00
1997-01-15 04:53:25 +03:00
smb_shm_get_usage ( & bytes_free , & bytes_used , & bytes_overhead ) ;
1996-08-15 19:11:34 +04:00
bytes_total = bytes_free + bytes_used + bytes_overhead ;
/*******************************************************************
deinitialize the shared memory for share_mode management
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1997-01-15 04:53:25 +03:00
smb_shm_close ( ) ;
1996-08-15 19:11:34 +04:00
1997-05-20 04:32:51 +04:00
# else /* FAST_SHARE_MODES */
} /* end for i */
if ( buf )
free ( buf ) ;
base = 0 ;
1996-08-15 19:11:34 +04:00
} /* end while */
1996-05-04 11:50:46 +04:00
closedir ( dir ) ;
1997-05-20 04:32:51 +04:00
# endif /* FAST_SHARE_MODES */
1996-05-04 11:50:46 +04:00
if ( firstopen )
printf ( " No locked files \n " ) ;
1997-05-20 04:32:51 +04:00
# ifdef FAST_SHARE_MODES
1996-08-15 19:11:34 +04:00
printf ( " \n Share mode memory usage (bytes): \n " ) ;
printf ( " %d(%d%%) free + %d(%d%%) used + %d(%d%%) overhead = %d(100%%) total \n " ,
bytes_free , ( bytes_free * 100 ) / bytes_total ,
bytes_used , ( bytes_used * 100 ) / bytes_total ,
bytes_overhead , ( bytes_overhead * 100 ) / bytes_total ,
bytes_total ) ;
1997-05-20 04:32:51 +04:00
# endif /* FAST_SHARE_MODES */
1996-05-04 11:50:46 +04:00
return ( 0 ) ;
}
/* added by OH */
void Ucrit_addUsername ( pstring username )
{
strcpy ( Ucrit_username , username ) ;
if ( strlen ( Ucrit_username ) > 0 )
Ucrit_IsActive = 1 ;
}
unsigned int Ucrit_checkUsername ( pstring username )
{
if ( ! Ucrit_IsActive ) return 1 ;
if ( strcmp ( Ucrit_username , username ) = = 0 ) return 1 ;
return 0 ;
}
void Ucrit_addPid ( int pid )
{
int i ;
if ( ! Ucrit_IsActive ) return ;
for ( i = 0 ; i < Ucrit_MaxPid ; i + + )
if ( pid = = Ucrit_pid [ i ] ) return ;
Ucrit_pid [ Ucrit_MaxPid + + ] = pid ;
}
unsigned int Ucrit_checkPid ( int pid )
{
int i ;
if ( ! Ucrit_IsActive ) return 1 ;
for ( i = 0 ; i < Ucrit_MaxPid ; i + + )
if ( pid = = Ucrit_pid [ i ] ) return 1 ;
return 0 ;
}