From 6b7e1ead37b8655cf3cfb52a421461cedb3d0c90 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 28 Jan 1999 21:11:15 +0000 Subject: rpcclient "Service Control Manager" svcenum [-i] command. (This used to be commit a022710f1e3996ecbe6bbe035e1df0bc4c050b34) --- source3/include/proto.h | 18 +++++- source3/include/rpc_svcctl.h | 4 +- source3/rpc_client/cli_svcctl.c | 129 +++++++++++++++++++++++++++++++++++++++- source3/rpc_parse/parse_svc.c | 6 +- source3/rpcclient/cmd_svcctl.c | 42 +++++++++++-- source3/rpcclient/display.c | 56 +++++++++++++++++ source3/rpcclient/rpcclient.c | 2 +- 7 files changed, 241 insertions(+), 16 deletions(-) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index 6f2c9934e8..15ed9a50af 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1778,17 +1778,26 @@ BOOL do_srv_net_srv_get_info(struct cli_state *cli, uint16 fnum, /*The following definitions come from rpc_client/cli_svcctl.c */ -BOOL do_svc_open_sc_man(struct cli_state *cli, uint16 fnum, +BOOL svc_open_sc_man(struct cli_state *cli, uint16 fnum, char *srv_name, char *db_name, uint32 des_access, POLICY_HND *hnd); -BOOL do_svc_enum_svcs(struct cli_state *cli, uint16 fnum, +BOOL svc_open_service(struct cli_state *cli, uint16 fnum, + POLICY_HND *scm_hnd, + char *srv_name, + uint32 des_access, + POLICY_HND *hnd); +BOOL svc_enum_svcs(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd, uint32 services_type, uint32 services_state, uint32 *buf_size, uint32 *resume_hnd, uint32 *dos_error, ENUM_SRVC_STATUS **svcs, uint32 *num_svcs); -BOOL do_svc_close(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd); +BOOL svc_query_svc_cfg(struct cli_state *cli, uint16 fnum, + POLICY_HND *hnd, + QUERY_SERVICE_CONFIG *cfg, + uint32 *buf_size); +BOOL svc_close(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd); /*The following definitions come from rpc_client/cli_wkssvc.c */ @@ -2540,6 +2549,7 @@ void make_svc_q_query_svc_config(SVC_Q_QUERY_SVC_CONFIG *q_c, POLICY_HND *hnd, uint32 buf_size); void svc_io_q_query_svc_config(char *desc, SVC_Q_QUERY_SVC_CONFIG *q_u, prs_struct *ps, int depth); void make_svc_r_query_svc_config(SVC_R_QUERY_SVC_CONFIG *r_c, + QUERY_SERVICE_CONFIG *cfg, uint32 buf_size); void svc_io_r_query_svc_config(char *desc, SVC_R_QUERY_SVC_CONFIG *r_u, prs_struct *ps, int depth); void make_svc_q_close(SVC_Q_CLOSE *q_c, POLICY_HND *hnd); @@ -2769,6 +2779,8 @@ void display_reg_value_info(FILE *out_hnd, enum action_type action, char *val_name, uint32 val_type, BUFFER2 *value); void display_reg_key_info(FILE *out_hnd, enum action_type action, char *key_name, time_t key_mod_time); +void display_query_svc_cfg(FILE *out_hnd, enum action_type action, + QUERY_SERVICE_CONFIG *cfg); void display_svc_info(FILE *out_hnd, enum action_type action, ENUM_SRVC_STATUS *svc); /*The following definitions come from rpcclient/rpcclient.c */ diff --git a/source3/include/rpc_svcctl.h b/source3/include/rpc_svcctl.h index dc7d48d6b3..8710a86276 100644 --- a/source3/include/rpc_svcctl.h +++ b/source3/include/rpc_svcctl.h @@ -58,8 +58,8 @@ typedef struct r_svc_open_sc_man_info typedef struct q_svc_open_service_info { POLICY_HND scman_pol; - UNISTR2 uni_srv_name; /* unicode server name starting with '\\' */ - uint32 des_access; /* 0x80000004 - SC_MANAGER_xxxx */ + UNISTR2 uni_svc_name; /* unicode service name */ + uint32 des_access; /* 0x8000 0001 */ } SVC_Q_OPEN_SERVICE; diff --git a/source3/rpc_client/cli_svcctl.c b/source3/rpc_client/cli_svcctl.c index f14a699802..ebf8c15dc4 100644 --- a/source3/rpc_client/cli_svcctl.c +++ b/source3/rpc_client/cli_svcctl.c @@ -34,7 +34,7 @@ extern int DEBUGLEVEL; /**************************************************************************** do a SVC Open Policy ****************************************************************************/ -BOOL do_svc_open_sc_man(struct cli_state *cli, uint16 fnum, +BOOL svc_open_sc_man(struct cli_state *cli, uint16 fnum, char *srv_name, char *db_name, uint32 des_access, POLICY_HND *hnd) @@ -91,10 +91,71 @@ BOOL do_svc_open_sc_man(struct cli_state *cli, uint16 fnum, } +/**************************************************************************** +do a SVC Open Service +****************************************************************************/ +BOOL svc_open_service(struct cli_state *cli, uint16 fnum, + POLICY_HND *scm_hnd, + char *srv_name, + uint32 des_access, + POLICY_HND *hnd) +{ + prs_struct rbuf; + prs_struct buf; + SVC_Q_OPEN_SERVICE q_o; + BOOL valid_pol = False; + + if (hnd == NULL || scm_hnd == NULL) return False; + + prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); + prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True ); + + /* create and send a MSRPC command with api SVC_OPEN_SERVICE */ + + DEBUG(4,("SVC Open Service\n")); + + make_svc_q_open_service(&q_o, scm_hnd, srv_name, des_access); + + /* turn parameters into data stream */ + svc_io_q_open_service("", &q_o, &buf, 0); + + /* send the data on \PIPE\ */ + if (rpc_api_pipe_req(cli, fnum, SVC_OPEN_SERVICE, &buf, &rbuf)) + { + SVC_R_OPEN_SERVICE r_o; + BOOL p; + + ZERO_STRUCT(r_o); + + svc_io_r_open_service("", &r_o, &rbuf, 0); + p = rbuf.offset != 0; + + if (p && r_o.status != 0) + { + /* report error code */ + DEBUG(0,("SVC_OPEN_SC_MAN: %s\n", get_nt_error_msg(r_o.status))); + p = False; + } + + if (p) + { + /* ok, at last: we're happy. return the policy handle */ + memcpy(hnd, r_o.pol.data, sizeof(hnd->data)); + valid_pol = True; + } + } + + prs_mem_free(&rbuf); + prs_mem_free(&buf ); + + return valid_pol; +} + + /**************************************************************************** do a SVC Enumerate Services ****************************************************************************/ -BOOL do_svc_enum_svcs(struct cli_state *cli, uint16 fnum, +BOOL svc_enum_svcs(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd, uint32 services_type, uint32 services_state, uint32 *buf_size, uint32 *resume_hnd, @@ -161,10 +222,72 @@ BOOL do_svc_enum_svcs(struct cli_state *cli, uint16 fnum, } +/**************************************************************************** +do a SVC Query Service Config +****************************************************************************/ +BOOL svc_query_svc_cfg(struct cli_state *cli, uint16 fnum, + POLICY_HND *hnd, + QUERY_SERVICE_CONFIG *cfg, + uint32 *buf_size) +{ + prs_struct rbuf; + prs_struct buf; + SVC_Q_QUERY_SVC_CONFIG q_c; + BOOL valid_cfg = False; + + if (hnd == NULL || buf_size == NULL) return False; + + /* create and send a MSRPC command with api SVC_QUERY_SVC_CONFIG */ + + prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); + prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True ); + + DEBUG(4,("SVC Query Service Config\n")); + + /* store the parameters */ + make_svc_q_query_svc_config(&q_c, hnd, *buf_size); + + /* turn parameters into data stream */ + svc_io_q_query_svc_config("", &q_c, &buf, 0); + + /* send the data on \PIPE\ */ + if (rpc_api_pipe_req(cli, fnum, SVC_QUERY_SVC_CONFIG, &buf, &rbuf)) + { + SVC_R_QUERY_SVC_CONFIG r_c; + BOOL p; + + ZERO_STRUCT (r_c); + ZERO_STRUCTP(cfg); + + r_c.cfg = cfg; + + svc_io_r_query_svc_config("", &r_c, &rbuf, 0); + p = rbuf.offset != 0; + + if (p && r_c.status != 0) + { + /* report error code */ + DEBUG(0,("SVC_QUERY_SVC_CONFIG: %s\n", get_nt_error_msg(r_c.status))); + p = False; + } + + if (p) + { + valid_cfg = r_c.buf_size != 0; + } + } + + prs_mem_free(&rbuf); + prs_mem_free(&buf ); + + return valid_cfg; +} + + /**************************************************************************** do a SVC Close ****************************************************************************/ -BOOL do_svc_close(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd) +BOOL svc_close(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd) { prs_struct rbuf; prs_struct buf; diff --git a/source3/rpc_parse/parse_svc.c b/source3/rpc_parse/parse_svc.c index 912582f35e..9c1f0f3335 100644 --- a/source3/rpc_parse/parse_svc.c +++ b/source3/rpc_parse/parse_svc.c @@ -106,7 +106,7 @@ void make_svc_q_open_service(SVC_Q_OPEN_SERVICE *q_u, DEBUG(5,("make_svc_q_open_service\n")); memcpy(&(q_u->scman_pol), hnd, sizeof(q_u->scman_pol)); - make_unistr2(&(q_u->uni_srv_name), server, strlen(server)+1); + make_unistr2(&(q_u->uni_svc_name), server, strlen(server)+1); q_u->des_access = des_access; } @@ -126,7 +126,7 @@ void svc_io_q_open_service(char *desc, SVC_Q_OPEN_SERVICE *q_u, prs_struct *ps, smb_io_pol_hnd("", &(q_u->scman_pol), ps, depth); prs_align(ps); - smb_io_unistr2("", &(q_u->uni_srv_name), 1, ps, depth); + smb_io_unistr2("", &(q_u->uni_svc_name), 1, ps, depth); prs_align(ps); prs_uint32("des_access", ps, depth, &(q_u->des_access)); @@ -492,12 +492,14 @@ void svc_io_q_query_svc_config(char *desc, SVC_Q_QUERY_SVC_CONFIG *q_u, prs_str makes an SVC_R_QUERY_SVC_CONFIG structure. ********************************************************************/ void make_svc_r_query_svc_config(SVC_R_QUERY_SVC_CONFIG *r_c, + QUERY_SERVICE_CONFIG *cfg, uint32 buf_size) { if (r_c == NULL) return; DEBUG(5,("make_svc_r_query_svc_config\n")); + r_c->cfg = cfg; r_c->buf_size = buf_size; } diff --git a/source3/rpcclient/cmd_svcctl.c b/source3/rpcclient/cmd_svcctl.c index 162b0204b7..e30c20af64 100644 --- a/source3/rpcclient/cmd_svcctl.c +++ b/source3/rpcclient/cmd_svcctl.c @@ -50,6 +50,8 @@ void cmd_svc_enum(struct client_info *info) uint32 dos_error = 0; ENUM_SRVC_STATUS *svcs = NULL; uint32 num_svcs = 0; + fstring tmp; + BOOL request_info = False; POLICY_HND sc_man_pol; @@ -61,11 +63,16 @@ void cmd_svc_enum(struct client_info *info) DEBUG(4,("cmd_svc_enum: server:%s\n", srv_name)); + if (next_token(NULL, tmp, NULL, sizeof(tmp))) + { + request_info = strequal(tmp, "-i"); + } + /* 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 ? do_svc_open_sc_man(smb_cli, fnum, + res = res ? svc_open_sc_man(smb_cli, fnum, srv_name, NULL, 0x80000004, &sc_man_pol) : False; @@ -74,7 +81,7 @@ void cmd_svc_enum(struct client_info *info) buf_size += 0x800; /* enumerate services */ - res1 = res ? do_svc_enum_svcs(smb_cli, fnum, + res1 = res ? svc_enum_svcs(smb_cli, fnum, &sc_man_pol, 0x00000030, 0x00000003, &buf_size, &resume_hnd, &dos_error, @@ -88,14 +95,39 @@ void cmd_svc_enum(struct client_info *info) fprintf(out_hnd,"--------\n"); } - for (i = 0; i < num_svcs && svcs != NULL; i++) + for (i = 0; i < num_svcs && svcs != NULL && res1; i++) { - if (res1) + BOOL res2 = request_info; + BOOL res3; + POLICY_HND svc_pol; + fstring svc_name; + QUERY_SERVICE_CONFIG cfg; + uint32 svc_buf_size = 0x800; + + fstrcpy(svc_name, unistr2(svcs[i].uni_srvc_name.buffer)); + + res2 = res2 ? svc_open_service(smb_cli, fnum, + &sc_man_pol, + svc_name, 0x80000001, + &svc_pol) : False; + res3 = res2 ? svc_query_svc_cfg(smb_cli, fnum, + &svc_pol, &cfg, + &svc_buf_size) : False; + + if (res3) + { + display_query_svc_cfg(out_hnd, ACTION_HEADER , &cfg); + display_query_svc_cfg(out_hnd, ACTION_ENUMERATE, &cfg); + display_query_svc_cfg(out_hnd, ACTION_FOOTER , &cfg); + } + else { display_svc_info(out_hnd, ACTION_HEADER , &svcs[i]); display_svc_info(out_hnd, ACTION_ENUMERATE, &svcs[i]); display_svc_info(out_hnd, ACTION_FOOTER , &svcs[i]); } + + res2 = res2 ? svc_close(smb_cli, fnum, &svc_pol) : False; } if (svcs != NULL) @@ -103,7 +135,7 @@ void cmd_svc_enum(struct client_info *info) free(svcs); } - res = res ? do_svc_close(smb_cli, fnum, &sc_man_pol) : False; + res = res ? svc_close(smb_cli, fnum, &sc_man_pol) : False; /* close the session */ cli_nt_session_close(smb_cli, fnum); diff --git a/source3/rpcclient/display.c b/source3/rpcclient/display.c index 800b89e563..d37b7283f8 100644 --- a/source3/rpcclient/display.c +++ b/source3/rpcclient/display.c @@ -1535,6 +1535,62 @@ void display_reg_key_info(FILE *out_hnd, enum action_type action, } } +/**************************************************************************** +convert a security permissions into a string +****************************************************************************/ +char *get_svc_start_type_str(uint32 type) +{ + static fstring typestr; + + switch (type) + { + case 0x00: fstrcpy(typestr, "Boot" ); return typestr; + case 0x01: fstrcpy(typestr, "System" ); return typestr; + case 0x02: fstrcpy(typestr, "Auto" ); return typestr; + case 0x03: fstrcpy(typestr, "Manual" ); return typestr; + case 0x04: fstrcpy(typestr, "Disabled"); return typestr; + default : break; + } + slprintf(typestr, sizeof(typestr)-1, "[%d]", type); + return typestr; +} + + +/**************************************************************************** + display structure + ****************************************************************************/ +void display_query_svc_cfg(FILE *out_hnd, enum action_type action, + QUERY_SERVICE_CONFIG *cfg) +{ + switch (action) + { + case ACTION_HEADER: + { + fprintf(out_hnd, "\tService:\t%s\n", unistr2_to_str(&cfg->uni_display_name)); /* service name unicode string */ + fprintf(out_hnd, "\t-------\n"); + break; + } + case ACTION_ENUMERATE: + { + fprintf(out_hnd, "\tPath:\t%s\n" , unistr2_to_str(&cfg->uni_bin_path_name)); + fprintf(out_hnd, "\tLoad Order:\t%s\n" , unistr2_to_str(&cfg->uni_load_order_grp)); + fprintf(out_hnd, "\tDependencies:\t%s\n" , unistr2_to_str(&cfg->uni_dependencies)); + fprintf(out_hnd, "\tService Start:\t%s\n", unistr2_to_str(&cfg->uni_service_start_name)); + fprintf(out_hnd, "\tService Type:\t%d\n" , cfg->service_type); + fprintf(out_hnd, "\tStart Type:\t%s\n" , get_svc_start_type_str(cfg->start_type)); + fprintf(out_hnd, "\tError Control:\t%d\n" , cfg->error_control); + fprintf(out_hnd, "\tTag Id:\t%d\n" , cfg->tag_id); + break; + + } + case ACTION_FOOTER: + { + fprintf(out_hnd, "\n"); + break; + } + } +} + /**************************************************************************** display structure ****************************************************************************/ diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index f2926276bc..79ab1b68a1 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -105,7 +105,7 @@ struct char *description; } commands[] = { - {"svcenum", cmd_svc_enum, "Services Manager Enumeration"}, + {"svcenum", cmd_svc_enum, "[-i] Lists Services Manager"}, {"regenum", cmd_reg_enum, " Registry Enumeration (keys, values)"}, {"regdeletekey",cmd_reg_delete_key, " Registry Key Delete"}, {"regcreatekey",cmd_reg_create_key, " [keyclass] Registry Key Create"}, -- cgit