From 7135fb0a2c869169996206a9c1cf5ac1112b9f0a Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 8 Dec 1998 23:29:37 +0000 Subject: adding "Service Control Manager" commands to rpcclient. (This used to be commit e5ee965f8d8452ab694bc5d88e474c4b91dce5b0) --- source3/Makefile.in | 2 + source3/include/proto.h | 31 +++++- source3/include/rpc_svcctl.h | 64 +++++++++-- source3/rpc_client/cli_svcctl.c | 230 ++++++++++++++++++++++++++++++++++++++++ source3/rpc_parse/parse_svc.c | 117 +++++++++++++++++--- source3/rpc_server/srv_svcctl.c | 28 ++--- source3/rpcclient/cmd_svcctl.c | 119 +++++++++++++++++++++ source3/rpcclient/rpcclient.c | 1 + 8 files changed, 551 insertions(+), 41 deletions(-) create mode 100644 source3/rpc_client/cli_svcctl.c create mode 100644 source3/rpcclient/cmd_svcctl.c diff --git a/source3/Makefile.in b/source3/Makefile.in index 837e7fcf8a..88b0168cda 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -146,6 +146,7 @@ RPC_CLIENT_OBJ = \ rpc_client/cli_lsarpc.o \ rpc_client/cli_wkssvc.o \ rpc_client/cli_srvsvc.o \ + rpc_client/cli_svcctl.o \ rpc_client/cli_samr.o @@ -234,6 +235,7 @@ RPCCLIENT_OBJ = rpcclient/rpcclient.o \ rpcclient/cmd_samr.o \ rpcclient/cmd_reg.o \ rpcclient/cmd_srvsvc.o \ + rpcclient/cmd_svcctl.o \ rpcclient/cmd_netlogon.o \ $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \ $(RPC_CLIENT_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_OBJ) diff --git a/source3/include/proto.h b/source3/include/proto.h index 0c4b25a21f..de2d6f476c 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1769,6 +1769,18 @@ BOOL do_srv_net_srv_file_enum(struct cli_state *cli, uint16 fnum, BOOL do_srv_net_srv_get_info(struct cli_state *cli, uint16 fnum, char *server_name, uint32 switch_value, SRV_INFO_CTR *ctr); +/*The following definitions come from rpc_client/cli_svcctl.c */ + +BOOL do_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, + POLICY_HND *hnd, + uint32 services_type, uint32 services_state, + uint32 buf_size, uint32 *resume_hnd); +BOOL do_svc_close(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd); + /*The following definitions come from rpc_client/cli_wkssvc.c */ BOOL do_wks_query_info(struct cli_state *cli, uint16 fnum, @@ -2482,12 +2494,17 @@ void srv_io_r_net_remote_tod(char *desc, SRV_R_NET_REMOTE_TOD *r_n, prs_struct * /*The following definitions come from rpc_parse/parse_svc.c */ -void make_svc_q_open_policy(SVC_Q_OPEN_POLICY *q_u, - char *server, uint16 unknown) ; -void svc_io_q_open_policy(char *desc, SVC_Q_OPEN_POLICY *q_u, prs_struct *ps, int depth); -void make_svc_r_open_policy(SVC_R_OPEN_POLICY *r_u, POLICY_HND *hnd, +void make_svc_q_open_sc_man(SVC_Q_OPEN_SC_MAN *q_u, + char *server, char *database, + uint32 des_access) ; +void svc_io_q_open_sc_man(char *desc, SVC_Q_OPEN_SC_MAN *q_u, prs_struct *ps, int depth); +void make_svc_r_open_sc_man(SVC_R_OPEN_SC_MAN *r_u, POLICY_HND *hnd, uint32 status) ; -void svc_io_r_open_policy(char *desc, SVC_R_OPEN_POLICY *r_u, prs_struct *ps, int depth); +void svc_io_r_open_sc_man(char *desc, SVC_R_OPEN_SC_MAN *r_u, prs_struct *ps, int depth); +void make_svc_q_enum_svcs_status(SVC_Q_ENUM_SVCS_STATUS *q_c, POLICY_HND *hnd, + uint32 service_type, uint32 service_state, + uint32 buf_size, uint32 enum_hnd ); +void svc_io_q_enum_svcs_status(char *desc, SVC_Q_ENUM_SVCS_STATUS *q_u, prs_struct *ps, int depth); void make_svc_q_close(SVC_Q_CLOSE *q_c, POLICY_HND *hnd); void svc_io_q_close(char *desc, SVC_Q_CLOSE *q_u, prs_struct *ps, int depth); void svc_io_r_close(char *desc, SVC_R_CLOSE *r_u, prs_struct *ps, int depth); @@ -2637,6 +2654,10 @@ void cmd_srv_enum_shares(struct client_info *info); void cmd_srv_enum_sess(struct client_info *info); void cmd_srv_enum_files(struct client_info *info); +/*The following definitions come from rpcclient/cmd_svcctl.c */ + +void cmd_svc_enum(struct client_info *info); + /*The following definitions come from rpcclient/cmd_wkssvc.c */ void cmd_wks_query_info(struct client_info *info); diff --git a/source3/include/rpc_svcctl.h b/source3/include/rpc_svcctl.h index 0a98496c79..4241928218 100644 --- a/source3/include/rpc_svcctl.h +++ b/source3/include/rpc_svcctl.h @@ -26,27 +26,73 @@ /* svcctl pipe */ -#define SVC_OPEN_POLICY 0x0f -#define SVC_CLOSE 0x00 +#define SVC_OPEN_SC_MAN 0x0f +#define SVC_ENUM_SVCS_STATUS 0x0e +#define SVC_CLOSE 0x00 -/* SVC_Q_OPEN_POLICY */ -typedef struct q_svc_open_pol_info +/* SVC_Q_OPEN_SC_MAN */ +typedef struct q_svc_open_sc_man_info { uint32 ptr_srv_name; /* pointer (to server name?) */ UNISTR2 uni_srv_name; /* unicode server name starting with '\\' */ - uint32 unknown; /* unknown */ + uint32 ptr_db_name; /* pointer (to database name?) */ + UNISTR2 uni_db_name; /* unicode database name */ -} SVC_Q_OPEN_POLICY; + uint32 des_access; /* 0x80000004 - SC_MANAGER_xxxx */ -/* SVC_R_OPEN_POLICY */ -typedef struct r_svc_open_pol_info +} SVC_Q_OPEN_SC_MAN; + +/* SVC_R_OPEN_SC_MAN */ +typedef struct r_svc_open_sc_man_info { POLICY_HND pol; uint32 status; /* return status */ -} SVC_R_OPEN_POLICY; +} SVC_R_OPEN_SC_MAN; + +/* SVC_STATUS */ +typedef struct svc_status_info +{ + uint32 svc_type; + uint32 current_state; + uint32 controls_accepted; + uint32 win32_exit_code; + uint32 svc_specific_exit_code; + uint32 check_point; + uint32 wait_hint; + +} SVC_STATUS; + +/* ENUM_SVC_STATUS */ +typedef struct enum_svc_status_info +{ + UNISTR uni_srvc_name; + UNISTR uni_disp_name; + SVC_STATUS status; + +} ENUM_SVC_STATUS; + +/* SVC_Q_ENUM_SVCS_STATUS */ +typedef struct q_svc_enum_svcs_status_info +{ + POLICY_HND pol; + uint32 service_type; /* 0x00000030 - win32 | 0x0000000b - driver */ + uint32 service_state; /* 0x00000003 - state_all */ + uint32 buf_size; /* max service buffer size */ + ENUM_HND resume_hnd; /* resume handle */ + +} SVC_Q_ENUM_SVCS_STATUS; + +/* SVC_R_ENUM_SVCS_STATUS */ +typedef struct r_svc_enum_svcs_status_info +{ + uint32 buf_size; /* service buffer size */ + ENUM_SVC_STATUS *svcs; + uint32 status; /* return status */ + +} SVC_R_ENUM_SVCS_STATUS; /* SVC_Q_CLOSE */ diff --git a/source3/rpc_client/cli_svcctl.c b/source3/rpc_client/cli_svcctl.c new file mode 100644 index 0000000000..90d74188da --- /dev/null +++ b/source3/rpc_client/cli_svcctl.c @@ -0,0 +1,230 @@ + +/* + * Unix SMB/Netbios implementation. + * Version 1.9. + * RPC Pipe client / server routines + * Copyright (C) Andrew Tridgell 1992-1998, + * Copyright (C) Luke Kenneth Casson Leighton 1996-1998, + * Copyright (C) Paul Ashton 1997-1998. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#ifdef SYSLOG +#undef SYSLOG +#endif + +#include "includes.h" + +extern int DEBUGLEVEL; + +/**************************************************************************** +do a SVC Open Policy +****************************************************************************/ +BOOL do_svc_open_sc_man(struct cli_state *cli, uint16 fnum, + char *srv_name, char *db_name, + uint32 des_access, + POLICY_HND *hnd) +{ + prs_struct rbuf; + prs_struct buf; + SVC_Q_OPEN_SC_MAN q_o; + BOOL valid_pol = False; + + if (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_SC_MAN */ + + DEBUG(4,("SVC Open SC_MAN\n")); + + make_svc_q_open_sc_man(&q_o, srv_name, db_name, des_access); + + /* turn parameters into data stream */ + svc_io_q_open_sc_man("", &q_o, &buf, 0); + + /* send the data on \PIPE\ */ + if (rpc_api_pipe_req(cli, fnum, SVC_OPEN_SC_MAN, &buf, &rbuf)) + { + SVC_R_OPEN_SC_MAN r_o; + BOOL p; + + ZERO_STRUCT(r_o); + + svc_io_r_open_sc_man("", &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, + POLICY_HND *hnd, + uint32 services_type, uint32 services_state, + uint32 buf_size, uint32 *resume_hnd) +{ + prs_struct rbuf; + prs_struct buf; + SVC_Q_ENUM_SVCS_STATUS q_o; + BOOL valid_pol = False; + + if (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_ENUM_SVCS_STATUS */ + + DEBUG(4,("SVC Enum Services Status\n")); + + make_svc_q_enum_svcs_status(&q_o, hnd, + services_type, services_state, + buf_size, *resume_hnd); + + /* turn parameters into data stream */ + svc_io_q_enum_svcs_status("", &q_o, &buf, 0); + + /* send the data on \PIPE\ */ + if (rpc_api_pipe_req(cli, fnum, SVC_ENUM_SVCS_STATUS, &buf, &rbuf)) + { +#if 0 + SVC_R_ENUM_SVCS_STATUS r_o; + BOOL p; + + ZERO_STRUCT(r_o); + + svc_io_r_enum_svcs_status("", &r_o, &rbuf, 0); + p = rbuf.offset != 0; + + if (p && r_o.status != 0) + { + /* report error code */ + DEBUG(0,("SVC_ENUM_SVCS_STATUS: %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; + } +#else + valid_pol = True; +#endif + } + + prs_mem_free(&rbuf); + prs_mem_free(&buf ); + + return valid_pol; +} + + +/**************************************************************************** +do a SVC Close +****************************************************************************/ +BOOL do_svc_close(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd) +{ + prs_struct rbuf; + prs_struct buf; + SVC_Q_CLOSE q_c; + BOOL valid_close = False; + + if (hnd == NULL) return False; + + /* create and send a MSRPC command with api SVC_CLOSE */ + + prs_init(&buf , 1024, 4, SAFETY_MARGIN, False); + prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True ); + + DEBUG(4,("SVC Close\n")); + + /* store the parameters */ + make_svc_q_close(&q_c, hnd); + + /* turn parameters into data stream */ + svc_io_q_close("", &q_c, &buf, 0); + + /* send the data on \PIPE\ */ + if (rpc_api_pipe_req(cli, fnum, SVC_CLOSE, &buf, &rbuf)) + { + SVC_R_CLOSE r_c; + BOOL p; + + ZERO_STRUCT(r_c); + + svc_io_r_close("", &r_c, &rbuf, 0); + p = rbuf.offset != 0; + + if (p && r_c.status != 0) + { + /* report error code */ + DEBUG(0,("SVC_CLOSE: %s\n", get_nt_error_msg(r_c.status))); + p = False; + } + + if (p) + { + /* check that the returned policy handle is all zeros */ + int i; + valid_close = True; + + for (i = 0; i < sizeof(r_c.pol.data); i++) + { + if (r_c.pol.data[i] != 0) + { + valid_close = False; + break; + } + } + if (!valid_close) + { + DEBUG(0,("SVC_CLOSE: non-zero handle returned\n")); + } + } + } + + prs_mem_free(&rbuf); + prs_mem_free(&buf ); + + return valid_close; +} + + diff --git a/source3/rpc_parse/parse_svc.c b/source3/rpc_parse/parse_svc.c index 288f23f46b..2134d86f47 100644 --- a/source3/rpc_parse/parse_svc.c +++ b/source3/rpc_parse/parse_svc.c @@ -28,26 +28,28 @@ extern int DEBUGLEVEL; /******************************************************************* - make_svc_q_open_policy + make_svc_q_open_sc_man ********************************************************************/ -void make_svc_q_open_policy(SVC_Q_OPEN_POLICY *q_u, - char *server, uint16 unknown) +void make_svc_q_open_sc_man(SVC_Q_OPEN_SC_MAN *q_u, + char *server, char *database, + uint32 des_access) { - DEBUG(5,("make_svc_q_open_policy\n")); + DEBUG(5,("make_svc_q_open_sc_man\n")); make_buf_unistr2(&(q_u->uni_srv_name), &(q_u->ptr_srv_name), server); - q_u->unknown = unknown; + make_buf_unistr2(&(q_u->uni_db_name ), &(q_u->ptr_db_name), database); + q_u->des_access = des_access; } /******************************************************************* -reads or writes a SVC_Q_OPEN_POLICY structure. +reads or writes a SVC_Q_OPEN_SC_MAN structure. ********************************************************************/ -void svc_io_q_open_policy(char *desc, SVC_Q_OPEN_POLICY *q_u, prs_struct *ps, int depth) +void svc_io_q_open_sc_man(char *desc, SVC_Q_OPEN_SC_MAN *q_u, prs_struct *ps, int depth) { if (q_u == NULL) return; - prs_debug(ps, depth, desc, "svc_io_q_open_policy"); + prs_debug(ps, depth, desc, "svc_io_q_open_sc_man"); depth++; prs_align(ps); @@ -56,14 +58,18 @@ void svc_io_q_open_policy(char *desc, SVC_Q_OPEN_POLICY *q_u, prs_struct *ps, in smb_io_unistr2("", &(q_u->uni_srv_name), q_u->ptr_srv_name, ps, depth); prs_align(ps); - prs_uint32("unknown", ps, depth, &(q_u->unknown)); + prs_uint32("ptr_db_name", ps, depth, &(q_u->ptr_db_name)); + smb_io_unistr2("", &(q_u->uni_db_name), q_u->ptr_db_name, ps, depth); + prs_align(ps); + + prs_uint32("des_access", ps, depth, &(q_u->des_access)); prs_align(ps); } /******************************************************************* - make_svc_r_open_policy + make_svc_r_open_sc_man ********************************************************************/ -void make_svc_r_open_policy(SVC_R_OPEN_POLICY *r_u, POLICY_HND *hnd, +void make_svc_r_open_sc_man(SVC_R_OPEN_SC_MAN *r_u, POLICY_HND *hnd, uint32 status) { DEBUG(5,("make_svc_r_unknown_0: %d\n", __LINE__)); @@ -75,11 +81,11 @@ void make_svc_r_open_policy(SVC_R_OPEN_POLICY *r_u, POLICY_HND *hnd, /******************************************************************* reads or writes a structure. ********************************************************************/ -void svc_io_r_open_policy(char *desc, SVC_R_OPEN_POLICY *r_u, prs_struct *ps, int depth) +void svc_io_r_open_sc_man(char *desc, SVC_R_OPEN_SC_MAN *r_u, prs_struct *ps, int depth) { if (r_u == NULL) return; - prs_debug(ps, depth, desc, "svc_io_r_open_policy"); + prs_debug(ps, depth, desc, "svc_io_r_open_sc_man"); depth++; prs_align(ps); @@ -89,6 +95,45 @@ void svc_io_r_open_policy(char *desc, SVC_R_OPEN_POLICY *r_u, prs_struct *ps, i prs_uint32("status ", ps, depth, &(r_u->status)); } +/******************************************************************* +makes an SVC_Q_ENUM_SVCS_STATUS structure. +********************************************************************/ +void make_svc_q_enum_svcs_status(SVC_Q_ENUM_SVCS_STATUS *q_c, POLICY_HND *hnd, + uint32 service_type, uint32 service_state, + uint32 buf_size, uint32 resume_hnd ) +{ + if (q_c == NULL || hnd == NULL) return; + + DEBUG(5,("make_svc_q_enum_svcs_status\n")); + + memcpy(&(q_c->pol), hnd, sizeof(q_c->pol)); + q_c->service_type = service_type; + q_c->service_state = service_state; + q_c->buf_size = buf_size; + make_enum_hnd(&q_c->resume_hnd, resume_hnd); +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ +void svc_io_q_enum_svcs_status(char *desc, SVC_Q_ENUM_SVCS_STATUS *q_u, prs_struct *ps, int depth) +{ + if (q_u == NULL) return; + + prs_debug(ps, depth, desc, "svc_io_q_enum_svcs_status"); + depth++; + + prs_align(ps); + + smb_io_pol_hnd("", &(q_u->pol), ps, depth); + prs_align(ps); + + prs_uint32("service_type ", ps, depth, &(q_u->service_type )); + prs_uint32("service_state", ps, depth, &(q_u->service_state)); + prs_uint32("buf_size ", ps, depth, &(q_u->buf_size )); + smb_io_enum_hnd("resume_hnd", &(q_u->resume_hnd), ps, depth); +} + /******************************************************************* makes an SVC_Q_CLOSE structure. ********************************************************************/ @@ -98,6 +143,7 @@ void make_svc_q_close(SVC_Q_CLOSE *q_c, POLICY_HND *hnd) DEBUG(5,("make_svc_q_close\n")); + memcpy(&(q_c->pol), hnd, sizeof(q_c->pol)); } /******************************************************************* @@ -134,3 +180,48 @@ void svc_io_r_close(char *desc, SVC_R_CLOSE *r_u, prs_struct *ps, int depth) prs_uint32("status", ps, depth, &(r_u->status)); } +#if 0 +/******************************************************************* +reads or writes a SEC_DESC_BUF structure. +********************************************************************/ +void sec_io_desc_buf(char *desc, SEC_DESC_BUF *sec, prs_struct *ps, int depth) +{ + uint32 off_len; + uint32 old_offset; + uint32 size; + + if (sec == NULL) return; + + prs_debug(ps, depth, desc, "sec_io_desc_buf"); + depth++; + + prs_align(ps); + + prs_uint32_pre("max_len", ps, depth, &(sec->max_len), &off_max_len); + + old_offset = ps->offset; + + if (sec->len != 0 && ps->io) + { + /* reading */ + sec->sec = malloc(sizeof(*sec->sec)); + ZERO_STRUCTP(sec->sec); + + if (sec->sec == NULL) + { + DEBUG(0,("INVALID SEC_DESC\n")); + ps->offset = 0xfffffffe; + return; + } + } + + /* reading, length is non-zero; writing, descriptor is non-NULL */ + if ((sec->len != 0 || (!ps->io)) && sec->sec != NULL) + { + sec_io_desc("sec ", sec->sec, ps, depth); + } + + size = ps->offset - old_offset; + prs_uint32_post("max_len", ps, depth, &(sec->max_len), off_max_len, size == 0 ? sec->max_len : size); +} +#endif diff --git a/source3/rpc_server/srv_svcctl.c b/source3/rpc_server/srv_svcctl.c index 6ae8a5c873..be99063946 100644 --- a/source3/rpc_server/srv_svcctl.c +++ b/source3/rpc_server/srv_svcctl.c @@ -71,17 +71,17 @@ static void api_svc_close( uint16 vuid, prs_struct *data, /******************************************************************* - svc_reply_open_policy + svc_reply_open_sc_man ********************************************************************/ -static void svc_reply_open_policy(SVC_Q_OPEN_POLICY *q_u, +static void svc_reply_open_sc_man(SVC_Q_OPEN_SC_MAN *q_u, prs_struct *rdata) { uint32 status = 0; POLICY_HND pol; - SVC_R_OPEN_POLICY r_u; + SVC_R_OPEN_SC_MAN r_u; fstring name; - DEBUG(5,("svc_open_policy: %d\n", __LINE__)); + DEBUG(5,("svc_open_sc_man: %d\n", __LINE__)); if (status == 0x0 && !open_lsa_policy_hnd(&pol)) { @@ -92,7 +92,7 @@ static void svc_reply_open_policy(SVC_Q_OPEN_POLICY *q_u, if (status == 0x0) { - DEBUG(5,("svc_open_policy: %s\n", name)); + DEBUG(5,("svc_open_sc_man: %s\n", name)); /* lkcl XXXX do a check on the name, here */ } @@ -101,23 +101,23 @@ static void svc_reply_open_policy(SVC_Q_OPEN_POLICY *q_u, status = 0xC000000 | NT_STATUS_TOO_MANY_SECRETS; /* ha ha very droll */ } - make_svc_r_open_policy(&r_u, &pol, status); + make_svc_r_open_sc_man(&r_u, &pol, status); /* store the response in the SMB stream */ - svc_io_r_open_policy("", &r_u, rdata, 0); + svc_io_r_open_sc_man("", &r_u, rdata, 0); - DEBUG(5,("svc_open_policy: %d\n", __LINE__)); + DEBUG(5,("svc_open_sc_man: %d\n", __LINE__)); } /******************************************************************* - api_svc_open_policy + api_svc_open_sc_man ********************************************************************/ -static void api_svc_open_policy( uint16 vuid, prs_struct *data, +static void api_svc_open_sc_man( uint16 vuid, prs_struct *data, prs_struct *rdata ) { - SVC_Q_OPEN_POLICY q_u; - svc_io_q_open_policy("", &q_u, data, 0); - svc_reply_open_policy(&q_u, rdata); + SVC_Q_OPEN_SC_MAN q_u; + svc_io_q_open_sc_man("", &q_u, data, 0); + svc_reply_open_sc_man(&q_u, rdata); } /******************************************************************* @@ -126,7 +126,7 @@ static void api_svc_open_policy( uint16 vuid, prs_struct *data, static struct api_struct api_svc_cmds[] = { { "SVC_CLOSE" , SVC_CLOSE , api_svc_close }, - { "SVC_OPEN_POLICY" , SVC_OPEN_POLICY , api_svc_open_policy }, + { "SVC_OPEN_SC_MAN" , SVC_OPEN_SC_MAN , api_svc_open_sc_man }, { NULL, 0 , NULL } }; diff --git a/source3/rpcclient/cmd_svcctl.c b/source3/rpcclient/cmd_svcctl.c new file mode 100644 index 0000000000..63f0d9651c --- /dev/null +++ b/source3/rpcclient/cmd_svcctl.c @@ -0,0 +1,119 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + NT Domain Authentication SMB / MSRPC client + Copyright (C) Andrew Tridgell 1994-1997 + Copyright (C) Luke Kenneth Casson Leighton 1996-1997 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + + +#ifdef SYSLOG +#undef SYSLOG +#endif + +#include "includes.h" +#include "nterr.h" + +extern int DEBUGLEVEL; + +extern struct cli_state *smb_cli; +extern int smb_tidx; + +extern FILE* out_hnd; + +/**************************************************************************** +nt svcistry enum +****************************************************************************/ +void cmd_svc_enum(struct client_info *info) +{ + uint16 fnum; + BOOL res = True; + BOOL res1 = True; + int i; + uint32 resume_hnd = 0; + + POLICY_HND sc_man_pol; + fstring full_keyname; + fstring srv_name; + + fstrcpy(srv_name, "\\\\"); + fstrcat(srv_name, info->myhostname); + strupper(srv_name); + + DEBUG(4,("cmd_svc_enum: server:%s\n", srv_name)); + + /* 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, + srv_name, NULL, 0x80000004, + &sc_man_pol) : False; + + /* enumerate services */ + res1 = res ? do_svc_enum_svcs(smb_cli, fnum, + &sc_man_pol, + 0x00000030, 0x00000003, + 0x00000200, &resume_hnd) : False; + +#if 0 + if (res1 && num_subkeys > 0) + { + fprintf(out_hnd,"Subkeys\n"); + fprintf(out_hnd,"-------\n"); + } + + for (i = 0; i < num_subkeys; i++) + { + BOOL res2 = True; + /* + * enumerate key + */ + + /* enum key */ + res2 = res2 ? do_svc_enum_key(smb_cli, fnum, &key_pol, + i, enum_name, + &enum_unk1, &enum_unk2, + &key_mod_time) : False; + + if (res2) + { + display_svc_key_info(out_hnd, ACTION_HEADER , enum_name, key_mod_time); + display_svc_key_info(out_hnd, ACTION_ENUMERATE, enum_name, key_mod_time); + display_svc_key_info(out_hnd, ACTION_FOOTER , enum_name, key_mod_time); + } + + } + + } +#endif + res = res ? do_svc_close(smb_cli, fnum, &sc_man_pol) : False; + + /* close the session */ + cli_nt_session_close(smb_cli, fnum); + + if (res && res1) + { + DEBUG(5,("cmd_svc_enum: query succeeded\n")); + } + else + { + DEBUG(5,("cmd_svc_enum: query failed\n")); + } +} + diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index 7bd4a5aae4..fd677f73bb 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -105,6 +105,7 @@ struct char *description; } commands[] = { + {"svcenum", cmd_svc_enum, "Services Manager Enumeration"}, {"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