summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/proto.h8
-rw-r--r--source3/include/rpc_svcctl.h24
-rw-r--r--source3/rpc_client/cli_svcctl.c58
-rw-r--r--source3/rpc_parse/parse_svc.c59
-rw-r--r--source3/rpcclient/cmd_svcctl.c61
-rw-r--r--source3/rpcclient/rpcclient.c7
6 files changed, 215 insertions, 2 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 75a1d55ac0..ed314fa88e 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -2051,6 +2051,9 @@ BOOL svc_enum_svcs(struct cli_state *cli, uint16 fnum,
uint32 *buf_size, uint32 *resume_hnd,
uint32 *dos_error,
ENUM_SRVC_STATUS **svcs, uint32 *num_svcs);
+BOOL svc_stop_service(struct cli_state *cli, uint16 fnum,
+ POLICY_HND *hnd,
+ uint32 unknown);
BOOL svc_start_service(struct cli_state *cli, uint16 fnum,
POLICY_HND *hnd,
uint32 argc,
@@ -3059,6 +3062,10 @@ BOOL svc_io_q_open_service(char *desc, SVC_Q_OPEN_SERVICE *q_u, prs_struct *ps,
BOOL make_svc_r_open_service(SVC_R_OPEN_SERVICE *r_u, POLICY_HND *hnd,
uint32 status) ;
BOOL svc_io_r_open_service(char *desc, SVC_R_OPEN_SERVICE *r_u, prs_struct *ps, int depth);
+BOOL make_svc_q_stop_service(SVC_Q_STOP_SERVICE *q_c, POLICY_HND *hnd,
+ uint32 unk);
+BOOL svc_io_q_stop_service(char *desc, SVC_Q_STOP_SERVICE *q_s, prs_struct *ps, int depth);
+BOOL svc_io_r_stop_service(char *desc, SVC_R_STOP_SERVICE *r_s, prs_struct *ps, int depth);
BOOL make_svc_q_start_service(SVC_Q_START_SERVICE *q_c, POLICY_HND *hnd,
uint32 argc,
char **argv);
@@ -3322,6 +3329,7 @@ BOOL msrpc_svc_enum(struct client_info *info,
SVC_INFO_FN(info_fn),
SVC_QUERY_FN(query_fn));
void cmd_svc_enum(struct client_info *info);
+void cmd_svc_stop(struct client_info *info);
void cmd_svc_start(struct client_info *info);
/*The following definitions come from rpcclient/cmd_wkssvc.c */
diff --git a/source3/include/rpc_svcctl.h b/source3/include/rpc_svcctl.h
index e72f7df376..e3b825fa53 100644
--- a/source3/include/rpc_svcctl.h
+++ b/source3/include/rpc_svcctl.h
@@ -32,6 +32,7 @@
#define SVC_QUERY_DISP_NAME 0x14
#define SVC_OPEN_SERVICE 0x10
#define SVC_START_SERVICE 0x13
+#define SVC_STOP_SERVICE 0x01
#define SVC_CLOSE 0x00
@@ -75,6 +76,29 @@ typedef struct r_svc_open_service_info
#define MAX_SVC_ARGS 10
+/* SVC_Q_STOP_SERVICE */
+typedef struct q_svc_stop_service_info
+{
+ POLICY_HND pol;
+
+ uint32 unknown;
+
+} SVC_Q_STOP_SERVICE;
+
+/* SVC_R_STOP_SERVICE */
+typedef struct r_svc_stop_service_info
+{
+ uint32 unknown0; /* 0x00000020 */
+ uint32 unknown1; /* 0x00000001 */
+ uint32 unknown2; /* 0x00000001 */
+ uint32 unknown3; /* 0x00000000 */
+ uint32 unknown4; /* 0x00000000 */
+ uint32 unknown5; /* 0x00000000 */
+ uint32 unknown6; /* 0x00000000 */
+ uint32 status;
+
+} SVC_R_STOP_SERVICE;
+
/* SVC_Q_START_SERVICE */
typedef struct q_svc_start_service_info
{
diff --git a/source3/rpc_client/cli_svcctl.c b/source3/rpc_client/cli_svcctl.c
index 1e1fe884ff..e09cd4ec12 100644
--- a/source3/rpc_client/cli_svcctl.c
+++ b/source3/rpc_client/cli_svcctl.c
@@ -230,6 +230,64 @@ BOOL svc_enum_svcs(struct cli_state *cli, uint16 fnum,
/****************************************************************************
+do a SVC Stop Service
+****************************************************************************/
+BOOL svc_stop_service(struct cli_state *cli, uint16 fnum,
+ POLICY_HND *hnd,
+ uint32 unknown)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ SVC_Q_STOP_SERVICE q_c;
+ BOOL valid_cfg = False;
+
+ if (hnd == NULL) return False;
+
+ /* create and send a MSRPC command with api SVC_STOP_SERVICE */
+
+ prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
+ prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True );
+
+ DEBUG(4,("SVC Stop Service\n"));
+
+ /* store the parameters */
+ make_svc_q_stop_service(&q_c, hnd, unknown);
+
+ /* turn parameters into data stream */
+ svc_io_q_stop_service("", &q_c, &buf, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, fnum, SVC_STOP_SERVICE, &buf, &rbuf))
+ {
+ SVC_R_STOP_SERVICE r_c;
+ BOOL p;
+
+ ZERO_STRUCT (r_c);
+
+ svc_io_r_stop_service("", &r_c, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_c.status != 0)
+ {
+ /* report error code */
+ DEBUG(1,("SVC_START_SERVICE: %s\n", get_nt_error_msg(r_c.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ valid_cfg = True;
+ }
+ }
+
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
+
+ return valid_cfg;
+}
+
+
+/****************************************************************************
do a SVC Start Service
****************************************************************************/
BOOL svc_start_service(struct cli_state *cli, uint16 fnum,
diff --git a/source3/rpc_parse/parse_svc.c b/source3/rpc_parse/parse_svc.c
index ef24e06be6..815f60151e 100644
--- a/source3/rpc_parse/parse_svc.c
+++ b/source3/rpc_parse/parse_svc.c
@@ -179,6 +179,63 @@ BOOL svc_io_r_open_service(char *desc, SVC_R_OPEN_SERVICE *r_u, prs_struct *ps,
}
/*******************************************************************
+makes an SVC_Q_STOP_SERVICE structure.
+********************************************************************/
+BOOL make_svc_q_stop_service(SVC_Q_STOP_SERVICE *q_c, POLICY_HND *hnd,
+ uint32 unk)
+{
+ if (q_c == NULL || hnd == NULL) return False;
+
+ DEBUG(5,("make_svc_q_stop_service\n"));
+
+ memcpy(&(q_c->pol), hnd, sizeof(q_c->pol));
+ q_c->unknown = unk;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a SVC_Q_STOP_SERVICE structure.
+********************************************************************/
+BOOL svc_io_q_stop_service(char *desc, SVC_Q_STOP_SERVICE *q_s, prs_struct *ps, int depth)
+{
+ if (q_s == NULL) return False;
+
+ prs_debug(ps, depth, desc, "svc_io_q_stop_service");
+ depth++;
+
+ prs_align(ps);
+ smb_io_pol_hnd("", &(q_s->pol), ps, depth);
+
+ prs_align(ps);
+
+ prs_uint32("unknown", ps, depth, &(q_s->unknown));
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL svc_io_r_stop_service(char *desc, SVC_R_STOP_SERVICE *r_s, prs_struct *ps, int depth)
+{
+ if (r_s == NULL) return False;
+
+ prs_debug(ps, depth, desc, "svc_io_r_stop_service");
+ depth++;
+
+ prs_uint32("unknown0", ps, depth, &(r_s->unknown0));
+ prs_uint32("unknown1", ps, depth, &(r_s->unknown1));
+ prs_uint32("unknown2", ps, depth, &(r_s->unknown2));
+ prs_uint32("unknown3", ps, depth, &(r_s->unknown3));
+ prs_uint32("unknown4", ps, depth, &(r_s->unknown4));
+ prs_uint32("unknown5", ps, depth, &(r_s->unknown5));
+ prs_uint32("unknown6", ps, depth, &(r_s->unknown6));
+ prs_uint32("status", ps, depth, &(r_s->status));
+
+ return True;
+}
+
+/*******************************************************************
makes an SVC_Q_START_SERVICE structure.
********************************************************************/
BOOL make_svc_q_start_service(SVC_Q_START_SERVICE *q_c, POLICY_HND *hnd,
@@ -189,7 +246,7 @@ BOOL make_svc_q_start_service(SVC_Q_START_SERVICE *q_c, POLICY_HND *hnd,
if (q_c == NULL || hnd == NULL) return False;
- DEBUG(5,("make_svc_q_query_svc_config\n"));
+ DEBUG(5,("make_svc_q_start_service\n"));
memcpy(&(q_c->pol), hnd, sizeof(q_c->pol));
q_c->argc = argc;
diff --git a/source3/rpcclient/cmd_svcctl.c b/source3/rpcclient/cmd_svcctl.c
index f804017926..7e93653275 100644
--- a/source3/rpcclient/cmd_svcctl.c
+++ b/source3/rpcclient/cmd_svcctl.c
@@ -242,6 +242,65 @@ void cmd_svc_enum(struct client_info *info)
}
/****************************************************************************
+nt stop service
+****************************************************************************/
+void cmd_svc_stop(struct client_info *info)
+{
+ uint16 fnum;
+ BOOL res = True;
+ BOOL res1 = True;
+ fstring svc_name;
+ BOOL res2 = True;
+ POLICY_HND pol_svc;
+ POLICY_HND pol_scm;
+
+ fstring srv_name;
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->myhostname);
+ strupper(srv_name);
+
+ DEBUG(4,("cmd_svc_stop: server:%s\n", srv_name));
+
+ if (!next_token(NULL, svc_name, NULL, sizeof(svc_name)))
+ {
+ report(out_hnd,"svcstop <service name>\n");
+ return;
+ }
+
+ /* open SVCCTL session. */
+ res = res ? cli_nt_session_open(smb_cli, PIPE_SVCCTL, &fnum) : False;
+
+ /* open service control manager receive a policy handle */
+ res = res ? svc_open_sc_man(smb_cli, fnum,
+ srv_name, NULL, 0x80000000,
+ &pol_scm) : False;
+
+ res1 = res ? svc_open_service(smb_cli, fnum,
+ &pol_scm,
+ svc_name, 0x00000020,
+ &pol_svc) : False;
+ res2 = res1 ? svc_stop_service(smb_cli, fnum, &pol_svc, 0x1) : False;
+
+ res1 = res1 ? svc_close(smb_cli, fnum, &pol_svc) : False;
+ res = res ? svc_close(smb_cli, fnum, &pol_scm) : False;
+
+ /* close the session */
+ cli_nt_session_close(smb_cli, fnum);
+
+ if (res2)
+ {
+ report(out_hnd,"Stopped Service %s\n", svc_name);
+ DEBUG(5,("cmd_svc_stop: succeeded\n"));
+ }
+ else
+ report(out_hnd,"Failed Service Stopped (%s)\n", svc_name);
+ {
+ DEBUG(5,("cmd_svc_stop: failed\n"));
+ }
+}
+
+/****************************************************************************
nt start service
****************************************************************************/
void cmd_svc_start(struct client_info *info)
@@ -263,7 +322,7 @@ void cmd_svc_start(struct client_info *info)
fstrcat(srv_name, info->myhostname);
strupper(srv_name);
- DEBUG(4,("cmd_svc_info: server:%s\n", srv_name));
+ DEBUG(4,("cmd_svc_start: server:%s\n", srv_name));
if (!next_token(NULL, svc_name, NULL, sizeof(svc_name)))
{
diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c
index 9a1193c015..732aa9ceb7 100644
--- a/source3/rpcclient/rpcclient.c
+++ b/source3/rpcclient/rpcclient.c
@@ -153,6 +153,13 @@ commands[] =
{COMPL_SVCLST, COMPL_NONE}
},
+ {
+ "svcstop",
+ cmd_svc_stop,
+ "<service> Stop Service",
+ {COMPL_SVCLST, COMPL_NONE}
+ },
+
/*
* scheduler
*/