2006-02-04 01:19:41 +03:00
/*
* Unix SMB / CIFS implementation .
* Shell around net rpc subcommands
* Copyright ( C ) Volker Lendecke 2006
*
* 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
2006-02-04 01:19:41 +03: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 09:23:25 +04:00
* along with this program ; if not , see < http : //www.gnu.org/licenses/>.
2006-02-04 01:19:41 +03:00
*/
# include "includes.h"
# include "utils/net.h"
2008-05-10 01:22:12 +04:00
static NTSTATUS rpc_sh_info ( struct net_context * c ,
TALLOC_CTX * mem_ctx , struct rpc_sh_ctx * ctx ,
2006-02-04 01:19:41 +03:00
struct rpc_pipe_client * pipe_hnd ,
int argc , const char * * argv )
{
2008-05-10 01:22:12 +04:00
return rpc_info_internals ( c , ctx - > domain_sid , ctx - > domain_name ,
2006-02-04 01:19:41 +03:00
ctx - > cli , pipe_hnd , mem_ctx ,
argc , argv ) ;
}
static struct rpc_sh_ctx * this_ctx ;
static char * * completion_fn ( const char * text , int start , int end )
{
char * * cmds = NULL ;
int n_cmds = 0 ;
struct rpc_sh_cmd * c ;
if ( start ! = 0 ) {
return NULL ;
}
ADD_TO_ARRAY ( NULL , char * , SMB_STRDUP ( text ) , & cmds , & n_cmds ) ;
for ( c = this_ctx - > cmds ; c - > name ! = NULL ; c + + ) {
2007-10-19 04:40:25 +04:00
bool match = ( strncmp ( text , c - > name , strlen ( text ) ) = = 0 ) ;
2006-02-04 01:19:41 +03:00
if ( match ) {
ADD_TO_ARRAY ( NULL , char * , SMB_STRDUP ( c - > name ) ,
& cmds , & n_cmds ) ;
}
}
if ( n_cmds = = 2 ) {
SAFE_FREE ( cmds [ 0 ] ) ;
cmds [ 0 ] = cmds [ 1 ] ;
n_cmds - = 1 ;
}
ADD_TO_ARRAY ( NULL , char * , NULL , & cmds , & n_cmds ) ;
return cmds ;
}
2008-05-10 01:22:12 +04:00
static NTSTATUS net_sh_run ( struct net_context * c ,
struct rpc_sh_ctx * ctx , struct rpc_sh_cmd * cmd ,
2006-02-04 01:19:41 +03:00
int argc , const char * * argv )
{
TALLOC_CTX * mem_ctx ;
struct rpc_pipe_client * pipe_hnd ;
NTSTATUS status ;
mem_ctx = talloc_new ( ctx ) ;
if ( mem_ctx = = NULL ) {
d_fprintf ( stderr , " talloc_new failed \n " ) ;
return NT_STATUS_NO_MEMORY ;
}
2008-07-20 20:40:31 +04:00
status = cli_rpc_pipe_open_noauth ( ctx - > cli , cmd - > interface ,
2008-07-20 13:04:31 +04:00
& pipe_hnd ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2006-02-04 01:19:41 +03:00
d_fprintf ( stderr , " Could not open pipe: %s \n " ,
nt_errstr ( status ) ) ;
return status ;
}
2008-05-10 01:22:12 +04:00
status = cmd - > fn ( c , mem_ctx , ctx , pipe_hnd , argc , argv ) ;
2006-02-04 01:19:41 +03:00
2008-04-20 15:51:46 +04:00
TALLOC_FREE ( pipe_hnd ) ;
2006-02-04 01:19:41 +03:00
talloc_destroy ( mem_ctx ) ;
return status ;
}
2008-05-10 01:22:12 +04:00
static bool net_sh_process ( struct net_context * c ,
struct rpc_sh_ctx * ctx ,
2006-02-04 01:19:41 +03:00
int argc , const char * * argv )
{
2008-05-10 01:22:12 +04:00
struct rpc_sh_cmd * cmd ;
2006-02-04 01:19:41 +03:00
struct rpc_sh_ctx * new_ctx ;
NTSTATUS status ;
if ( argc = = 0 ) {
2008-05-12 13:53:23 +04:00
return true ;
2006-02-04 01:19:41 +03:00
}
if ( ctx = = this_ctx ) {
/* We've been called from the cmd line */
if ( strequal ( argv [ 0 ] , " .. " ) & &
( this_ctx - > parent ! = NULL ) ) {
new_ctx = this_ctx - > parent ;
2006-02-20 20:59:58 +03:00
TALLOC_FREE ( this_ctx ) ;
2006-02-04 01:19:41 +03:00
this_ctx = new_ctx ;
2008-05-12 13:53:23 +04:00
return true ;
2006-02-04 01:19:41 +03:00
}
}
2006-06-19 14:02:04 +04:00
if ( strequal ( argv [ 0 ] , " exit " ) | | strequal ( argv [ 0 ] , " quit " ) ) {
2008-05-12 13:53:23 +04:00
return false ;
2006-06-19 14:02:04 +04:00
}
2006-02-04 01:19:41 +03:00
if ( strequal ( argv [ 0 ] , " help " ) | | strequal ( argv [ 0 ] , " ? " ) ) {
2008-05-10 01:22:12 +04:00
for ( cmd = ctx - > cmds ; cmd - > name ! = NULL ; cmd + + ) {
2006-02-04 01:19:41 +03:00
if ( ctx ! = this_ctx ) {
d_printf ( " %s " , ctx - > whoami ) ;
}
2008-05-10 01:22:12 +04:00
d_printf ( " %-15s %s \n " , cmd - > name , cmd - > help ) ;
2006-02-04 01:19:41 +03:00
}
2008-05-12 13:53:23 +04:00
return true ;
2006-02-04 01:19:41 +03:00
}
2008-05-10 01:22:12 +04:00
for ( cmd = ctx - > cmds ; cmd - > name ! = NULL ; cmd + + ) {
if ( strequal ( cmd - > name , argv [ 0 ] ) ) {
2006-02-04 01:19:41 +03:00
break ;
}
}
2008-05-10 01:22:12 +04:00
if ( cmd - > name = = NULL ) {
2006-02-04 01:19:41 +03:00
/* None found */
d_fprintf ( stderr , " %s: unknown cmd \n " , argv [ 0 ] ) ;
2008-05-12 13:53:23 +04:00
return true ;
2006-02-04 01:19:41 +03:00
}
new_ctx = TALLOC_P ( ctx , struct rpc_sh_ctx ) ;
if ( new_ctx = = NULL ) {
d_fprintf ( stderr , " talloc failed \n " ) ;
2008-05-12 13:53:23 +04:00
return false ;
2006-02-04 01:19:41 +03:00
}
new_ctx - > cli = ctx - > cli ;
new_ctx - > whoami = talloc_asprintf ( new_ctx , " %s %s " ,
2008-05-10 01:22:12 +04:00
ctx - > whoami , cmd - > name ) ;
new_ctx - > thiscmd = talloc_strdup ( new_ctx , cmd - > name ) ;
2006-02-04 01:19:41 +03:00
2008-05-10 01:22:12 +04:00
if ( cmd - > sub ! = NULL ) {
new_ctx - > cmds = cmd - > sub ( c , new_ctx , ctx ) ;
2006-02-04 01:19:41 +03:00
} else {
new_ctx - > cmds = NULL ;
}
new_ctx - > parent = ctx ;
new_ctx - > domain_name = ctx - > domain_name ;
new_ctx - > domain_sid = ctx - > domain_sid ;
argc - = 1 ;
argv + = 1 ;
2008-05-10 01:22:12 +04:00
if ( cmd - > sub ! = NULL ) {
2006-02-04 01:19:41 +03:00
if ( argc = = 0 ) {
this_ctx = new_ctx ;
2008-05-12 13:53:23 +04:00
return true ;
2006-02-04 01:19:41 +03:00
}
2008-05-10 01:22:12 +04:00
return net_sh_process ( c , new_ctx , argc , argv ) ;
2006-02-04 01:19:41 +03:00
}
2008-05-10 01:22:12 +04:00
status = net_sh_run ( c , new_ctx , cmd , argc , argv ) ;
2006-02-04 01:19:41 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_fprintf ( stderr , " %s failed: %s \n " , new_ctx - > whoami ,
nt_errstr ( status ) ) ;
}
2008-05-12 13:53:23 +04:00
return true ;
2006-02-04 01:19:41 +03:00
}
2006-02-21 00:58:33 +03:00
static struct rpc_sh_cmd sh_cmds [ 6 ] = {
2008-07-20 20:40:31 +04:00
{ " info " , NULL , & ndr_table_samr . syntax_id , rpc_sh_info ,
2006-02-21 00:58:33 +03:00
" Print information about the domain connected to " } ,
{ " rights " , net_rpc_rights_cmds , 0 , NULL ,
" List/Grant/Revoke user rights " } ,
{ " share " , net_rpc_share_cmds , 0 , NULL ,
" List/Add/Remove etc shares " } ,
{ " user " , net_rpc_user_cmds , 0 , NULL ,
" List/Add/Remove user info " } ,
{ " account " , net_rpc_acct_cmds , 0 , NULL ,
" Show/Change account policy settings " } ,
{ NULL , NULL , 0 , NULL , NULL }
} ;
2008-05-10 01:22:12 +04:00
int net_rpc_shell ( struct net_context * c , int argc , const char * * argv )
2006-02-04 01:19:41 +03:00
{
NTSTATUS status ;
struct rpc_sh_ctx * ctx ;
2008-05-21 12:27:59 +04:00
if ( argc ! = 0 | | c - > display_usage ) {
d_printf ( " Usage: \n "
" net rpc shell \n " ) ;
2006-02-04 01:19:41 +03:00
return - 1 ;
}
2008-08-27 15:54:49 +04:00
if ( libnetapi_init ( & c - > netapi_ctx ) ! = 0 ) {
return - 1 ;
}
2009-07-05 11:21:07 +04:00
libnetapi_set_username ( c - > netapi_ctx , c - > opt_user_name ) ;
libnetapi_set_password ( c - > netapi_ctx , c - > opt_password ) ;
if ( c - > opt_kerberos ) {
2008-08-27 15:54:49 +04:00
libnetapi_set_use_kerberos ( c - > netapi_ctx ) ;
}
2006-02-04 01:19:41 +03:00
ctx = TALLOC_P ( NULL , struct rpc_sh_ctx ) ;
if ( ctx = = NULL ) {
d_fprintf ( stderr , " talloc failed \n " ) ;
return - 1 ;
}
2008-05-10 01:22:12 +04:00
status = net_make_ipc_connection ( c , 0 , & ( ctx - > cli ) ) ;
2007-09-17 19:11:20 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_fprintf ( stderr , " Could not open connection: %s \n " ,
nt_errstr ( status ) ) ;
2006-02-04 01:19:41 +03:00
return - 1 ;
}
ctx - > cmds = sh_cmds ;
ctx - > whoami = " net rpc " ;
ctx - > parent = NULL ;
status = net_get_remote_domain_sid ( ctx - > cli , ctx , & ctx - > domain_sid ,
& ctx - > domain_name ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return - 1 ;
}
d_printf ( " Talking to domain %s (%s) \n " , ctx - > domain_name ,
2007-12-15 23:53:26 +03:00
sid_string_tos ( ctx - > domain_sid ) ) ;
2007-12-07 04:16:33 +03:00
2006-02-04 01:19:41 +03:00
this_ctx = ctx ;
while ( 1 ) {
2007-12-07 04:16:33 +03:00
char * prompt = NULL ;
char * line = NULL ;
2006-02-04 01:19:41 +03:00
int ret ;
2007-12-07 04:16:33 +03:00
if ( asprintf ( & prompt , " %s> " , this_ctx - > whoami ) < 0 ) {
break ;
}
2006-02-04 01:19:41 +03:00
line = smb_readline ( prompt , NULL , completion_fn ) ;
SAFE_FREE ( prompt ) ;
if ( line = = NULL ) {
break ;
}
ret = poptParseArgvString ( line , & argc , & argv ) ;
2006-02-05 00:44:57 +03:00
if ( ret = = POPT_ERROR_NOARG ) {
2007-12-07 04:16:33 +03:00
SAFE_FREE ( line ) ;
2006-02-05 00:44:57 +03:00
continue ;
}
2006-02-04 01:19:41 +03:00
if ( ret ! = 0 ) {
d_fprintf ( stderr , " cmdline invalid: %s \n " ,
poptStrerror ( ret ) ) ;
2007-12-07 04:16:33 +03:00
SAFE_FREE ( line ) ;
2008-05-12 13:53:23 +04:00
return false ;
2006-02-04 01:19:41 +03:00
}
if ( ( line [ 0 ] ! = ' \n ' ) & &
2008-05-10 01:22:12 +04:00
( ! net_sh_process ( c , this_ctx , argc , argv ) ) ) {
2007-12-07 04:16:33 +03:00
SAFE_FREE ( line ) ;
2006-02-04 01:19:41 +03:00
break ;
}
2007-12-07 04:16:33 +03:00
SAFE_FREE ( line ) ;
2006-02-04 01:19:41 +03:00
}
cli_shutdown ( ctx - > cli ) ;
2006-02-20 20:59:58 +03:00
TALLOC_FREE ( ctx ) ;
2006-02-04 01:19:41 +03:00
return 0 ;
}