diff options
-rw-r--r-- | source3/include/proto.h | 8 | ||||
-rw-r--r-- | source3/include/rpc_svcctl.h | 24 | ||||
-rw-r--r-- | source3/rpc_client/cli_svcctl.c | 58 | ||||
-rw-r--r-- | source3/rpc_parse/parse_svc.c | 59 | ||||
-rw-r--r-- | source3/rpcclient/cmd_svcctl.c | 61 | ||||
-rw-r--r-- | source3/rpcclient/rpcclient.c | 7 |
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 */ |