2019-05-02 22:33:46 +03:00
/*
* Copyright ( C ) 2019 , Ralph Boehme < slow @ samba . org . >
*
* This library 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 library 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 library ; if not , write to the
* Free Software Foundation , Inc . , 51 Franklin Street , Fifth Floor ,
* Boston , MA 02110 - 1301 , USA .
*/
# include "includes.h"
# include "lib/util/debug.h"
2021-01-13 12:44:57 +03:00
# include "lib/cmdline/cmdline.h"
2019-05-02 22:33:46 +03:00
# include "lib/cmdline_contexts.h"
# include "param.h"
# include "client.h"
# include "libsmb/proto.h"
# include "librpc/rpc/rpc_common.h"
# include "rpc_client/cli_pipe.h"
# include "rpc_client/cli_mdssvc.h"
# include "librpc/gen_ndr/ndr_mdssvc_c.h"
static char * opt_path ;
static int opt_live ;
int main ( int argc , char * * argv )
{
const char * * const_argv = discard_const_p ( const char * , argv ) ;
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2023-08-07 06:32:14 +03:00
struct loadparm_context * lp_ctx = NULL ;
2019-05-02 22:33:46 +03:00
struct tevent_context * ev = NULL ;
2019-11-11 16:45:43 +03:00
struct cli_credentials * creds = NULL ;
2019-05-02 22:33:46 +03:00
struct rpc_pipe_client * rpccli = NULL ;
struct mdscli_ctx * mdscli_ctx = NULL ;
struct mdscli_search_ctx * search = NULL ;
const char * server = NULL ;
const char * share = NULL ;
const char * mds_query = NULL ;
struct cli_state * cli = NULL ;
char * basepath = NULL ;
2020-05-28 18:22:12 +03:00
uint32_t flags = CLI_FULL_CONNECTION_IPC ;
2019-05-02 22:33:46 +03:00
uint64_t * cnids = NULL ;
size_t ncnids ;
size_t i ;
int opt ;
poptContext pc ;
NTSTATUS status ;
bool ok ;
2021-01-13 12:44:57 +03:00
struct poptOption long_options [ ] = {
POPT_AUTOHELP
{
. longName = " path " ,
. shortName = ' p ' ,
. argInfo = POPT_ARG_STRING ,
. arg = & opt_path ,
. descrip = " Server-relative search path " ,
} ,
{
. longName = " live " ,
. shortName = ' L ' ,
. argInfo = POPT_ARG_NONE ,
. arg = & opt_live ,
. descrip = " live query " ,
} ,
POPT_COMMON_SAMBA
POPT_COMMON_CREDENTIALS
POPT_LEGACY_S3
POPT_COMMON_VERSION
POPT_TABLEEND
} ;
2019-05-02 22:33:46 +03:00
smb_init_locale ( ) ;
2021-01-13 12:44:57 +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 ) ;
}
2023-08-07 06:32:14 +03:00
lp_ctx = samba_cmdline_get_lp_ctx ( ) ;
lpcfg_set_cmdline ( lp_ctx , " log level " , " 1 " ) ;
2019-05-02 22:33:46 +03:00
2021-01-13 12:44:57 +03:00
pc = samba_popt_get_context ( getprogname ( ) ,
argc ,
const_argv ,
long_options ,
POPT_CONTEXT_KEEP_FIRST ) ;
2019-05-02 22:33:46 +03:00
2020-07-05 00:16:40 +03:00
poptSetOtherOptionHelp ( pc , " mdsearch [OPTIONS] <server> <share> <query> \n " ) ;
2019-05-02 22:33:46 +03:00
while ( ( opt = poptGetNextOpt ( pc ) ) ! = - 1 ) {
DBG_ERR ( " Invalid option %s: %s \n " ,
poptBadOption ( pc , 0 ) ,
poptStrerror ( opt ) ) ;
poptPrintHelp ( pc , stderr , 0 ) ;
goto fail ;
}
poptGetArg ( pc ) ; /* Drop argv[0], the program name */
server = poptGetArg ( pc ) ;
share = poptGetArg ( pc ) ;
mds_query = poptGetArg ( pc ) ;
if ( server = = NULL | | mds_query = = NULL ) {
poptPrintHelp ( pc , stderr , 0 ) ;
goto fail ;
}
2021-01-13 12:44:57 +03:00
samba_cmdline_burn ( argc , argv ) ;
2019-05-02 22:33:46 +03:00
if ( ( server [ 0 ] = = ' / ' & & server [ 1 ] = = ' / ' ) | |
( server [ 0 ] = = ' \\ ' & & server [ 1 ] = = ' \\ ' ) )
{
server + = 2 ;
}
ev = samba_tevent_context_init ( frame ) ;
if ( ev = = NULL ) {
goto fail ;
}
cmdline_messaging_context ( get_dyn_CONFIGFILE ( ) ) ;
2021-01-13 12:44:57 +03:00
creds = samba_cmdline_get_creds ( ) ;
2019-05-02 22:33:46 +03:00
2023-11-23 17:07:53 +03:00
status = cli_full_connection_creds ( frame ,
& cli ,
2019-11-11 16:45:43 +03:00
lp_netbios_name ( ) ,
server ,
NULL ,
0 ,
" IPC$ " ,
" IPC " ,
creds ,
2020-06-04 15:59:14 +03:00
flags ) ;
2019-05-02 22:33:46 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
DBG_ERR ( " Cannot connect to server: %s \n " , nt_errstr ( status ) ) ;
2023-01-12 10:47:20 +03:00
goto fail_free_messaging ;
2019-05-02 22:33:46 +03:00
}
2021-03-15 19:27:21 +03:00
status = cli_rpc_pipe_open_noauth ( cli , & ndr_table_mdssvc , & rpccli ) ;
2019-05-02 22:33:46 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2023-01-12 10:47:20 +03:00
goto fail_free_messaging ;
2019-05-02 22:33:46 +03:00
}
status = mdscli_connect ( frame ,
rpccli - > binding_handle ,
share ,
" /foo/bar " ,
& mdscli_ctx ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Failed to connect mdssvc \n " ) ;
2023-01-12 10:47:20 +03:00
goto fail_free_messaging ;
2019-05-02 22:33:46 +03:00
}
if ( opt_path = = NULL ) {
basepath = mdscli_get_basepath ( frame , mdscli_ctx ) ;
} else {
basepath = talloc_strdup ( frame , opt_path ) ;
}
if ( basepath = = NULL ) {
2023-01-12 10:47:20 +03:00
goto fail_free_messaging ;
2019-05-02 22:33:46 +03:00
}
status = mdscli_search ( frame ,
mdscli_ctx ,
mds_query ,
basepath ,
opt_live = = 1 ? true : false ,
& search ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " mdscli_search failed \n " ) ;
2023-01-12 10:47:20 +03:00
goto fail_free_messaging ;
2019-05-02 22:33:46 +03:00
}
if ( ! opt_live ) {
sleep ( 1 ) ;
}
while ( true ) {
status = mdscli_get_results ( frame ,
search ,
& cnids ) ;
if ( NT_STATUS_EQUAL ( status , NT_STATUS_NO_MORE_MATCHES ) ) {
if ( opt_live ) {
sleep ( 1 ) ;
continue ;
}
break ;
}
2023-04-20 16:12:49 +03:00
ncnids = talloc_array_length ( cnids ) ;
if ( NT_STATUS_EQUAL ( status , NT_STATUS_PENDING ) & &
ncnids = = 0 )
{
sleep ( 1 ) ;
continue ;
}
2019-05-02 22:33:46 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " mdscli_get_results failed \n " ) ;
2023-01-12 10:47:20 +03:00
goto fail_free_messaging ;
2019-05-02 22:33:46 +03:00
}
if ( ncnids = = 0 ) {
break ;
}
for ( i = 0 ; i < ncnids ; i + + ) {
char * path = NULL ;
status = mdscli_get_path ( frame ,
mdscli_ctx ,
cnids [ i ] ,
& path ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Get path for CNID 0x% " PRIx64 " failed \n " ,
cnids [ i ] ) ;
2023-01-12 10:47:20 +03:00
goto fail_free_messaging ;
2019-05-02 22:33:46 +03:00
}
printf ( " %s \n " , path ) ;
TALLOC_FREE ( path ) ;
}
}
status = mdscli_close_search ( & search ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " mdscli_close_search failed \n " ) ;
2023-01-12 10:47:20 +03:00
goto fail_free_messaging ;
2019-05-02 22:33:46 +03:00
}
status = mdscli_disconnect ( mdscli_ctx ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " mdscli_disconnect failed \n " ) ;
2023-01-12 10:47:20 +03:00
goto fail_free_messaging ;
2019-05-02 22:33:46 +03:00
}
2020-12-24 14:38:18 +03:00
cmdline_messaging_context_free ( ) ;
2019-05-02 22:33:46 +03:00
TALLOC_FREE ( frame ) ;
poptFreeContext ( pc ) ;
return 0 ;
2023-01-12 10:47:20 +03:00
fail_free_messaging :
cmdline_messaging_context_free ( ) ;
2019-05-02 22:33:46 +03:00
fail :
2022-10-14 13:26:24 +03:00
poptFreeContext ( pc ) ;
2019-05-02 22:33:46 +03:00
TALLOC_FREE ( frame ) ;
return 1 ;
}