1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-05 21:57:51 +03:00

r6051: finish off

net rpc service stop
        net rpc service start
        net rpc service pause
        net rpc service resume
This commit is contained in:
Gerald Carter 2005-03-25 00:38:30 +00:00 committed by Gerald (Jerry) Carter
parent 80e788143a
commit a7fb2c50b0
5 changed files with 352 additions and 22 deletions

View File

@ -186,6 +186,7 @@
#define WERR_IO_PENDING W_ERROR(997)
#define WERR_CAN_NOT_COMPLETE W_ERROR(1003)
#define WERR_NO_SUCH_SERVICE W_ERROR(1060)
#define WERR_INVALID_SERVICE_CONTROL W_ERROR(1052)
#define WERR_INVALID_SECURITY_DESCRIPTOR W_ERROR(1338)
#define WERR_SERVER_UNAVAILABLE W_ERROR(1722)
#define WERR_INVALID_FORM_NAME W_ERROR(1902)

View File

@ -72,6 +72,11 @@
#define SVCCTL_ACCEPT_HARDWAREPROFILECHANGE 0x00000020
#define SVCCTL_ACCEPT_POWEREVENT 0x00000040
/* Service Controls */
#define SVCCTL_CONTROL_STOP 0x00000001
#define SVCCTL_CONTROL_PAUSE 0x00000002
#define SVCCTL_CONTROL_CONTINUE 0x00000003
/* utility structures for RPCs */

View File

@ -70,6 +70,7 @@ werror_code_struct dos_errs[] =
{ "WERR_INVALID_OWNER", WERR_INVALID_OWNER },
{ "WERR_SERVER_UNAVAILABLE", WERR_SERVER_UNAVAILABLE },
{ "WERR_IO_PENDING", WERR_IO_PENDING },
{ "WERR_INVALID_SERVICE_CONTROL", WERR_INVALID_SERVICE_CONTROL },
{ NULL, W_ERROR(0) }
};

View File

