1996-05-04 11:50:46 +04:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
1996-05-04 11:50:46 +04:00
status reporting
1998-01-22 16:27:43 +03:00
Copyright ( C ) Andrew Tridgell 1994 - 1998
2009-09-18 20:10:54 +04:00
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
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
1996-05-04 11:50:46 +04:00
( at your option ) any later version .
2009-09-18 20:10:54 +04:00
1996-05-04 11:50:46 +04:00
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 .
2009-09-18 20:10:54 +04:00
1996-05-04 11:50:46 +04:00
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/>.
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
1998-07-24 05:08:31 +04:00
21 - Jul - 1998 : rsharpe @ ns . aus . com ( Richard Sharpe )
Added - L ( locks only ) - S ( shares only ) flags and code
1996-05-04 11:50:46 +04:00
*/
/*
* This program reports current SMB connections
*/
# include "includes.h"
2017-01-01 23:00:55 +03:00
# include "lib/util/server_id.h"
2015-11-09 19:17:17 +03:00
# include "smbd/globals.h"
2011-02-26 01:20:06 +03:00
# include "system/filesys.h"
2010-08-05 12:49:53 +04:00
# include "popt_common.h"
2011-07-07 19:42:08 +04:00
# include "dbwrap/dbwrap.h"
2011-07-06 18:40:21 +04:00
# include "dbwrap/dbwrap_open.h"
2010-10-12 08:27:50 +04:00
# include "../libcli/security/security.h"
2011-02-25 01:14:15 +03:00
# include "session.h"
2011-03-23 14:43:17 +03:00
# include "locking/proto.h"
2011-03-24 17:31:06 +03:00
# include "messages.h"
2011-11-24 17:11:28 +04:00
# include "librpc/gen_ndr/open_files.h"
2012-06-05 16:50:23 +04:00
# include "smbd/smbd.h"
2012-04-04 16:51:09 +04:00
# include "librpc/gen_ndr/notify.h"
2012-06-04 17:32:28 +04:00
# include "lib/conn_tdb.h"
2013-04-18 19:09:32 +04:00
# include "serverid.h"
2014-10-10 16:18:50 +04:00
# include "status_profile.h"
2015-01-09 15:48:56 +03:00
# include "smbd/notifyd/notifyd.h"
2018-08-21 01:46:27 +03:00
# include "cmdline_contexts.h"
1996-05-04 11:50:46 +04:00
2003-11-13 01:35:50 +03:00
# define SMB_MAXPIDS 2048
2004-12-17 11:51:23 +03:00
static uid_t Ucrit_uid = 0 ; /* added by OH */
2007-05-07 19:31:12 +04:00
static struct server_id Ucrit_pid [ SMB_MAXPIDS ] ; /* Ugly !!! */ /* added by OH */
2003-11-13 01:35:50 +03:00
static int Ucrit_MaxPid = 0 ; /* added by OH */
static unsigned int Ucrit_IsActive = 0 ; /* added by OH */
2007-10-19 22:38:36 +04:00
static bool verbose , brief ;
static bool shares_only ; /* Added by RJS */
static bool locks_only ; /* Added by RJS */
static bool processes_only ;
static bool show_brl ;
static bool numeric_only ;
2012-07-13 19:24:02 +04:00
static bool do_checks = true ;
1998-07-24 05:08:31 +04:00
2004-11-12 02:30:32 +03:00
const char * username = NULL ;
1998-08-10 05:25:32 +04:00
/* added by OH */
2004-12-17 11:51:23 +03:00
static void Ucrit_addUid ( uid_t uid )
1998-08-10 05:25:32 +04:00
{
2004-12-17 11:51:23 +03:00
Ucrit_uid = uid ;
Ucrit_IsActive = 1 ;
1998-08-10 05:25:32 +04:00
}
2004-12-17 11:51:23 +03:00
static unsigned int Ucrit_checkUid ( uid_t uid )
1998-08-10 05:25:32 +04:00
{
2003-11-13 01:35:50 +03:00
if ( ! Ucrit_IsActive )
return 1 ;
2009-09-18 20:10:54 +04:00
2004-12-17 11:51:23 +03:00
if ( uid = = Ucrit_uid )
2003-11-13 01:35:50 +03:00
return 1 ;
2009-09-18 20:10:54 +04:00
1998-08-10 05:25:32 +04:00
return 0 ;
}
2007-05-07 19:31:12 +04:00
static unsigned int Ucrit_checkPid ( struct server_id pid )
1998-08-10 05:25:32 +04:00
{
int i ;
2009-09-18 20:10:54 +04:00
2003-11-13 01:35:50 +03:00
if ( ! Ucrit_IsActive )
return 1 ;
2009-09-18 20:10:54 +04:00
2003-11-13 01:35:50 +03:00
for ( i = 0 ; i < Ucrit_MaxPid ; i + + ) {
2012-06-16 02:26:26 +04:00
if ( serverid_equal ( & pid , & Ucrit_pid [ i ] ) ) {
2003-11-13 01:35:50 +03:00
return 1 ;
2012-06-16 02:07:16 +04:00
}
2003-11-13 01:35:50 +03:00
}
2009-09-18 20:10:54 +04:00
1998-08-10 05:25:32 +04:00
return 0 ;
}
2007-10-19 04:40:25 +04:00
static bool Ucrit_addPid ( struct server_id pid )
2003-11-13 01:35:50 +03:00
{
if ( ! Ucrit_IsActive )
return True ;
if ( Ucrit_MaxPid > = SMB_MAXPIDS ) {
d_printf ( " ERROR: More than %d pids for user %s! \n " ,
2004-12-17 11:51:23 +03:00
SMB_MAXPIDS , uidtoname ( Ucrit_uid ) ) ;
2003-11-13 01:35:50 +03:00
return False ;
}
Ucrit_pid [ Ucrit_MaxPid + + ] = pid ;
2009-09-18 20:10:54 +04:00
2003-11-13 01:35:50 +03:00
return True ;
}
1998-08-10 05:25:32 +04:00
2018-07-25 17:56:35 +03:00
static int print_share_mode ( struct file_id fid ,
const struct share_mode_data * d ,
const struct share_mode_entry * e ,
void * private_data )
1997-10-20 12:46:00 +04:00
{
static int count ;
2006-02-01 00:54:24 +03:00
2012-07-13 19:24:02 +04:00
if ( do_checks & & ! is_valid_share_mode_entry ( e ) ) {
2014-11-05 22:27:06 +03:00
return 0 ;
2006-02-01 00:54:24 +03:00
}
1997-10-20 12:46:00 +04:00
if ( count = = 0 ) {
2001-09-08 06:59:23 +04:00
d_printf ( " Locked files: \n " ) ;
2006-06-21 06:31:12 +04:00
d_printf ( " Pid Uid DenyMode Access R/W Oplock SharePath Name Time \n " ) ;
d_printf ( " -------------------------------------------------------------------------------------------------- \n " ) ;
1997-10-20 12:46:00 +04:00
}
count + + ;
2013-04-18 19:09:32 +04:00
if ( do_checks & & ! serverid_exists ( & e - > pid ) ) {
/* the process for this entry does not exist any more */
2014-09-24 22:46:15 +04:00
return 0 ;
2013-04-18 19:09:32 +04:00
}
2007-05-07 19:31:12 +04:00
if ( Ucrit_checkPid ( e - > pid ) ) {
2015-04-23 19:06:17 +03:00
struct server_id_buf tmp ;
d_printf ( " %-11s " , server_id_str_buf ( e - > pid , & tmp ) ) ;
2006-06-21 06:31:12 +04:00
d_printf ( " %-9u " , ( unsigned int ) e - > uid ) ;
2005-07-08 08:51:27 +04:00
switch ( map_share_mode_to_deny_mode ( e - > share_access ,
e - > private_options ) ) {
case DENY_NONE : d_printf ( " DENY_NONE " ) ; break ;
case DENY_ALL : d_printf ( " DENY_ALL " ) ; break ;
case DENY_DOS : d_printf ( " DENY_DOS " ) ; break ;
case DENY_READ : d_printf ( " DENY_READ " ) ; break ;
case DENY_WRITE : printf ( " DENY_WRITE " ) ; break ;
case DENY_FCB : d_printf ( " DENY_FCB " ) ; break ;
default : {
d_printf ( " unknown-please report ! "
" e->share_access = 0x%x, "
" e->private_options = 0x%x \n " ,
( unsigned int ) e - > share_access ,
( unsigned int ) e - > private_options ) ;
break ;
}
}
d_printf ( " 0x%-8x " , ( unsigned int ) e - > access_mask ) ;
2005-09-14 00:13:33 +04:00
if ( ( e - > access_mask & ( FILE_READ_DATA | FILE_WRITE_DATA ) ) = =
( FILE_READ_DATA | FILE_WRITE_DATA ) ) {
2005-07-08 08:51:27 +04:00
d_printf ( " RDWR " ) ;
} else if ( e - > access_mask & FILE_WRITE_DATA ) {
d_printf ( " WRONLY " ) ;
} else {
d_printf ( " RDONLY " ) ;
}
if ( ( e - > op_type & ( EXCLUSIVE_OPLOCK | BATCH_OPLOCK ) ) = =
( EXCLUSIVE_OPLOCK | BATCH_OPLOCK ) ) {
d_printf ( " EXCLUSIVE+BATCH " ) ;
} else if ( e - > op_type & EXCLUSIVE_OPLOCK ) {
d_printf ( " EXCLUSIVE " ) ;
} else if ( e - > op_type & BATCH_OPLOCK ) {
d_printf ( " BATCH " ) ;
} else if ( e - > op_type & LEVEL_II_OPLOCK ) {
d_printf ( " LEVEL_II " ) ;
2014-11-27 20:34:56 +03:00
} else if ( e - > op_type = = LEASE_OPLOCK ) {
2018-07-25 17:59:53 +03:00
struct share_mode_lease * l = & d - > leases [ e - > lease_idx ] ;
uint32_t lstate = l - > current_state ;
2014-11-27 20:34:56 +03:00
d_printf ( " LEASE(%s%s%s)%s%s%s " ,
( lstate & SMB2_LEASE_READ ) ? " R " : " " ,
( lstate & SMB2_LEASE_WRITE ) ? " W " : " " ,
( lstate & SMB2_LEASE_HANDLE ) ? " H " : " " ,
( lstate & SMB2_LEASE_READ ) ? " " : " " ,
( lstate & SMB2_LEASE_WRITE ) ? " " : " " ,
( lstate & SMB2_LEASE_HANDLE ) ? " " : " " ) ;
2005-07-08 08:51:27 +04:00
} else {
d_printf ( " NONE " ) ;
}
2015-10-11 10:38:18 +03:00
d_printf ( " %s %s%s %s " ,
2018-07-25 17:56:35 +03:00
d - > servicepath , d - > base_name ,
( d - > stream_name ! = NULL ) ? d - > stream_name : " " ,
2015-10-11 10:38:18 +03:00
time_to_asc ( ( time_t ) e - > time . tv_sec ) ) ;
1998-05-30 06:25:11 +04:00
}
2014-09-24 22:46:15 +04:00
return 0 ;
1997-10-20 12:46:00 +04:00
}
1997-05-20 04:32:51 +04:00
2007-05-29 13:30:34 +04:00
static void print_brl ( struct file_id id ,
2007-05-07 13:35:35 +04:00
struct server_id pid ,
2006-04-10 19:33:04 +04:00
enum brl_type lock_type ,
enum brl_flavour lock_flav ,
br_off start ,
2007-05-29 17:26:44 +04:00
br_off size ,
void * private_data )
2000-01-16 14:14:44 +03:00
{
static int count ;
2012-07-13 19:32:19 +04:00
unsigned int i ;
2007-05-29 13:30:34 +04:00
static const struct {
enum brl_type lock_type ;
const char * desc ;
} lock_types [ ] = {
{ READ_LOCK , " R " } ,
{ WRITE_LOCK , " W " } ,
{ PENDING_READ_LOCK , " PR " } ,
{ PENDING_WRITE_LOCK , " PW " } ,
{ UNLOCK_LOCK , " U " }
} ;
const char * desc = " X " ;
2007-08-01 15:18:56 +04:00
const char * sharepath = " " ;
2009-07-09 03:22:44 +04:00
char * fname = NULL ;
2007-08-01 15:18:56 +04:00
struct share_mode_lock * share_mode ;
2015-04-23 19:06:17 +03:00
struct server_id_buf tmp ;
2007-08-01 15:18:56 +04:00
2000-01-16 14:14:44 +03:00
if ( count = = 0 ) {
2001-09-08 06:59:23 +04:00
d_printf ( " Byte range locks: \n " ) ;
2007-08-01 15:18:56 +04:00
d_printf ( " Pid dev:inode R/W start size SharePath Name \n " ) ;
d_printf ( " -------------------------------------------------------------------------------- \n " ) ;
2000-01-16 14:14:44 +03:00
}
count + + ;
2009-07-09 03:22:44 +04:00
share_mode = fetch_share_mode_unlocked ( NULL , id ) ;
2007-08-01 15:18:56 +04:00
if ( share_mode ) {
2012-01-10 16:56:37 +04:00
bool has_stream = share_mode - > data - > stream_name ! = NULL ;
2009-07-09 03:22:44 +04:00
2012-01-10 16:56:37 +04:00
fname = talloc_asprintf ( NULL , " %s%s%s " ,
share_mode - > data - > base_name ,
2009-07-09 03:22:44 +04:00
has_stream ? " : " : " " ,
2012-01-10 16:56:37 +04:00
has_stream ?
share_mode - > data - > stream_name :
2009-07-09 03:22:44 +04:00
" " ) ;
} else {
fname = talloc_strdup ( NULL , " " ) ;
if ( fname = = NULL ) {
return ;
}
2007-08-01 15:18:56 +04:00
}
2007-05-29 13:30:34 +04:00
for ( i = 0 ; i < ARRAY_SIZE ( lock_types ) ; i + + ) {
if ( lock_type = = lock_types [ i ] . lock_type ) {
desc = lock_types [ i ] . desc ;
}
}
2014-06-01 17:16:16 +04:00
d_printf ( " %-10s %-15s %-4s %-9jd %-9jd %-24s %-24s \n " ,
2015-04-23 19:06:17 +03:00
server_id_str_buf ( pid , & tmp ) , file_id_string_tos ( & id ) ,
2007-05-29 13:30:34 +04:00
desc ,
2014-06-01 17:16:16 +04:00
( intmax_t ) start , ( intmax_t ) size ,
2007-08-01 15:18:56 +04:00
sharepath , fname ) ;
2009-07-09 03:22:44 +04:00
TALLOC_FREE ( fname ) ;
2007-08-02 13:22:47 +04:00
TALLOC_FREE ( share_mode ) ;
2000-01-16 14:14:44 +03:00
}
2015-11-30 12:48:12 +03:00
static const char * session_dialect_str ( uint16_t dialect )
{
static fstring unkown_dialect ;
switch ( dialect ) {
case SMB2_DIALECT_REVISION_000 :
return " NT1 " ;
case SMB2_DIALECT_REVISION_202 :
return " SMB2_02 " ;
case SMB2_DIALECT_REVISION_210 :
return " SMB2_10 " ;
case SMB2_DIALECT_REVISION_222 :
return " SMB2_22 " ;
case SMB2_DIALECT_REVISION_224 :
return " SMB2_24 " ;
case SMB3_DIALECT_REVISION_300 :
return " SMB3_00 " ;
case SMB3_DIALECT_REVISION_302 :
return " SMB3_02 " ;
case SMB3_DIALECT_REVISION_310 :
return " SMB3_10 " ;
case SMB3_DIALECT_REVISION_311 :
return " SMB3_11 " ;
}
fstr_sprintf ( unkown_dialect , " Unknown (0x%04x) " , dialect ) ;
return unkown_dialect ;
}
2012-07-13 19:14:09 +04:00
static int traverse_connections ( const struct connections_key * key ,
const struct connections_data * crec ,
2015-11-19 17:54:17 +03:00
void * private_data )
1999-12-21 07:54:30 +03:00
{
2015-11-19 17:54:17 +03:00
TALLOC_CTX * mem_ctx = ( TALLOC_CTX * ) private_data ;
2015-04-23 19:06:17 +03:00
struct server_id_buf tmp ;
2015-11-09 20:01:47 +03:00
char * timestr = NULL ;
2015-11-09 19:26:51 +03:00
int result = 0 ;
const char * encryption = " - " ;
2015-11-30 13:20:43 +03:00
const char * signing = " - " ;
2015-04-23 19:06:17 +03:00
2012-06-06 17:22:31 +04:00
if ( crec - > cnum = = TID_FIELD_INVALID )
2001-05-15 22:12:02 +04:00
return 0 ;
1999-12-21 07:54:30 +03:00
2012-07-13 19:24:02 +04:00
if ( do_checks & &
( ! process_exists ( crec - > pid ) | | ! Ucrit_checkUid ( crec - > uid ) ) ) {
1999-12-21 07:54:30 +03:00
return 0 ;
}
2015-11-09 20:01:47 +03:00
timestr = timestring ( mem_ctx , crec - > start ) ;
if ( timestr = = NULL ) {
return - 1 ;
}
2015-11-09 19:26:51 +03:00
if ( smbXsrv_is_encrypted ( crec - > encryption_flags ) ) {
switch ( crec - > cipher ) {
2015-11-30 19:03:26 +03:00
case SMB_ENCRYPTION_GSSAPI :
encryption = " GSSAPI " ;
break ;
2015-11-09 19:26:51 +03:00
case SMB2_ENCRYPTION_AES128_CCM :
encryption = " AES-128-CCM " ;
break ;
case SMB2_ENCRYPTION_AES128_GCM :
encryption = " AES-128-GCM " ;
break ;
default :
encryption = " ??? " ;
result = - 1 ;
break ;
}
}
2015-11-30 13:20:43 +03:00
if ( smbXsrv_is_signed ( crec - > signing_flags ) ) {
if ( crec - > dialect > = SMB3_DIALECT_REVISION_302 ) {
signing = " AES-128-CMAC " ;
} else if ( crec - > dialect > = SMB2_DIALECT_REVISION_202 ) {
signing = " HMAC-SHA256 " ;
2015-11-30 19:03:26 +03:00
} else {
signing = " HMAC-MD5 " ;
2015-11-30 13:20:43 +03:00
}
}
d_printf ( " %-12s %-7s %-13s %-32s %-12s %-12s \n " ,
2015-04-23 19:06:17 +03:00
crec - > servicename , server_id_str_buf ( crec - > pid , & tmp ) ,
2015-11-09 19:26:51 +03:00
crec - > machine ,
timestr ,
2015-11-30 13:20:43 +03:00
encryption ,
signing ) ;
2015-11-09 20:01:47 +03:00
TALLOC_FREE ( timestr ) ;
2001-08-22 23:11:55 +04:00
2015-11-09 19:26:51 +03:00
return result ;
2001-08-22 23:11:55 +04:00
}
2010-03-01 18:18:23 +03:00
static int traverse_sessionid ( const char * key , struct sessionid * session ,
void * private_data )
2001-08-22 23:11:55 +04:00
{
2015-11-19 12:40:29 +03:00
TALLOC_CTX * mem_ctx = ( TALLOC_CTX * ) private_data ;
2017-07-04 13:22:00 +03:00
fstring uid_gid_str ;
2015-04-23 19:06:17 +03:00
struct server_id_buf tmp ;
2015-11-09 19:02:38 +03:00
char * machine_hostname = NULL ;
2015-11-09 19:17:17 +03:00
int result = 0 ;
const char * encryption = " - " ;
2015-11-30 13:20:43 +03:00
const char * signing = " - " ;
2001-08-22 23:11:55 +04:00
2012-07-13 19:24:02 +04:00
if ( do_checks & &
( ! process_exists ( session - > pid ) | |
! Ucrit_checkUid ( session - > uid ) ) ) {
2001-08-22 23:11:55 +04:00
return 0 ;
1999-12-21 07:54:30 +03:00
}
2010-03-01 18:18:23 +03:00
Ucrit_addPid ( session - > pid ) ;
2003-11-13 01:35:50 +03:00
2017-07-04 13:22:00 +03:00
if ( numeric_only ) {
fstr_sprintf ( uid_gid_str , " %-12u %-12u " ,
( unsigned int ) session - > uid ,
( unsigned int ) session - > gid ) ;
} else {
if ( session - > uid = = - 1 & & session - > gid = = - 1 ) {
/*
* The session is not fully authenticated yet .
*/
fstrcpy ( uid_gid_str , " (auth in progress) " ) ;
2013-07-09 14:32:34 +04:00
} else {
2017-07-04 13:22:00 +03:00
/*
* In theory it should not happen that one of
* session - > uid and session - > gid is valid ( ie ! = - 1 )
* while the other is not ( ie = - 1 ) , so we a check for
* that case that bails out would be reasonable .
*/
const char * uid_name = " -1 " ;
const char * gid_name = " -1 " ;
if ( session - > uid ! = - 1 ) {
uid_name = uidtoname ( session - > uid ) ;
if ( uid_name = = NULL ) {
return - 1 ;
}
2017-11-22 12:43:19 +03:00
}
2017-07-04 13:22:00 +03:00
if ( session - > gid ! = - 1 ) {
gid_name = gidtoname ( session - > gid ) ;
if ( gid_name = = NULL ) {
return - 1 ;
}
2017-11-22 12:43:19 +03:00
}
2017-07-04 13:22:00 +03:00
fstr_sprintf ( uid_gid_str , " %-12s %-12s " ,
uid_name , gid_name ) ;
2013-07-09 14:32:34 +04:00
}
}
2004-12-17 11:51:23 +03:00
2015-11-09 19:02:38 +03:00
machine_hostname = talloc_asprintf ( mem_ctx , " %s (%s) " ,
session - > remote_machine ,
session - > hostname ) ;
if ( machine_hostname = = NULL ) {
return - 1 ;
}
2015-11-09 19:17:17 +03:00
if ( smbXsrv_is_encrypted ( session - > encryption_flags ) ) {
switch ( session - > cipher ) {
case SMB2_ENCRYPTION_AES128_CCM :
encryption = " AES-128-CCM " ;
break ;
case SMB2_ENCRYPTION_AES128_GCM :
encryption = " AES-128-GCM " ;
break ;
default :
encryption = " ??? " ;
result = - 1 ;
break ;
}
} else if ( smbXsrv_is_partially_encrypted ( session - > encryption_flags ) ) {
switch ( session - > cipher ) {
2015-11-30 19:03:26 +03:00
case SMB_ENCRYPTION_GSSAPI :
encryption = " partial(GSSAPI) " ;
break ;
2015-11-09 19:17:17 +03:00
case SMB2_ENCRYPTION_AES128_CCM :
encryption = " partial(AES-128-CCM) " ;
break ;
case SMB2_ENCRYPTION_AES128_GCM :
encryption = " partial(AES-128-GCM) " ;
break ;
default :
encryption = " ??? " ;
result = - 1 ;
break ;
}
}
2015-11-30 13:20:43 +03:00
if ( smbXsrv_is_signed ( session - > signing_flags ) ) {
if ( session - > connection_dialect > = SMB3_DIALECT_REVISION_302 ) {
signing = " AES-128-CMAC " ;
} else if ( session - > connection_dialect > = SMB2_DIALECT_REVISION_202 ) {
signing = " HMAC-SHA256 " ;
2015-11-30 19:03:26 +03:00
} else {
signing = " HMAC-MD5 " ;
2015-11-30 13:20:43 +03:00
}
} else if ( smbXsrv_is_partially_signed ( session - > signing_flags ) ) {
if ( session - > connection_dialect > = SMB3_DIALECT_REVISION_302 ) {
signing = " partial(AES-128-CMAC) " ;
} else if ( session - > connection_dialect > = SMB2_DIALECT_REVISION_202 ) {
signing = " partial(HMAC-SHA256) " ;
2015-11-30 19:03:26 +03:00
} else {
signing = " partial(HMAC-MD5) " ;
2015-11-30 13:20:43 +03:00
}
}
2017-07-04 13:22:00 +03:00
d_printf ( " %-7s %-25s %-41s %-17s %-20s %-21s \n " ,
2015-04-23 19:06:17 +03:00
server_id_str_buf ( session - > pid , & tmp ) ,
2017-07-04 13:22:00 +03:00
uid_gid_str ,
2015-11-09 19:02:38 +03:00
machine_hostname ,
2015-11-09 19:17:17 +03:00
session_dialect_str ( session - > connection_dialect ) ,
2015-11-30 13:20:43 +03:00
encryption ,
signing ) ;
2009-09-18 20:10:54 +04:00
2015-11-09 19:02:38 +03:00
TALLOC_FREE ( machine_hostname ) ;
2015-11-09 19:17:17 +03:00
return result ;
1999-12-21 07:54:30 +03:00
}
2015-01-09 15:48:56 +03:00
static bool print_notify_rec ( const char * path , struct server_id server ,
const struct notify_instance * instance ,
void * private_data )
2012-04-04 16:51:09 +04:00
{
2015-01-09 15:48:56 +03:00
struct server_id_buf idbuf ;
2012-04-04 16:51:09 +04:00
2015-01-09 15:48:56 +03:00
d_printf ( " %s \\ %s \\ %x \\ %x \n " , path , server_id_str_buf ( server , & idbuf ) ,
( unsigned ) instance - > filter ,
( unsigned ) instance - > subdir_filter ) ;
2012-04-04 16:51:09 +04:00
2015-01-09 15:48:56 +03:00
return true ;
2012-04-04 16:51:09 +04:00
}
1997-05-20 04:32:51 +04:00
2014-02-26 23:16:26 +04:00
int main ( int argc , const char * argv [ ] )
1996-05-04 11:50:46 +04:00
{
1999-12-21 07:54:30 +03:00
int c ;
2006-07-11 22:01:26 +04:00
int profile_only = 0 ;
2007-10-19 04:40:25 +04:00
bool show_processes , show_locks , show_shares ;
2012-04-04 16:51:09 +04:00
bool show_notify = false ;
2002-03-12 00:37:01 +03:00
poptContext pc ;
struct poptOption long_options [ ] = {
2002-10-28 22:50:06 +03:00
POPT_AUTOHELP
2007-10-19 22:38:36 +04:00
{ " processes " , ' p ' , POPT_ARG_NONE , NULL , ' p ' , " Show processes only " } ,
{ " verbose " , ' v ' , POPT_ARG_NONE , NULL , ' v ' , " Be verbose " } ,
{ " locks " , ' L ' , POPT_ARG_NONE , NULL , ' L ' , " Show locks only " } ,
{ " shares " , ' S ' , POPT_ARG_NONE , NULL , ' S ' , " Show shares only " } ,
2012-04-04 16:51:09 +04:00
{ " notify " , ' N ' , POPT_ARG_NONE , NULL , ' N ' , " Show notifies " } ,
2004-11-12 02:30:32 +03:00
{ " user " , ' u ' , POPT_ARG_STRING , & username , ' u ' , " Switch to user " } ,
2007-10-19 22:38:36 +04:00
{ " brief " , ' b ' , POPT_ARG_NONE , NULL , ' b ' , " Be brief " } ,
2006-07-11 22:01:26 +04:00
{ " profile " , ' P ' , POPT_ARG_NONE , NULL , ' P ' , " Do profiling " } ,
{ " profile-rates " , ' R ' , POPT_ARG_NONE , NULL , ' R ' , " Show call rates " } ,
2007-10-19 22:38:36 +04:00
{ " byterange " , ' B ' , POPT_ARG_NONE , NULL , ' B ' , " Include byte range locks " } ,
{ " numeric " , ' n ' , POPT_ARG_NONE , NULL , ' n ' , " Numeric uid/gid " } ,
2012-07-13 19:24:02 +04:00
{ " fast " , ' f ' , POPT_ARG_NONE , NULL , ' f ' , " Skip checks if processes still exist " } ,
2003-04-14 07:30:20 +04:00
POPT_COMMON_SAMBA
POPT_TABLEEND
2002-03-12 00:37:01 +03:00
} ;
2007-08-31 13:54:30 +04:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
int ret = 0 ;
2015-01-09 15:48:56 +03:00
struct messaging_context * msg_ctx = NULL ;
2014-11-02 22:21:49 +03:00
char * db_path ;
2014-11-24 19:46:27 +03:00
bool ok ;
2002-03-12 00:37:01 +03:00
2006-05-11 02:33:10 +04:00
sec_init ( ) ;
2015-03-21 22:00:06 +03:00
smb_init_locale ( ) ;
2005-12-29 01:48:54 +03:00
2010-10-29 07:19:32 +04:00
setup_logging ( argv [ 0 ] , DEBUG_STDERR ) ;
2015-07-09 01:15:38 +03:00
lp_set_cmdline ( " log level " , " 0 " ) ;
2009-09-18 20:10:54 +04:00
1999-12-21 07:54:30 +03:00
if ( getuid ( ) ! = geteuid ( ) ) {
2001-09-08 06:59:23 +04:00
d_printf ( " smbstatus should not be run setuid \n " ) ;
2007-08-31 13:54:30 +04:00
ret = 1 ;
goto done ;
1998-07-24 05:08:31 +04:00
}
2002-03-12 00:37:01 +03:00
2014-12-16 17:52:43 +03:00
if ( getuid ( ) ! = 0 ) {
d_printf ( " smbstatus only works as root! \n " ) ;
ret = 1 ;
goto done ;
}
2014-02-26 23:16:26 +04:00
pc = poptGetContext ( NULL , argc , argv , long_options ,
2002-03-12 00:37:01 +03:00
POPT_CONTEXT_KEEP_FIRST ) ;
2009-09-18 20:10:54 +04:00
2003-04-16 18:31:10 +04:00
while ( ( c = poptGetNextOpt ( pc ) ) ! = - 1 ) {
1999-12-21 07:54:30 +03:00
switch ( c ) {
2007-10-19 22:38:36 +04:00
case ' p ' :
processes_only = true ;
break ;
case ' v ' :
verbose = true ;
break ;
case ' L ' :
locks_only = true ;
break ;
case ' S ' :
shares_only = true ;
break ;
2012-04-04 16:51:09 +04:00
case ' N ' :
show_notify = true ;
break ;
2007-10-19 22:38:36 +04:00
case ' b ' :
brief = true ;
break ;
case ' u ' :
2004-12-17 11:51:23 +03:00
Ucrit_addUid ( nametouid ( poptGetOptArg ( pc ) ) ) ;
1999-12-21 07:54:30 +03:00
break ;
2006-07-11 22:01:26 +04:00
case ' P ' :
case ' R ' :
profile_only = c ;
2007-10-19 22:38:36 +04:00
break ;
case ' B ' :
show_brl = true ;
break ;
case ' n ' :
numeric_only = true ;
break ;
2012-07-13 19:24:02 +04:00
case ' f ' :
do_checks = false ;
break ;
1999-12-13 16:27:58 +03:00
}
1999-12-21 07:54:30 +03:00
}
2001-06-13 09:36:28 +04:00
2004-11-12 02:30:32 +03:00
/* setup the flags based on the possible combincations */
show_processes = ! ( shares_only | | locks_only | | profile_only ) | | processes_only ;
show_locks = ! ( shares_only | | processes_only | | profile_only ) | | locks_only ;
show_shares = ! ( processes_only | | locks_only | | profile_only ) | | shares_only ;
if ( username )
2004-12-17 11:51:23 +03:00
Ucrit_addUid ( nametouid ( username ) ) ;
2004-11-12 02:30:32 +03:00
1999-12-21 07:54:30 +03:00
if ( verbose ) {
2007-12-10 22:30:37 +03:00
d_printf ( " using configfile = %s \n " , get_dyn_CONFIGFILE ( ) ) ;
1999-12-21 07:54:30 +03:00
}
2002-10-28 22:50:06 +03:00
2018-08-21 01:46:27 +03:00
msg_ctx = cmdline_messaging_context ( get_dyn_CONFIGFILE ( ) ) ;
2015-11-10 19:59:09 +03:00
if ( msg_ctx = = NULL ) {
2018-08-21 01:46:27 +03:00
fprintf ( stderr , " Could not initialize messaging, not root? \n " ) ;
2015-11-10 19:59:09 +03:00
ret = - 1 ;
goto done ;
2008-06-13 14:00:24 +04:00
}
2011-07-28 12:39:45 +04:00
if ( ! lp_load_global ( get_dyn_CONFIGFILE ( ) ) ) {
2008-04-23 13:35:51 +04:00
fprintf ( stderr , " Can't load %s - run testparm to debug it \n " ,
get_dyn_CONFIGFILE ( ) ) ;
ret = - 1 ;
goto done ;
}
2006-07-11 22:01:26 +04:00
switch ( profile_only ) {
case ' P ' :
/* Dump profile data */
2014-11-24 19:46:27 +03:00
ok = status_profile_dump ( verbose ) ;
return ok ? 0 : 1 ;
2006-07-11 22:01:26 +04:00
case ' R ' :
/* Continuously display rate-converted data */
2014-11-24 19:46:27 +03:00
ok = status_profile_rates ( verbose ) ;
return ok ? 0 : 1 ;
2006-07-11 22:01:26 +04:00
default :
break ;
1999-12-21 07:54:30 +03:00
}
2006-07-11 22:01:26 +04:00
2004-11-12 02:30:32 +03:00
if ( show_processes ) {
2010-03-01 18:18:23 +03:00
d_printf ( " \n Samba version %s \n " , samba_version_string ( ) ) ;
2015-11-30 13:20:43 +03:00
d_printf ( " %-7s %-12s %-12s %-41s %-17s %-20s %-21s \n " , " PID " , " Username " , " Group " , " Machine " , " Protocol Version " , " Encryption " , " Signing " ) ;
d_printf ( " ---------------------------------------------------------------------------------------------------------------------------------------- \n " ) ;
2004-11-12 02:30:32 +03:00
2015-11-19 12:40:29 +03:00
sessionid_traverse_read ( traverse_sessionid , frame ) ;
2010-03-01 18:18:23 +03:00
2007-08-31 13:54:30 +04:00
if ( processes_only ) {
goto done ;
}
2001-09-11 02:31:59 +04:00
}
2009-09-18 20:10:54 +04:00
2004-11-12 02:30:32 +03:00
if ( show_shares ) {
2007-08-31 13:54:30 +04:00
if ( brief ) {
goto done ;
}
2009-09-18 20:10:54 +04:00
2015-11-30 13:20:43 +03:00
d_printf ( " \n %-12s %-7s %-13s %-32s %-12s %-12s \n " , " Service " , " pid " , " Machine " , " Connected at " , " Encryption " , " Signing " ) ;
d_printf ( " --------------------------------------------------------------------------------------------- \n " ) ;
2009-09-18 20:10:54 +04:00
2015-11-19 17:54:17 +03:00
connections_forall_read ( traverse_connections , frame ) ;
2004-11-12 02:30:32 +03:00
2007-05-08 17:44:36 +04:00
d_printf ( " \n " ) ;
1999-12-21 07:54:30 +03:00
2007-08-31 13:54:30 +04:00
if ( shares_only ) {
goto done ;
}
2001-09-11 02:31:59 +04:00
}
1999-12-21 07:54:30 +03:00
2004-11-12 02:30:32 +03:00
if ( show_locks ) {
2007-08-31 13:54:30 +04:00
int result ;
2007-10-21 19:05:34 +04:00
struct db_context * db ;
2014-11-02 22:21:49 +03:00
2018-08-16 11:51:44 +03:00
db_path = lock_path ( talloc_tos ( ) , " locking.tdb " ) ;
2014-11-02 22:21:49 +03:00
if ( db_path = = NULL ) {
d_printf ( " Out of memory - exiting \n " ) ;
ret = - 1 ;
goto done ;
}
db = db_open ( NULL , db_path , 0 ,
2012-01-06 20:19:54 +04:00
TDB_CLEAR_IF_FIRST | TDB_INCOMPATIBLE_HASH , O_RDONLY , 0 ,
2014-01-27 17:49:12 +04:00
DBWRAP_LOCK_ORDER_1 , DBWRAP_FLAG_NONE ) ;
2007-10-21 19:05:34 +04:00
if ( ! db ) {
2014-11-02 22:21:49 +03:00
d_printf ( " %s not initialised \n " , db_path ) ;
2007-10-21 19:05:34 +04:00
d_printf ( " This is normal if an SMB client has never "
" connected to your server. \n " ) ;
2014-11-02 22:21:49 +03:00
TALLOC_FREE ( db_path ) ;
2007-10-21 19:05:34 +04:00
exit ( 0 ) ;
} else {
TALLOC_FREE ( db ) ;
2014-11-02 22:21:49 +03:00
TALLOC_FREE ( db_path ) ;
2007-10-21 19:05:34 +04:00
}
1999-12-22 04:36:27 +03:00
2007-12-05 22:53:22 +03:00
if ( ! locking_init_readonly ( ) ) {
2001-09-08 06:59:23 +04:00
d_printf ( " Can't initialise locking module - exiting \n " ) ;
2007-08-31 13:54:30 +04:00
ret = 1 ;
goto done ;
1999-12-21 07:54:30 +03:00
}
2009-09-18 20:10:54 +04:00
2014-09-23 07:18:54 +04:00
result = share_entry_forall ( print_share_mode , NULL ) ;
1999-12-22 04:36:27 +03:00
2007-08-31 13:54:30 +04:00
if ( result = = 0 ) {
2001-09-08 06:59:23 +04:00
d_printf ( " No locked files \n " ) ;
2011-06-20 13:10:31 +04:00
} else if ( result < 0 ) {
2001-09-08 06:59:23 +04:00
d_printf ( " locked file list truncated \n " ) ;
1999-12-22 04:36:27 +03:00
}
2009-09-18 20:10:54 +04:00
2001-09-08 06:59:23 +04:00
d_printf ( " \n " ) ;
2000-01-16 14:14:44 +03:00
if ( show_brl ) {
2007-05-29 17:26:44 +04:00
brl_forall ( print_brl , NULL ) ;
2000-01-16 14:14:44 +03:00
}
2009-09-18 20:10:54 +04:00
1999-12-21 07:54:30 +03:00
locking_end ( ) ;
}
1997-05-20 04:32:51 +04:00
2012-04-04 16:51:09 +04:00
if ( show_notify ) {
struct notify_context * n ;
2015-01-09 15:48:56 +03:00
n = notify_init ( talloc_tos ( ) , msg_ctx ,
2016-06-14 15:54:32 +03:00
NULL , NULL ) ;
2012-04-04 16:51:09 +04:00
if ( n = = NULL ) {
goto done ;
}
2015-01-09 15:48:56 +03:00
notify_walk ( n , print_notify_rec , NULL ) ;
2012-04-04 16:51:09 +04:00
TALLOC_FREE ( n ) ;
}
2007-08-31 13:54:30 +04:00
done :
TALLOC_FREE ( frame ) ;
return ret ;
1996-05-04 11:50:46 +04:00
}