2005-03-24 07:25:49 +03:00
/*
* Unix SMB / CIFS implementation .
* RPC Pipe client / server routines
* Copyright ( C ) Gerald Carter 2005.
*
* 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 .
*/
# include "includes.h"
2005-03-24 21:05:31 +03:00
# include "rpc_client.h"
2005-03-24 20:11:51 +03:00
2005-03-25 01:32:31 +03:00
struct svc_state_msg {
uint32 flag ;
const char * message ;
} ;
static struct svc_state_msg state_msg_table [ ] = {
2005-03-25 03:38:30 +03:00
{ SVCCTL_STOPPED , " stopped " } ,
{ SVCCTL_START_PENDING , " start pending " } ,
{ SVCCTL_STOP_PENDING , " stop pending " } ,
{ SVCCTL_RUNNING , " running " } ,
{ SVCCTL_CONTINUE_PENDING , " resume pending " } ,
{ SVCCTL_PAUSE_PENDING , " pause pending " } ,
{ SVCCTL_PAUSED , " paused " } ,
2005-03-25 01:32:31 +03:00
{ 0 , NULL }
} ;
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
const char * svc_status_string ( uint32 state )
{
static fstring msg ;
int i ;
fstr_sprintf ( msg , " Unknown State [%d] " , state ) ;
for ( i = 0 ; state_msg_table [ i ] . message ; i + + ) {
if ( state_msg_table [ i ] . flag = = state ) {
fstrcpy ( msg , state_msg_table [ i ] . message ) ;
break ;
}
}
return msg ;
}
2005-03-24 20:11:51 +03:00
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-03-24 19:11:23 +03:00
2005-09-30 21:13:37 +04:00
WERROR rpccli_svcctl_open_scm ( struct rpc_pipe_client * cli , TALLOC_CTX * mem_ctx ,
2005-03-24 20:11:51 +03:00
POLICY_HND * hSCM , uint32 access_desired )
2005-03-24 19:11:23 +03:00
{
2005-03-24 20:11:51 +03:00
SVCCTL_Q_OPEN_SCMANAGER in ;
SVCCTL_R_OPEN_SCMANAGER out ;
2005-03-24 19:11:23 +03:00
prs_struct qbuf , rbuf ;
2005-03-24 20:11:51 +03:00
fstring server ;
ZERO_STRUCT ( in ) ;
ZERO_STRUCT ( out ) ;
2005-03-24 19:11:23 +03:00
2005-03-24 20:11:51 +03:00
/* leave the database name NULL to get the default service db */
2005-03-24 19:11:23 +03:00
2005-03-24 20:11:51 +03:00
in . database = NULL ;
2005-03-24 19:11:23 +03:00
2005-03-24 20:11:51 +03:00
/* set the server name */
2005-03-24 19:11:23 +03:00
2005-03-24 20:11:51 +03:00
if ( ! ( in . servername = TALLOC_P ( mem_ctx , UNISTR2 ) ) )
return WERR_NOMEM ;
2005-09-30 21:13:37 +04:00
fstr_sprintf ( server , " \\ \\ %s " , cli - > cli - > desthost ) ;
2005-03-24 20:11:51 +03:00
init_unistr2 ( in . servername , server , UNI_STR_TERMINATE ) ;
2005-03-24 19:11:23 +03:00
2005-03-24 20:11:51 +03:00
in . access = access_desired ;
2005-09-30 21:13:37 +04:00
CLI_DO_RPC_WERR ( cli , mem_ctx , PI_SVCCTL , SVCCTL_OPEN_SCMANAGER_W ,
2005-03-24 20:11:51 +03:00
in , out ,
qbuf , rbuf ,
svcctl_io_q_open_scmanager ,
svcctl_io_r_open_scmanager ,
WERR_GENERAL_FAILURE ) ;
if ( ! W_ERROR_IS_OK ( out . status ) )
return out . status ;
memcpy ( hSCM , & out . handle , sizeof ( POLICY_HND ) ) ;
return out . status ;
2005-03-24 19:11:23 +03:00
}
2005-03-24 07:25:49 +03:00
2005-03-24 20:11:51 +03:00
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-03-24 07:25:49 +03:00
2005-09-30 21:13:37 +04:00
WERROR rpccli_svcctl_open_service ( struct rpc_pipe_client * cli , TALLOC_CTX * mem_ctx ,
2005-03-25 01:32:31 +03:00
POLICY_HND * hSCM , POLICY_HND * hService ,
const char * servicename , uint32 access_desired )
{
SVCCTL_Q_OPEN_SERVICE in ;
SVCCTL_R_OPEN_SERVICE out ;
prs_struct qbuf , rbuf ;
ZERO_STRUCT ( in ) ;
ZERO_STRUCT ( out ) ;
memcpy ( & in . handle , hSCM , sizeof ( POLICY_HND ) ) ;
init_unistr2 ( & in . servicename , servicename , UNI_STR_TERMINATE ) ;
in . access = access_desired ;
2005-09-30 21:13:37 +04:00
CLI_DO_RPC_WERR ( cli , mem_ctx , PI_SVCCTL , SVCCTL_OPEN_SERVICE_W ,
2005-03-25 01:32:31 +03:00
in , out ,
qbuf , rbuf ,
svcctl_io_q_open_service ,
svcctl_io_r_open_service ,
WERR_GENERAL_FAILURE ) ;
if ( ! W_ERROR_IS_OK ( out . status ) )
return out . status ;
memcpy ( hService , & out . handle , sizeof ( POLICY_HND ) ) ;
return out . status ;
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-09-30 21:13:37 +04:00
WERROR rpccli_svcctl_close_service ( struct rpc_pipe_client * cli , TALLOC_CTX * mem_ctx , POLICY_HND * hService )
2005-03-24 07:25:49 +03:00
{
2005-03-24 20:11:51 +03:00
SVCCTL_Q_CLOSE_SERVICE in ;
SVCCTL_R_CLOSE_SERVICE out ;
2005-03-24 19:11:23 +03:00
prs_struct qbuf , rbuf ;
2005-03-24 20:11:51 +03:00
ZERO_STRUCT ( in ) ;
ZERO_STRUCT ( out ) ;
memcpy ( & in . handle , hService , sizeof ( POLICY_HND ) ) ;
2005-09-30 21:13:37 +04:00
CLI_DO_RPC_WERR ( cli , mem_ctx , PI_SVCCTL , SVCCTL_CLOSE_SERVICE ,
2005-03-24 20:11:51 +03:00
in , out ,
qbuf , rbuf ,
svcctl_io_q_close_service ,
svcctl_io_r_close_service ,
WERR_GENERAL_FAILURE ) ;
return out . status ;
2005-03-24 19:11:23 +03:00
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-09-30 21:13:37 +04:00
WERROR rpccli_svcctl_enumerate_services ( struct rpc_pipe_client * cli , TALLOC_CTX * mem_ctx ,
2005-03-24 19:11:23 +03:00
POLICY_HND * hSCM , uint32 type , uint32 state ,
2005-03-24 21:05:31 +03:00
uint32 * returned , ENUM_SERVICES_STATUS * * service_array )
2005-03-24 19:11:23 +03:00
{
2005-03-24 20:11:51 +03:00
SVCCTL_Q_ENUM_SERVICES_STATUS in ;
SVCCTL_R_ENUM_SERVICES_STATUS out ;
2005-03-24 19:11:23 +03:00
prs_struct qbuf , rbuf ;
2005-03-24 21:05:31 +03:00
uint32 resume = 0 ;
ENUM_SERVICES_STATUS * services ;
int i ;
2005-03-24 19:11:23 +03:00
2005-03-24 20:11:51 +03:00
ZERO_STRUCT ( in ) ;
ZERO_STRUCT ( out ) ;
2005-03-24 21:05:31 +03:00
/* setup the request */
memcpy ( & in . handle , hSCM , sizeof ( POLICY_HND ) ) ;
in . type = type ;
in . state = state ;
in . resume = & resume ;
/* first time is to get the buffer size */
in . buffer_size = 0 ;
2005-03-24 19:11:23 +03:00
2005-09-30 21:13:37 +04:00
CLI_DO_RPC_WERR ( cli , mem_ctx , PI_SVCCTL , SVCCTL_ENUM_SERVICES_STATUS_W ,
2005-03-24 20:11:51 +03:00
in , out ,
qbuf , rbuf ,
svcctl_io_q_enum_services_status ,
svcctl_io_r_enum_services_status ,
WERR_GENERAL_FAILURE ) ;
2005-03-24 19:11:23 +03:00
2005-03-24 21:05:31 +03:00
/* second time with correct buffer size...should be ok */
2005-03-25 01:32:31 +03:00
if ( W_ERROR_EQUAL ( out . status , WERR_MORE_DATA ) ) {
2005-03-24 21:05:31 +03:00
in . buffer_size = out . needed ;
2005-09-30 21:13:37 +04:00
CLI_DO_RPC_WERR ( cli , mem_ctx , PI_SVCCTL , SVCCTL_ENUM_SERVICES_STATUS_W ,
2005-03-24 21:05:31 +03:00
in , out ,
qbuf , rbuf ,
svcctl_io_q_enum_services_status ,
svcctl_io_r_enum_services_status ,
WERR_GENERAL_FAILURE ) ;
}
2005-03-24 20:11:51 +03:00
if ( ! W_ERROR_IS_OK ( out . status ) )
return out . status ;
2005-03-24 21:05:31 +03:00
/* pull out the data */
if ( ! ( services = TALLOC_ARRAY ( mem_ctx , ENUM_SERVICES_STATUS , out . returned ) ) )
return WERR_NOMEM ;
for ( i = 0 ; i < out . returned ; i + + ) {
svcctl_io_enum_services_status ( " " , & services [ i ] , & out . buffer , 0 ) ;
}
* service_array = services ;
* returned = out . returned ;
2005-03-24 20:11:51 +03:00
return out . status ;
2005-03-24 07:25:49 +03:00
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-09-30 21:13:37 +04:00
WERROR rpccli_svcctl_query_status ( struct rpc_pipe_client * cli , TALLOC_CTX * mem_ctx ,
2005-03-25 01:32:31 +03:00
POLICY_HND * hService , SERVICE_STATUS * status )
2005-03-24 07:25:49 +03:00
{
2005-03-25 01:32:31 +03:00
SVCCTL_Q_QUERY_STATUS in ;
SVCCTL_R_QUERY_STATUS out ;
prs_struct qbuf , rbuf ;
ZERO_STRUCT ( in ) ;
ZERO_STRUCT ( out ) ;
memcpy ( & in . handle , hService , sizeof ( POLICY_HND ) ) ;
2005-09-30 21:13:37 +04:00
CLI_DO_RPC_WERR ( cli , mem_ctx , PI_SVCCTL , SVCCTL_QUERY_STATUS ,
2005-03-25 01:32:31 +03:00
in , out ,
qbuf , rbuf ,
svcctl_io_q_query_status ,
svcctl_io_r_query_status ,
WERR_GENERAL_FAILURE ) ;
if ( ! W_ERROR_IS_OK ( out . status ) )
return out . status ;
2005-03-24 07:25:49 +03:00
2005-03-25 01:32:31 +03:00
memcpy ( status , & out . svc_status , sizeof ( SERVICE_STATUS ) ) ;
return out . status ;
2005-03-24 07:25:49 +03:00
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-09-30 21:13:37 +04:00
WERROR rpccli_svcctl_query_config ( struct rpc_pipe_client * cli , TALLOC_CTX * mem_ctx ,
2005-03-25 01:32:31 +03:00
POLICY_HND * hService , SERVICE_CONFIG * config )
2005-03-24 07:25:49 +03:00
{
2005-03-25 01:32:31 +03:00
SVCCTL_Q_QUERY_SERVICE_CONFIG in ;
SVCCTL_R_QUERY_SERVICE_CONFIG out ;
prs_struct qbuf , rbuf ;
ZERO_STRUCT ( in ) ;
ZERO_STRUCT ( out ) ;
memcpy ( & in . handle , hService , sizeof ( POLICY_HND ) ) ;
in . buffer_size = 0 ;
2005-09-30 21:13:37 +04:00
CLI_DO_RPC_WERR ( cli , mem_ctx , PI_SVCCTL , SVCCTL_QUERY_SERVICE_CONFIG_W ,
2005-03-25 01:32:31 +03:00
in , out ,
qbuf , rbuf ,
svcctl_io_q_query_service_config ,
svcctl_io_r_query_service_config ,
WERR_GENERAL_FAILURE ) ;
if ( W_ERROR_EQUAL ( out . status , WERR_INSUFFICIENT_BUFFER ) ) {
in . buffer_size = out . needed ;
2005-03-24 07:25:49 +03:00
2005-09-30 21:13:37 +04:00
CLI_DO_RPC_WERR ( cli , mem_ctx , PI_SVCCTL , SVCCTL_QUERY_SERVICE_CONFIG_W ,
2005-03-25 01:32:31 +03:00
in , out ,
qbuf , rbuf ,
svcctl_io_q_query_service_config ,
svcctl_io_r_query_service_config ,
WERR_GENERAL_FAILURE ) ;
}
if ( ! W_ERROR_IS_OK ( out . status ) )
return out . status ;
memcpy ( config , & out . config , sizeof ( SERVICE_CONFIG ) ) ;
config - > executablepath = TALLOC_ZERO_P ( mem_ctx , UNISTR2 ) ;
config - > loadordergroup = TALLOC_ZERO_P ( mem_ctx , UNISTR2 ) ;
config - > dependencies = TALLOC_ZERO_P ( mem_ctx , UNISTR2 ) ;
config - > startname = TALLOC_ZERO_P ( mem_ctx , UNISTR2 ) ;
config - > displayname = TALLOC_ZERO_P ( mem_ctx , UNISTR2 ) ;
2005-09-30 21:13:37 +04:00
if ( out . config . executablepath ) {
config - > executablepath = TALLOC_ZERO_P ( mem_ctx , UNISTR2 ) ;
copy_unistr2 ( config - > executablepath , out . config . executablepath ) ;
}
if ( out . config . loadordergroup ) {
config - > loadordergroup = TALLOC_ZERO_P ( mem_ctx , UNISTR2 ) ;
copy_unistr2 ( config - > loadordergroup , out . config . loadordergroup ) ;
}
if ( out . config . dependencies ) {
config - > dependencies = TALLOC_ZERO_P ( mem_ctx , UNISTR2 ) ;
copy_unistr2 ( config - > dependencies , out . config . dependencies ) ;
}
if ( out . config . startname ) {
config - > startname = TALLOC_ZERO_P ( mem_ctx , UNISTR2 ) ;
copy_unistr2 ( config - > startname , out . config . startname ) ;
}
if ( out . config . displayname ) {
config - > displayname = TALLOC_ZERO_P ( mem_ctx , UNISTR2 ) ;
copy_unistr2 ( config - > displayname , out . config . displayname ) ;
}
2005-03-25 01:32:31 +03:00
return out . status ;
2005-03-24 07:25:49 +03:00
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-09-30 21:13:37 +04:00
WERROR rpccli_svcctl_start_service ( struct rpc_pipe_client * cli , TALLOC_CTX * mem_ctx ,
2005-03-25 03:38:30 +03:00
POLICY_HND * hService ,
const char * * parm_array , uint32 parmcount )
2005-03-24 07:25:49 +03:00
{
2005-03-25 03:38:30 +03:00
SVCCTL_Q_START_SERVICE in ;
SVCCTL_R_START_SERVICE out ;
prs_struct qbuf , rbuf ;
ZERO_STRUCT ( in ) ;
ZERO_STRUCT ( out ) ;
memcpy ( & in . handle , hService , sizeof ( POLICY_HND ) ) ;
2005-03-26 09:52:56 +03:00
in . parmcount = 0 ;
in . parameters = NULL ;
2005-03-25 03:38:30 +03:00
2005-09-30 21:13:37 +04:00
CLI_DO_RPC_WERR ( cli , mem_ctx , PI_SVCCTL , SVCCTL_START_SERVICE_W ,
2005-03-25 03:38:30 +03:00
in , out ,
qbuf , rbuf ,
svcctl_io_q_start_service ,
svcctl_io_r_start_service ,
WERR_GENERAL_FAILURE ) ;
return out . status ;
2005-03-24 07:25:49 +03:00
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-09-30 21:13:37 +04:00
WERROR rpccli_svcctl_control_service ( struct rpc_pipe_client * cli , TALLOC_CTX * mem_ctx ,
2005-03-25 03:38:30 +03:00
POLICY_HND * hService , uint32 control ,
SERVICE_STATUS * status )
2005-03-24 07:25:49 +03:00
{
2005-03-25 03:38:30 +03:00
SVCCTL_Q_CONTROL_SERVICE in ;
SVCCTL_R_CONTROL_SERVICE out ;
prs_struct qbuf , rbuf ;
ZERO_STRUCT ( in ) ;
ZERO_STRUCT ( out ) ;
memcpy ( & in . handle , hService , sizeof ( POLICY_HND ) ) ;
in . control = control ;
2005-09-30 21:13:37 +04:00
CLI_DO_RPC_WERR ( cli , mem_ctx , PI_SVCCTL , SVCCTL_CONTROL_SERVICE ,
2005-03-25 03:38:30 +03:00
in , out ,
qbuf , rbuf ,
svcctl_io_q_control_service ,
svcctl_io_r_control_service ,
WERR_GENERAL_FAILURE ) ;
if ( ! W_ERROR_IS_OK ( out . status ) )
return out . status ;
2005-03-24 07:25:49 +03:00
2005-03-25 03:38:30 +03:00
memcpy ( status , & out . svc_status , sizeof ( SERVICE_STATUS ) ) ;
return out . status ;
2005-03-24 07:25:49 +03:00
}
2005-03-25 01:32:31 +03:00
2005-03-24 07:25:49 +03:00
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-09-30 21:13:37 +04:00
WERROR rpccli_svcctl_get_dispname ( struct rpc_pipe_client * cli , TALLOC_CTX * mem_ctx ,
2005-03-25 01:32:31 +03:00
POLICY_HND * hService , fstring displayname )
2005-03-24 07:25:49 +03:00
{
2005-03-25 01:32:31 +03:00
SVCCTL_Q_GET_DISPLAY_NAME in ;
SVCCTL_R_GET_DISPLAY_NAME out ;
prs_struct qbuf , rbuf ;
ZERO_STRUCT ( in ) ;
ZERO_STRUCT ( out ) ;
memcpy ( & in . handle , hService , sizeof ( POLICY_HND ) ) ;
in . display_name_len = 0 ;
2005-09-30 21:13:37 +04:00
CLI_DO_RPC_WERR ( cli , mem_ctx , PI_SVCCTL , SVCCTL_GET_DISPLAY_NAME ,
2005-03-25 01:32:31 +03:00
in , out ,
qbuf , rbuf ,
svcctl_io_q_get_display_name ,
svcctl_io_r_get_display_name ,
WERR_GENERAL_FAILURE ) ;
/* second time with correct buffer size...should be ok */
if ( W_ERROR_EQUAL ( out . status , WERR_INSUFFICIENT_BUFFER ) ) {
in . display_name_len = out . display_name_len ;
2005-03-24 07:25:49 +03:00
2005-09-30 21:13:37 +04:00
CLI_DO_RPC_WERR ( cli , mem_ctx , PI_SVCCTL , SVCCTL_GET_DISPLAY_NAME ,
2005-03-25 01:32:31 +03:00
in , out ,
qbuf , rbuf ,
svcctl_io_q_get_display_name ,
svcctl_io_r_get_display_name ,
WERR_GENERAL_FAILURE ) ;
}
if ( ! W_ERROR_IS_OK ( out . status ) )
return out . status ;
rpcstr_pull ( displayname , out . displayname . buffer , sizeof ( displayname ) , - 1 , STR_TERMINATE ) ;
return out . status ;
2005-03-24 07:25:49 +03:00
}