@ -28,13 +28,13 @@ struct svc_state_msg {
};
static struct svc_state_msg state_msg_table[] = {
{ SVCCTL_STOPPED, "SVCCTL_STOPPED" },
{ SVCCTL_START_PENDING, "SVCCTL_START_PENDING" },
{ SVCCTL_STOP_PENDING, "SVCCTL_STOP_PENDING" },
{ SVCCTL_RUNNING, "SVCCTL_RUNNING" },
{ SVCCTL_CONTINUE_PENDING, "SVCCTL_CONTINUE_PENDING" },
{ SVCCTL_PAUSE_PENDING, "SVCCTL_PAUSE_PENDING" },
{ SVCCTL_PAUSED, "SVCCTL_PAUSED" },
{ 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" },
{ 0, NULL }
};
@ -136,7 +136,7 @@ WERROR cli_svcctl_open_service( struct cli_state *cli, TALLOC_CTX *mem_ctx,
/********************************************************************
********************************************************************/
WERROR close_service_handle( struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *hService )
WERROR cli_svcctl_close_service( struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *hService )
{
SVCCTL_Q_CLOSE_SERVICE in;
SVCCTL_R_CLOSE_SERVICE out;
@ -310,19 +310,62 @@ WERROR cli_svcctl_query_config(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/*******************************************************************
*******************************************************************/
WERROR cli_svcctl_start_service(struct cli_state *cli, TALLOC_CTX *mem_ctx )
WERROR cli_svcctl_start_service( struct cli_state *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hService,
const char **parm_array, uint32 parmcount )
{
return WERR_OK;
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) );
in.parmcount = 0;
in.parameters.ref_id = 0x0;
CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_START_SERVICE_W,
in, out,
qbuf, rbuf,
svcctl_io_q_start_service,
svcctl_io_r_start_service,
WERR_GENERAL_FAILURE );
return out.status;
}
/*******************************************************************
*******************************************************************/
WERROR cli_svcctl_control_service(struct cli_state *cli, TALLOC_CTX *mem_ctx )
WERROR cli_svcctl_control_service( struct cli_state *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hService, uint32 control,
SERVICE_STATUS *status )
{
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;
CLI_DO_RPC( cli, mem_ctx, PI_SVCCTL, SVCCTL_CONTROL_SERVICE,
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;
return WERR_OK;
memcpy( status, &out.svc_status, sizeof(SERVICE_STATUS) );
return out.status;
}

View File

@ -20,6 +20,113 @@
#include "includes.h"
#include "utils/net.h"
/********************************************************************
********************************************************************/
static WERROR query_service_state( struct cli_state *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hSCM, const char *service, uint32 *state )
{
POLICY_HND hService;
SERVICE_STATUS service_status;
WERROR result = WERR_GENERAL_FAILURE;
/* now cycle until the status is actually 'watch_state' */
result = cli_svcctl_open_service( cli, mem_ctx, hSCM, &hService,
service, SC_RIGHT_SVC_QUERY_STATUS );
if ( !W_ERROR_IS_OK(result) ) {
d_printf("Failed to open service. [%s]\n", dos_errstr(result));
return result;
}
result = cli_svcctl_query_status( cli, mem_ctx, &hService, &service_status );
if ( W_ERROR_IS_OK(result) ) {
*state = service_status.state;
}
cli_svcctl_close_service( cli, mem_ctx, &hService );
return result;
}
/********************************************************************
********************************************************************/
static WERROR watch_service_state( struct cli_state *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hSCM, const char *service,
uint32 watch_state, uint32 *final_state )
{
uint32 i;
uint32 state = 0;
WERROR result = WERR_GENERAL_FAILURE;
i = 0;
while ( (state != watch_state ) && i<30 ) {
/* get the status */
result = query_service_state( cli, mem_ctx, hSCM, service, &state );
if ( !W_ERROR_IS_OK(result) ) {
break;
}
d_printf(".");
i++;
usleep( 100 );
}
d_printf("\n");
*final_state = state;
return result;
}
/********************************************************************
********************************************************************/
static WERROR control_service( struct cli_state *cli, TALLOC_CTX *mem_ctx,
POLICY_HND *hSCM, const char *service,
uint32 control, uint32 watch_state )
{
POLICY_HND hService;
WERROR result = WERR_GENERAL_FAILURE;
SERVICE_STATUS service_status;
uint32 state = 0;
/* Open the Service */
result = cli_svcctl_open_service( cli, mem_ctx, hSCM, &hService,
service, (SC_RIGHT_SVC_STOP|SC_RIGHT_SVC_PAUSE_CONTINUE) );
if ( !W_ERROR_IS_OK(result) ) {
d_printf("Failed to open service. [%s]\n", dos_errstr(result));
goto done;
}
/* get the status */
result = cli_svcctl_control_service( cli, mem_ctx, &hService,
control, &service_status );
if ( !W_ERROR_IS_OK(result) ) {
d_printf("Control service request failed. [%s]\n", dos_errstr(result));
goto done;
}
/* loop -- checking the state until we are where we want to be */
result = watch_service_state( cli, mem_ctx, hSCM, service, watch_state, &state );
d_printf("%s service is %s.\n", service, svc_status_string(state));
done:
cli_svcctl_close_service( cli, mem_ctx, &hService );
return result;
}
/********************************************************************
********************************************************************/
@ -65,7 +172,7 @@ static NTSTATUS rpc_service_list_internal( const DOM_SID *domain_sid, const char
}
done:
close_service_handle( cli, mem_ctx, &hSCM );
cli_svcctl_close_service( cli, mem_ctx, &hSCM );
return werror_to_ntstatus(result);
}
@ -161,12 +268,174 @@ static NTSTATUS rpc_service_status_internal( const DOM_SID *domain_sid, const ch
}
done:
close_service_handle( cli, mem_ctx, &hService );
close_service_handle( cli, mem_ctx, &hSCM );
cli_svcctl_close_service( cli, mem_ctx, &hService );
cli_svcctl_close_service( cli, mem_ctx, &hSCM );
return werror_to_ntstatus(result);
}
/********************************************************************
********************************************************************/
static NTSTATUS rpc_service_stop_internal( const DOM_SID *domain_sid, const char *domain_name,
struct cli_state *cli, TALLOC_CTX *mem_ctx,
int argc, const char **argv )
{
POLICY_HND hSCM;
WERROR result = WERR_GENERAL_FAILURE;
fstring servicename;
if (argc != 1 ) {
d_printf("Usage: net rpc service status <service>\n");
return NT_STATUS_OK;
}
fstrcpy( servicename, argv[0] );
/* Open the Service Control Manager */
result = cli_svcctl_open_scm( cli, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
if ( !W_ERROR_IS_OK(result) ) {
d_printf("Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
return werror_to_ntstatus(result);
}
result = control_service( cli, mem_ctx, &hSCM, servicename,
SVCCTL_CONTROL_STOP, SVCCTL_STOPPED );
cli_svcctl_close_service( cli, mem_ctx, &hSCM );
return werror_to_ntstatus(result);
}
/********************************************************************
********************************************************************/
static NTSTATUS rpc_service_pause_internal( const DOM_SID *domain_sid, const char *domain_name,
struct cli_state *cli, TALLOC_CTX *mem_ctx,
int argc, const char **argv )
{
POLICY_HND hSCM;
WERROR result = WERR_GENERAL_FAILURE;
fstring servicename;
if (argc != 1 ) {
d_printf("Usage: net rpc service status <service>\n");
return NT_STATUS_OK;
}
fstrcpy( servicename, argv[0] );
/* Open the Service Control Manager */
result = cli_svcctl_open_scm( cli, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
if ( !W_ERROR_IS_OK(result) ) {
d_printf("Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
return werror_to_ntstatus(result);
}
result = control_service( cli, mem_ctx, &hSCM, servicename,
SVCCTL_CONTROL_PAUSE, SVCCTL_PAUSED );
cli_svcctl_close_service( cli, mem_ctx, &hSCM );
return werror_to_ntstatus(result);
}
/********************************************************************
********************************************************************/
static NTSTATUS rpc_service_resume_internal( const DOM_SID *domain_sid, const char *domain_name,
struct cli_state *cli, TALLOC_CTX *mem_ctx,
int argc, const char **argv )
{
POLICY_HND hSCM;
WERROR result = WERR_GENERAL_FAILURE;
fstring servicename;
if (argc != 1 ) {
d_printf("Usage: net rpc service status <service>\n");
return NT_STATUS_OK;
}
fstrcpy( servicename, argv[0] );
/* Open the Service Control Manager */
result = cli_svcctl_open_scm( cli, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
if ( !W_ERROR_IS_OK(result) ) {
d_printf("Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
return werror_to_ntstatus(result);
}
result = control_service( cli, mem_ctx, &hSCM, servicename,
SVCCTL_CONTROL_CONTINUE, SVCCTL_RUNNING );
cli_svcctl_close_service( cli, mem_ctx, &hSCM );
return werror_to_ntstatus(result);
}
/********************************************************************
********************************************************************/
static NTSTATUS rpc_service_start_internal( const DOM_SID *domain_sid, const char *domain_name,
struct cli_state *cli, TALLOC_CTX *mem_ctx,
int argc, const char **argv )
{
POLICY_HND hSCM, hService;
WERROR result = WERR_GENERAL_FAILURE;
fstring servicename;
uint32 state = 0;
if (argc != 1 ) {
d_printf("Usage: net rpc service status <service>\n");
return NT_STATUS_OK;
}
fstrcpy( servicename, argv[0] );
/* Open the Service Control Manager */
result = cli_svcctl_open_scm( cli, mem_ctx, &hSCM, SC_RIGHT_MGR_ENUMERATE_SERVICE );
if ( !W_ERROR_IS_OK(result) ) {
d_printf("Failed to open Service Control Manager. [%s]\n", dos_errstr(result));
return werror_to_ntstatus(result);
}
/* Open the Service */
result = cli_svcctl_open_service( cli, mem_ctx, &hSCM, &hService,
servicename, SC_RIGHT_SVC_START );
if ( !W_ERROR_IS_OK(result) ) {
d_printf("Failed to open service. [%s]\n", dos_errstr(result));
goto done;
}
/* get the status */
result = cli_svcctl_start_service( cli, mem_ctx, &hService, NULL, 0 );
if ( !W_ERROR_IS_OK(result) ) {
d_printf("Query status request failed. [%s]\n", dos_errstr(result));
goto done;
}
result = watch_service_state( cli, mem_ctx, &hSCM, servicename, SVCCTL_RUNNING, &state );
if ( W_ERROR_IS_OK(result) && (state == SVCCTL_RUNNING) )
d_printf("Successfully started service: %s\n", servicename );
else
d_printf("Failed to start service: %s [%s]\n", servicename, dos_errstr(result) );
done:
cli_svcctl_close_service( cli, mem_ctx, &hService );
cli_svcctl_close_service( cli, mem_ctx, &hSCM );
return werror_to_ntstatus(result);
}
/********************************************************************
********************************************************************/
@ -181,8 +450,8 @@ static int rpc_service_list( int argc, const char **argv )
static int rpc_service_start( int argc, const char **argv )
{
d_printf("not implemented\n");
return 0;
return run_rpc_command( NULL, PI_SVCCTL, 0,
rpc_service_start_internal, argc, argv );
}
/********************************************************************
@ -190,8 +459,17 @@ static int rpc_service_start( int argc, const char **argv )
static int rpc_service_stop( int argc, const char **argv )
{
d_printf("not implemented\n");
return 0;
return run_rpc_command( NULL, PI_SVCCTL, 0,
rpc_service_stop_internal, argc, argv );
}
/********************************************************************
********************************************************************/
static int rpc_service_resume( int argc, const char **argv )
{
return run_rpc_command( NULL, PI_SVCCTL, 0,
rpc_service_resume_internal, argc, argv );
}
/********************************************************************
@ -199,8 +477,8 @@ static int rpc_service_stop( int argc, const char **argv )
static int rpc_service_pause( int argc, const char **argv )
{
d_printf("not implemented\n");
return 0;
return run_rpc_command( NULL, PI_SVCCTL, 0,
rpc_service_pause_internal, argc, argv );
}
/********************************************************************
@ -221,6 +499,7 @@ static int net_help_service( int argc, const char **argv )
d_printf("net rpc service start <service> Start a service\n");
d_printf("net rpc service stop <service> Stop a service\n");
d_printf("net rpc service pause <service> Pause a service\n");
d_printf("net rpc service resume <service> Resume a paused a service\n");
d_printf("net rpc service status <service> View the current status of a service\n");
return -1;
@ -236,6 +515,7 @@ int net_rpc_service(int argc, const char **argv)
{"start", rpc_service_start},
{"stop", rpc_service_stop},
{"pause", rpc_service_pause},
{"resume", rpc_service_resume},
{"status", rpc_service_status},
{NULL, NULL}
};