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:
parent
80e788143a
commit
a7fb2c50b0
@ -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)
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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) }
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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}
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user