2023-10-24 13:04:19 +03:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
2001-07-06 14:49:34 +04:00
Network neighbourhood browser .
2023-10-24 13:04:19 +03:00
2001-07-06 14:49:34 +04:00
Copyright ( C ) Tim Potter 2000
2003-04-14 07:30:20 +04:00
Copyright ( C ) Jelmer Vernooij 2003
2023-10-24 13:04:19 +03:00
2001-07-06 14:49:34 +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
2001-07-06 14:49:34 +04:00
( at your option ) any later version .
2023-10-24 13:04:19 +03:00
2001-07-06 14:49:34 +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 .
2023-10-24 13:04:19 +03:00
2001-07-06 14:49:34 +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/>.
2001-07-06 14:49:34 +04:00
*/
# include "includes.h"
2021-01-13 16:43:17 +03:00
# include "lib/cmdline/cmdline.h"
2011-02-28 12:19:44 +03:00
# include "rpc_client/cli_pipe.h"
2011-01-12 15:01:57 +03:00
# include "../librpc/gen_ndr/ndr_srvsvc_c.h"
2011-05-06 13:47:43 +04:00
# include "libsmb/libsmb.h"
2018-03-10 17:31:11 +03:00
# include "libsmb/namequery.h"
2011-02-24 12:46:55 +03:00
# include "libsmb/clirap.h"
2019-10-29 22:11:49 +03:00
# include "../libcli/smb/smbXcli_base.h"
2020-04-05 14:01:07 +03:00
# include "nameserv.h"
2020-04-11 20:54:11 +03:00
# include "libsmbclient.h"
2001-08-20 21:38:37 +04:00
2001-07-06 14:49:34 +04:00
/* How low can we go? */
enum tree_level { LEV_WORKGROUP , LEV_SERVER , LEV_SHARE } ;
2002-08-17 18:45:04 +04:00
static enum tree_level level = LEV_SHARE ;
2001-07-06 14:49:34 +04:00
2020-04-11 20:54:11 +03:00
static void get_auth_data_with_context_fn (
SMBCCTX * context ,
const char * server ,
const char * share ,
char * domain ,
int domain_len ,
char * user ,
int user_len ,
char * password ,
int password_len )
2001-07-06 14:49:34 +04:00
{
2021-01-13 16:43:17 +03:00
struct cli_credentials * creds = samba_cmdline_get_creds ( ) ;
2020-04-11 20:54:11 +03:00
size_t len ;
2001-07-06 14:49:34 +04:00
2021-01-13 16:43:17 +03:00
len = strlcpy ( domain , cli_credentials_get_domain ( creds ) , domain_len ) ;
2020-04-11 20:54:11 +03:00
if ( ( int ) len > = domain_len ) {
return ;
2006-05-16 05:21:16 +04:00
}
2020-04-11 20:54:11 +03:00
len = strlcpy (
2021-01-13 16:43:17 +03:00
user , cli_credentials_get_username ( creds ) , user_len ) ;
2020-04-11 20:54:11 +03:00
if ( ( int ) len > = user_len ) {
return ;
2006-05-16 05:21:16 +04:00
}
2020-04-11 20:54:11 +03:00
len = strlcpy (
2021-01-13 16:43:17 +03:00
password , cli_credentials_get_password ( creds ) , password_len ) ;
2020-04-11 20:54:11 +03:00
if ( ( int ) len > = password_len ) {
/* pointless, but what can you do... */
return ;
2019-10-29 22:11:49 +03:00
}
2001-07-06 14:49:34 +04:00
}
/****************************************************************************
main program
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2014-02-26 23:16:26 +04:00
int main ( int argc , char * argv [ ] )
2001-07-06 14:49:34 +04:00
{
2007-09-04 09:39:06 +04:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2014-02-26 23:16:26 +04:00
const char * * argv_const = discard_const_p ( const char * , argv ) ;
2003-04-14 07:30:20 +04:00
struct poptOption long_options [ ] = {
POPT_AUTOHELP
2019-01-11 16:53:36 +03:00
{
. longName = " domains " ,
. shortName = ' D ' ,
. argInfo = POPT_ARG_VAL ,
. arg = & level ,
. val = LEV_WORKGROUP ,
. descrip = " List only domains (workgroups) of tree " ,
} ,
{
. longName = " servers " ,
. shortName = ' S ' ,
. argInfo = POPT_ARG_VAL ,
. arg = & level ,
. val = LEV_SERVER ,
. descrip = " List domains(workgroups) and servers of tree " ,
} ,
2003-04-14 07:30:20 +04:00
POPT_COMMON_SAMBA
POPT_COMMON_CREDENTIALS
2021-01-13 16:43:17 +03:00
POPT_COMMON_VERSION
2003-04-14 07:30:20 +04:00
POPT_TABLEEND
} ;
poptContext pc ;
2020-04-11 20:54:11 +03:00
SMBCCTX * ctx = NULL ;
SMBCFILE * workgroups = NULL ;
struct smbc_dirent * dirent = NULL ;
bool ok ;
int ret , result = 1 ;
2021-09-10 08:13:48 +03:00
int opt ;
2020-04-11 20:54:11 +03:00
int debuglevel ;
2007-12-04 05:48:41 +03:00
2001-07-06 14:49:34 +04:00
/* Initialise samba stuff */
2015-03-21 22:00:06 +03:00
smb_init_locale ( ) ;
2001-07-06 14:49:34 +04:00
setlinebuf ( stdout ) ;
2021-01-13 16:43:17 +03:00
ok = samba_cmdline_init ( frame ,
SAMBA_CMDLINE_CONFIG_CLIENT ,
false /* require_smbconf */ ) ;
if ( ! ok ) {
DBG_ERR ( " Failed to init cmdline parser! \n " ) ;
TALLOC_FREE ( frame ) ;
exit ( 1 ) ;
}
2001-07-06 14:49:34 +04:00
2021-01-13 16:43:17 +03:00
pc = samba_popt_get_context ( getprogname ( ) ,
argc ,
argv_const ,
long_options ,
POPT_CONTEXT_KEEP_FIRST ) ;
if ( pc = = NULL ) {
DBG_ERR ( " Failed to setup popt context! \n " ) ;
TALLOC_FREE ( frame ) ;
exit ( 1 ) ;
}
2016-12-09 18:04:38 +03:00
2021-09-10 08:13:48 +03:00
while ( ( opt = poptGetNextOpt ( pc ) ) ! = - 1 ) {
switch ( opt ) {
case POPT_ERROR_BADOPT :
fprintf ( stderr , " \n Invalid option %s: %s \n \n " ,
poptBadOption ( pc , 0 ) , poptStrerror ( opt ) ) ;
poptPrintUsage ( pc , stderr , 0 ) ;
exit ( 1 ) ;
}
}
2021-01-13 16:43:17 +03:00
samba_cmdline_burn ( argc , argv ) ;
2003-04-14 07:30:20 +04:00
2020-04-11 20:54:11 +03:00
debuglevel = DEBUGLEVEL ;
ctx = smbc_new_context ( ) ;
if ( ctx = = NULL ) {
perror ( " smbc_new_context " ) ;
goto fail ;
}
ret = smbc_setConfiguration ( ctx , get_dyn_CONFIGFILE ( ) ) ;
if ( ret = = - 1 ) {
perror ( " smbc_setConfiguration " ) ;
goto fail ;
}
smbc_setDebug ( ctx , debuglevel ) ;
ok = smbc_setOptionProtocols ( ctx , NULL , " NT1 " ) ;
if ( ! ok ) {
perror ( " smbc_setOptionProtocols " ) ;
goto fail ;
}
smbc_setFunctionAuthDataWithContext (
ctx , get_auth_data_with_context_fn ) ;
2001-07-06 14:49:34 +04:00
2020-04-11 20:54:11 +03:00
ok = smbc_init_context ( ctx ) ;
if ( ! ok ) {
perror ( " smbc_init_context " ) ;
goto fail ;
}
workgroups = smbc_getFunctionOpendir ( ctx ) ( ctx , " smb:// " ) ;
if ( workgroups = = NULL ) {
2021-07-14 12:38:39 +03:00
DBG_ERR ( " This is utility doesn't work if netbios name "
" resolution is not configured. \n "
" If you are using SMB2 or SMB3, network browsing uses "
" WSD/LLMNR, which is not yet supported by Samba. SMB1 "
" is disabled by default on the latest Windows versions "
" for security reasons. It is still possible to access "
" the Samba resources directly via \\ name or "
" \\ ip.address. \n " ) ;
2020-04-11 20:54:11 +03:00
goto fail ;
}
while ( ( dirent = smbc_getFunctionReaddir ( ctx ) ( ctx , workgroups ) )
! = NULL ) {
char * url = NULL ;
SMBCFILE * servers = NULL ;
if ( dirent - > smbc_type ! = SMBC_WORKGROUP ) {
continue ;
}
printf ( " %s \n " , dirent - > name ) ;
if ( level = = LEV_WORKGROUP ) {
continue ;
}
url = talloc_asprintf (
talloc_tos ( ) , " smb://%s/ " , dirent - > name ) ;
if ( url = = NULL ) {
perror ( " talloc_asprintf " ) ;
goto fail ;
}
servers = smbc_getFunctionOpendir ( ctx ) ( ctx , url ) ;
if ( servers = = NULL ) {
perror ( " smbc_opendir " ) ;
goto fail ;
}
TALLOC_FREE ( url ) ;
while ( ( dirent = smbc_getFunctionReaddir ( ctx ) ( ctx , servers ) )
! = NULL ) {
SMBCFILE * shares = NULL ;
char * servername = NULL ;
if ( dirent - > smbc_type ! = SMBC_SERVER ) {
continue ;
}
printf ( " \t \\ \\ %-15s \t \t %s \n " ,
dirent - > name ,
dirent - > comment ) ;
if ( level = = LEV_SERVER ) {
continue ;
}
/*
* The subsequent readdir for shares will
* overwrite the " server " readdir
*/
servername = talloc_strdup ( talloc_tos ( ) , dirent - > name ) ;
if ( servername = = NULL ) {
continue ;
}
url = talloc_asprintf (
talloc_tos ( ) , " smb://%s/ " , servername ) ;
if ( url = = NULL ) {
perror ( " talloc_asprintf " ) ;
goto fail ;
}
shares = smbc_getFunctionOpendir ( ctx ) ( ctx , url ) ;
if ( shares = = NULL ) {
perror ( " smbc_opendir " ) ;
goto fail ;
}
while ( ( dirent = smbc_getFunctionReaddir (
ctx ) ( ctx , shares ) )
! = NULL ) {
printf ( " \t \t \\ \\ %s \\ %-15s \t %s \n " ,
servername ,
dirent - > name ,
dirent - > comment ) ;
}
ret = smbc_getFunctionClosedir ( ctx ) ( ctx , shares ) ;
if ( ret = = - 1 ) {
perror ( " smbc_closedir " ) ;
goto fail ;
}
TALLOC_FREE ( servername ) ;
TALLOC_FREE ( url ) ;
}
ret = smbc_getFunctionClosedir ( ctx ) ( ctx , servers ) ;
if ( ret = = - 1 ) {
perror ( " smbc_closedir " ) ;
goto fail ;
}
}
ret = smbc_getFunctionClosedir ( ctx ) ( ctx , workgroups ) ;
if ( ret = = - 1 ) {
perror ( " smbc_closedir " ) ;
2020-04-11 20:03:39 +03:00
goto fail ;
2007-09-04 09:39:06 +04:00
}
2001-07-06 14:49:34 +04:00
2020-04-11 20:03:39 +03:00
result = 0 ;
fail :
2020-04-11 20:54:11 +03:00
if ( ctx ! = NULL ) {
smbc_free_context ( ctx , 0 ) ;
ctx = NULL ;
}
2023-10-24 13:04:19 +03:00
gfree_all ( ) ;
2019-08-19 14:29:03 +03:00
poptFreeContext ( pc ) ;
2007-09-04 09:39:06 +04:00
TALLOC_FREE ( frame ) ;
2020-04-11 20:03:39 +03:00
return result ;
2001-07-06 14:49:34 +04:00
}