From 52fb07aea26cc3041e571fafdc843622f1741a19 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 16 Feb 1999 18:04:21 +0000 Subject: rpcclient shutdown command (This used to be commit 59f081069a58f6a070ed6016c06153d5e695da93) --- source3/include/proto.h | 13 +++++++-- source3/include/rpc_reg.h | 21 +++++++++++++++ source3/include/smb.h | 7 +++++ source3/rpc_client/cli_reg.c | 55 +++++++++++++++++++++++++++++++++++++ source3/rpc_parse/parse_reg.c | 63 +++++++++++++++++++++++++++++++++++++++++++ source3/rpcclient/cmd_reg.c | 45 +++++++++++++++++++++++++++++++ source3/rpcclient/rpcclient.c | 1 + 7 files changed, 203 insertions(+), 2 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 1d3b041e4d..a1b8f2eeac 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -561,6 +561,8 @@ BOOL string_set(char **dest,const char *src); void string_sub(char *s,const char *pattern,const char *insert); void all_string_sub(char *s,const char *pattern,const char *insert); void split_at_last_component(char *path, char *front, char sep, char *back); +char *bit_field_to_str(uint32 type, struct field_info *bs); +char *enum_field_to_str(uint32 type, struct field_info *bs, BOOL first_default); /*The following definitions come from lib/util_unistr.c */ @@ -568,11 +570,11 @@ char *ascii_to_unibuf(char *dest, const char *src, int maxlen); void unibuf_to_ascii(char *dest, const char *src, int maxlen); void ascii_to_unistr(uint16 *dest, const char *src, int maxlen); void unistr_to_ascii(char *dest, const uint16 *src, int len); -void unistr2_to_ascii(char *dest, const UNISTR2 *str, int destlen); +void unistr2_to_ascii(char *dest, const UNISTR2 *str, int maxlen); char *skip_unibuf(char *srcbuf, int len); char *uni_strncpy(char *destbuf, const char *srcbuf, int len); uint32 buffer2_to_uint32(const BUFFER2 *str); -void buffer2_to_multistr(char *dest, const BUFFER2 *str, int destlen); +void buffer2_to_multistr(char *dest, const BUFFER2 *str, int maxlen); /*The following definitions come from libsmb/clientgen.c */ @@ -1632,6 +1634,8 @@ BOOL do_reg_open_entry(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd, char *key_name, uint32 unk_0, POLICY_HND *key_hnd); BOOL do_reg_close(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd); +BOOL do_reg_shutdown(struct cli_state *cli, uint16 fnum, + char *msg, uint32 timeout, uint16 flags); /*The following definitions come from rpc_client/cli_samr.c */ @@ -2092,6 +2096,10 @@ void reg_io_q_open_entry(char *desc, REG_Q_OPEN_ENTRY *r_q, prs_struct *ps, int void make_reg_r_open_entry(REG_R_OPEN_ENTRY *r_r, POLICY_HND *pol, uint32 status); void reg_io_r_open_entry(char *desc, REG_R_OPEN_ENTRY *r_r, prs_struct *ps, int depth); +void make_reg_q_shutdown(REG_Q_SHUTDOWN *q_i, + char *msg, uint32 timeout, uint16 flags); +void reg_io_q_shutdown(char *desc, REG_Q_SHUTDOWN *q_q, prs_struct *ps, int depth); +void reg_io_r_shutdown(char *desc, REG_R_SHUTDOWN *r_q, prs_struct *ps, int depth); /*The following definitions come from rpc_parse/parse_rpc.c */ @@ -2677,6 +2685,7 @@ void cmd_reg_delete_key(struct client_info *info); void cmd_reg_create_key(struct client_info *info); void cmd_reg_test_key_sec(struct client_info *info); void cmd_reg_get_key_sec(struct client_info *info); +void cmd_reg_shutdown(struct client_info *info); /*The following definitions come from rpcclient/cmd_samr.c */ diff --git a/source3/include/rpc_reg.h b/source3/include/rpc_reg.h index 7766052588..cc163540d7 100644 --- a/source3/include/rpc_reg.h +++ b/source3/include/rpc_reg.h @@ -42,6 +42,7 @@ #define REG_OPEN_ENTRY 0x0f #define REG_INFO 0x11 #define REG_CLOSE 0x05 +#define REG_SHUTDOWN 0x18 #define HKEY_LOCAL_MACHINE 0x80000000 #define HKEY_USERS 0x80000003 @@ -461,6 +462,26 @@ typedef struct r_reg_open_entry_info } REG_R_OPEN_ENTRY; +/* REG_Q_SHUTDOWN */ +typedef struct q_reg_shutdown_info +{ + uint32 ptr_0; + uint32 ptr_1; + uint32 ptr_2; + UNIHDR hdr_msg; /* shutdown message */ + UNISTR2 uni_msg; + uint32 timeout; /* seconds */ + uint16 flags; + +} REG_Q_SHUTDOWN; + +/* REG_R_SHUTDOWN */ +typedef struct r_reg_shutdown_info +{ + uint32 status; /* return status */ + +} REG_R_SHUTDOWN; + #endif /* _RPC_REG_H */ diff --git a/source3/include/smb.h b/source3/include/smb.h index 662ba245b1..daf617bd7f 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -1900,6 +1900,13 @@ struct nmb_name { #define MAP_TO_GUEST_ON_BAD_USER 1 #define MAP_TO_GUEST_ON_BAD_PASSWORD 2 +/* associate bit field or enumeration field with a string */ +struct field_info +{ + uint32 bits; + char *str; +}; + #endif /* _SMB_H */ /* _SMB_H */ diff --git a/source3/rpc_client/cli_reg.c b/source3/rpc_client/cli_reg.c index 166617ff37..fc7f6a5b53 100644 --- a/source3/rpc_client/cli_reg.c +++ b/source3/rpc_client/cli_reg.c @@ -1041,4 +1041,59 @@ BOOL do_reg_close(struct cli_state *cli, uint16 fnum, POLICY_HND *hnd) return valid_close; } +/**************************************************************************** +do a REG Shutdown Server +****************************************************************************/ +BOOL do_reg_shutdown(struct cli_state *cli, uint16 fnum, + char *msg, uint32 timeout, uint16 flags) +{ + prs_struct rbuf; + prs_struct buf; + REG_Q_SHUTDOWN q_o; + BOOL valid_shutdown = False; + + if (msg == 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 REG_SHUTDOWN */ + + DEBUG(4,("REG Shutdown: (timeout: %d secs) %s\n", timeout, msg)); + + make_reg_q_shutdown(&q_o, msg, timeout, flags); + + /* turn parameters into data stream */ + reg_io_q_shutdown("", &q_o, &buf, 0); + + /* send the data on \PIPE\ */ + if (rpc_api_pipe_req(cli, fnum, REG_SHUTDOWN, &buf, &rbuf)) + { + REG_R_SHUTDOWN r_o; + BOOL p; + + ZERO_STRUCT(r_o); + + reg_io_r_shutdown("", &r_o, &rbuf, 0); + p = rbuf.offset != 0; + + if (p && r_o.status != 0) + { + /* report error code */ + DEBUG(0,("REG_SHUTDOWN: %s\n", get_nt_error_msg(r_o.status))); + p = False; + } + + if (p) + { + valid_shutdown = True; + } + } + + prs_mem_free(&rbuf); + prs_mem_free(&buf ); + + return valid_shutdown; +} + diff --git a/source3/rpc_parse/parse_reg.c b/source3/rpc_parse/parse_reg.c index 8072ed2a64..ecec498528 100644 --- a/source3/rpc_parse/parse_reg.c +++ b/source3/rpc_parse/parse_reg.c @@ -1180,3 +1180,66 @@ void reg_io_r_open_entry(char *desc, REG_R_OPEN_ENTRY *r_r, prs_struct *ps, int prs_uint32("status", ps, depth, &(r_r->status)); } +/******************************************************************* +makes a structure. +********************************************************************/ +void make_reg_q_shutdown(REG_Q_SHUTDOWN *q_i, + char *msg, uint32 timeout, uint16 flags) +{ + int len = strlen(msg) + 1; + + if (q_i == NULL) return; + + ZERO_STRUCTP(q_i); + + q_i->ptr_0 = 1; + q_i->ptr_1 = 1; + q_i->ptr_2 = 1; + + make_uni_hdr(&q_i->hdr_msg, len, len, 1); + make_unistr2(&(q_i->uni_msg), msg, len); + + q_i->timeout = timeout; + q_i->flags = flags; +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ +void reg_io_q_shutdown(char *desc, REG_Q_SHUTDOWN *q_q, prs_struct *ps, int depth) +{ + if (q_q == NULL) return; + + prs_debug(ps, depth, desc, "reg_io_q_shutdown"); + depth++; + + prs_align(ps); + + prs_uint32("ptr_0", ps, depth, &(q_q->ptr_0)); + prs_uint32("ptr_1", ps, depth, &(q_q->ptr_1)); + prs_uint32("ptr_2", ps, depth, &(q_q->ptr_2)); + + smb_io_unihdr ("hdr_msg", &(q_q->hdr_msg), ps, depth); + smb_io_unistr2("uni_msg", &(q_q->uni_msg), q_q->hdr_msg.buffer, ps, depth); + prs_align(ps); + + prs_uint32("timeout", ps, depth, &(q_q->timeout)); + prs_uint16("flags ", ps, depth, &(q_q->flags )); + prs_align(ps); +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ +void reg_io_r_shutdown(char *desc, REG_R_SHUTDOWN *r_q, prs_struct *ps, int depth) +{ + if (r_q == NULL) return; + + prs_debug(ps, depth, desc, "reg_io_r_shutdown"); + depth++; + + prs_align(ps); + + prs_uint32("status", ps, depth, &(r_q->status)); +} + diff --git a/source3/rpcclient/cmd_reg.c b/source3/rpcclient/cmd_reg.c index f6a8a0a898..54e726847a 100644 --- a/source3/rpcclient/cmd_reg.c +++ b/source3/rpcclient/cmd_reg.c @@ -918,3 +918,48 @@ void cmd_reg_get_key_sec(struct client_info *info) } } +/**************************************************************************** +nt registry shutdown +****************************************************************************/ +void cmd_reg_shutdown(struct client_info *info) +{ + uint16 fnum; + BOOL res = True; + + fstring msg; + fstring tmp; + uint32 timeout = 20; + + DEBUG(5, ("cmd_reg_shutdown: smb_cli->fd:%d\n", smb_cli->fd)); + + if (!next_token(NULL, msg, NULL, sizeof(msg))) + { + msg[0] = 0; + } + else if (next_token(NULL, tmp, NULL, sizeof(tmp))) + { + timeout = atoi(tmp); + } + + + /* open WINREG session. */ + res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG, &fnum) : False; + + /* create an entry */ + res = res ? do_reg_shutdown(smb_cli, fnum, msg, timeout, 1) : False; + + /* close the session */ + cli_nt_session_close(smb_cli, fnum); + + if (res) + { + DEBUG(5,("cmd_reg_shutdown: query succeeded\n")); + fprintf(out_hnd,"OK\n"); + } + else + { + DEBUG(5,("cmd_reg_shutdown: query failed\n")); + fprintf(out_hnd,"Failed\n"); + } +} + diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index 79ab1b68a1..c0ff8526f1 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -109,6 +109,7 @@ struct {"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"}, + {"shutdown",cmd_reg_shutdown, "[message] [timeout] Server Shutdown"}, {"regquerykey",cmd_reg_query_key, " Registry Key Query"}, {"regdeleteval",cmd_reg_delete_val, " Registry Value Delete"}, {"regcreateval",cmd_reg_create_val, " Registry Key Create"}, -- cgit