From e7a9b398c79cb77678de18f3fc448131e1d6eb25 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sun, 31 Oct 1999 05:23:32 +0000 Subject: added yet another rpcclient command: svcstart [arg0] [arg1] ... works with command-line completion on the service name (ohh yesss, this is becoming my favourite bit of functionality-on-the-side hee hee :) had to fix the svc_io_q_start_service() code which was missing the ptr_argv[] array in between the array-size and the UNISTR2-array. i.e it's actually an array of _pointers_ to unicode strings... (This used to be commit 2903f22e7ed9306229035accfa757fd810645820) --- source3/include/proto.h | 8 +++++ source3/include/rpc_svcctl.h | 5 +-- source3/rpc_client/cli_svcctl.c | 59 ++++++++++++++++++++++++++++++++++ source3/rpc_parse/parse_svc.c | 40 ++++++++++++++++++++--- source3/rpcclient/cmd_svcctl.c | 71 +++++++++++++++++++++++++++++++++++++++++ source3/rpcclient/rpcclient.c | 7 ++++ 6 files changed, 184 insertions(+), 6 deletions(-) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index aed1d824de..75a1d55ac0 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -2051,6 +2051,10 @@ 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_start_service(struct cli_state *cli, uint16 fnum, + POLICY_HND *hnd, + uint32 argc, + char **argv); BOOL svc_query_svc_cfg(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd, QUERY_SERVICE_CONFIG *cfg, @@ -3055,6 +3059,9 @@ 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_start_service(SVC_Q_START_SERVICE *q_c, POLICY_HND *hnd, + uint32 argc, + char **argv); BOOL svc_io_q_start_service(char *desc, SVC_Q_START_SERVICE *q_s, prs_struct *ps, int depth); BOOL svc_io_r_start_service(char *desc, SVC_R_START_SERVICE *r_s, prs_struct *ps, int depth); BOOL make_svc_query_svc_cfg(QUERY_SERVICE_CONFIG *q_u, @@ -3315,6 +3322,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_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 8a2a771d64..e72f7df376 100644 --- a/source3/include/rpc_svcctl.h +++ b/source3/include/rpc_svcctl.h @@ -73,7 +73,7 @@ typedef struct r_svc_open_service_info } SVC_R_OPEN_SERVICE; -#define MAX_SVC_ARGS 4 +#define MAX_SVC_ARGS 10 /* SVC_Q_START_SERVICE */ typedef struct q_svc_start_service_info @@ -81,8 +81,9 @@ typedef struct q_svc_start_service_info POLICY_HND pol; uint32 argc; - uint32 ptr_argv; + uint32 ptr_args; uint32 argc2; + uint32 ptr_argv[MAX_SVC_ARGS]; UNISTR2 argv[MAX_SVC_ARGS]; } SVC_Q_START_SERVICE; diff --git a/source3/rpc_client/cli_svcctl.c b/source3/rpc_client/cli_svcctl.c index f161e4207f..1e1fe884ff 100644 --- a/source3/rpc_client/cli_svcctl.c +++ b/source3/rpc_client/cli_svcctl.c @@ -229,6 +229,65 @@ BOOL svc_enum_svcs(struct cli_state *cli, uint16 fnum, } +/**************************************************************************** +do a SVC Start Service +****************************************************************************/ +BOOL svc_start_service(struct cli_state *cli, uint16 fnum, + POLICY_HND *hnd, + uint32 argc, + char **argv) +{ + prs_struct rbuf; + prs_struct buf; + SVC_Q_START_SERVICE q_c; + BOOL valid_cfg = False; + + if (hnd == NULL) return False; + + /* create and send a MSRPC command with api SVC_START_SERVICE */ + + prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); + prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True ); + + DEBUG(4,("SVC Start Service\n")); + + /* store the parameters */ + make_svc_q_start_service(&q_c, hnd, argc, argv); + + /* turn parameters into data stream */ + svc_io_q_start_service("", &q_c, &buf, 0); + + /* send the data on \PIPE\ */ + if (rpc_api_pipe_req(cli, fnum, SVC_START_SERVICE, &buf, &rbuf)) + { + SVC_R_START_SERVICE r_c; + BOOL p; + + ZERO_STRUCT (r_c); + + svc_io_r_start_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 Query Service Config ****************************************************************************/ diff --git a/source3/rpc_parse/parse_svc.c b/source3/rpc_parse/parse_svc.c index 43594329b5..ef24e06be6 100644 --- a/source3/rpc_parse/parse_svc.c +++ b/source3/rpc_parse/parse_svc.c @@ -178,6 +178,34 @@ BOOL svc_io_r_open_service(char *desc, SVC_R_OPEN_SERVICE *r_u, prs_struct *ps, return True; } +/******************************************************************* +makes an SVC_Q_START_SERVICE structure. +********************************************************************/ +BOOL make_svc_q_start_service(SVC_Q_START_SERVICE *q_c, POLICY_HND *hnd, + uint32 argc, + char **argv) +{ + uint32 i; + + if (q_c == NULL || hnd == NULL) return False; + + DEBUG(5,("make_svc_q_query_svc_config\n")); + + memcpy(&(q_c->pol), hnd, sizeof(q_c->pol)); + q_c->argc = argc; + q_c->ptr_args = 1; + q_c->argc2 = argc; + + for (i = 0; i < argc; i++) + { + size_t len_argv = argv[i] != NULL ? strlen(argv[i])+1 : 0; + q_c->ptr_argv[i] = argv[i] != NULL ? 1 : 0; + make_unistr2(&(q_c->argv[i]), argv[i], len_argv); + } + + return True; +} + /******************************************************************* reads or writes a SVC_Q_START_SERVICE structure. ********************************************************************/ @@ -193,9 +221,9 @@ BOOL svc_io_q_start_service(char *desc, SVC_Q_START_SERVICE *q_s, prs_struct *ps prs_align(ps); prs_uint32("argc ", ps, depth, &(q_s->argc )); - prs_uint32("ptr_argv", ps, depth, &(q_s->ptr_argv)); + prs_uint32("ptr_args", ps, depth, &(q_s->ptr_args)); - if (q_s->ptr_argv != 0) + if (q_s->ptr_args != 0) { uint32 i; @@ -203,12 +231,16 @@ BOOL svc_io_q_start_service(char *desc, SVC_Q_START_SERVICE *q_s, prs_struct *ps if (q_s->argc2 > MAX_SVC_ARGS) { - q_s->argc = q_s->argc2 = MAX_SVC_ARGS; + return False; } for (i = 0; i < q_s->argc2; i++) { - smb_io_unistr2("", &(q_s->argv[i]), 1, ps, depth); + prs_uint32("", ps, depth, &(q_s->ptr_argv[i])); + } + for (i = 0; i < q_s->argc2; i++) + { + smb_io_unistr2("", &(q_s->argv[i]), q_s->ptr_argv[i], ps, depth); prs_align(ps); } } diff --git a/source3/rpcclient/cmd_svcctl.c b/source3/rpcclient/cmd_svcctl.c index 6af58035c5..f804017926 100644 --- a/source3/rpcclient/cmd_svcctl.c +++ b/source3/rpcclient/cmd_svcctl.c @@ -241,3 +241,74 @@ void cmd_svc_enum(struct client_info *info) } } +/**************************************************************************** +nt start service +****************************************************************************/ +void cmd_svc_start(struct client_info *info) +{ + uint16 fnum; + BOOL res = True; + BOOL res1 = True; + fstring svc_name; + fstring tmp; + BOOL res2 = True; + POLICY_HND pol_svc; + POLICY_HND pol_scm; + uint32 argc = 0; + char **argv = NULL; + + fstring srv_name; + + fstrcpy(srv_name, "\\\\"); + fstrcat(srv_name, info->myhostname); + strupper(srv_name); + + DEBUG(4,("cmd_svc_info: server:%s\n", srv_name)); + + if (!next_token(NULL, svc_name, NULL, sizeof(svc_name))) + { + report(out_hnd,"svcstart [arg 0] [arg 1]...]\n"); + return; + } + + while (next_token(NULL, tmp, NULL, sizeof(tmp))) + { + add_chars_to_array(&argc, &argv, tmp); + } + + /* 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, 0x80000010, + &pol_svc) : False; + res2 = res1 ? svc_start_service(smb_cli, fnum, + &pol_svc, argc, argv) : 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,"Started Service %s\n", svc_name); + DEBUG(5,("cmd_svc_start: succeeded\n")); + } + else + report(out_hnd,"Failed Service Startup (%s)\n", svc_name); + { + DEBUG(5,("cmd_svc_start: failed\n")); + } + + free_char_array(argc, argv); + +} + diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index 50f77b35a1..9a1193c015 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -146,6 +146,13 @@ commands[] = {COMPL_SVCLST, COMPL_NONE} }, + { + "svcstart", + cmd_svc_start, + " [arg 0] [arg 1] ... Start Service", + {COMPL_SVCLST, COMPL_NONE} + }, + /* * scheduler */ -- cgit