From 1e1c2ec93c204e6fd3ebba6dfb11e4fbc136e10c Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 10 Nov 1998 19:05:00 +0000 Subject: rpcclient registry commands. (This used to be commit 36fcb4a6e643a05d06a2a273d74318fee7f2c647) --- source3/Makefile.in | 4 +- source3/include/includes.h | 4 + source3/include/ntdomain.h | 3 + source3/include/proto.h | 140 +++++++- source3/include/rpc_dce.h | 1 + source3/include/rpc_lsa.h | 19 +- source3/include/rpc_misc.h | 40 ++- source3/include/rpc_reg.h | 268 ++++++++++++++- source3/include/rpcclient.h | 9 +- source3/include/smb.h | 3 +- source3/lib/time.c | 79 ++--- source3/lib/util_str.c | 50 +++ source3/lib/util_unistr.c | 64 ++++ source3/lsarpcd/srv_lsa.c | 2 +- source3/rpc_client/cli_reg.c | 152 +++++++-- source3/rpc_parse/parse_lsa.c | 2 +- source3/rpc_parse/parse_misc.c | 171 ++++++++-- source3/rpc_parse/parse_prs.c | 58 +++- source3/rpc_parse/parse_reg.c | 732 ++++++++++++++++++++++++++++++++++++++++- source3/rpc_parse/parse_samr.c | 2 +- source3/rpc_server/srv_lsa.c | 2 +- source3/rpcclient/cmd_reg.c | 389 ++++++++++++++++++---- source3/rpcclient/display.c | 375 ++++++++++++++++++++- source3/rpcclient/rpcclient.c | 40 ++- 24 files changed, 2383 insertions(+), 226 deletions(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index beb577839e..fee28ac8f4 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -114,7 +114,7 @@ RPC_PARSE_OBJ = rpc_parse/parse_lsa.o rpc_parse/parse_misc.o \ rpc_parse/parse_net.o rpc_parse/parse_prs.o \ rpc_parse/parse_reg.o rpc_parse/parse_rpc.o \ rpc_parse/parse_samr.o rpc_parse/parse_srv.o \ - rpc_parse/parse_wks.o + rpc_parse/parse_wks.o rpc_parse/parse_sec.o RPC_CLIENT_OBJ = \ rpc_client/cli_login.o \ @@ -123,6 +123,7 @@ RPC_CLIENT_OBJ = \ rpc_client/cli_lsarpc.o \ rpc_client/cli_wkssvc.o \ rpc_client/cli_srvsvc.o \ + rpc_client/cli_reg.o \ rpc_client/cli_samr.o @@ -196,6 +197,7 @@ RPCCLIENT_OBJ = rpcclient/rpcclient.o \ rpcclient/cmd_lsarpc.o \ rpcclient/cmd_wkssvc.o \ rpcclient/cmd_samr.o \ + rpcclient/cmd_reg.o \ rpcclient/cmd_srvsvc.o \ rpcclient/cmd_netlogon.o \ $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \ diff --git a/source3/include/includes.h b/source3/include/includes.h index 56ab47cecc..6c7a67afef 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -99,9 +99,13 @@ #include #endif +#ifdef MEM_MAN +#include "../mem_man/mem_man.h" +#else #ifdef HAVE_MALLOC_H #include #endif +#endif #ifdef HAVE_FCNTL_H #include diff --git a/source3/include/ntdomain.h b/source3/include/ntdomain.h index 97122c8169..5b53834efe 100644 --- a/source3/include/ntdomain.h +++ b/source3/include/ntdomain.h @@ -31,6 +31,9 @@ /* miscellaneous structures / defines */ #include "rpc_misc.h" +/* security descriptor structures */ +#include "rpc_secdes.h" + /* different dce/rpc pipes */ #include "rpc_lsa.h" #include "rpc_netlogon.h" diff --git a/source3/include/proto.h b/source3/include/proto.h index ccbf919ebb..143f397e0a 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -178,8 +178,9 @@ void GetTimeOfDay(struct timeval *tval); void TimeInit(void); int TimeDiff(time_t t); struct tm *LocalTime(time_t *t); -time_t interpret_nt_time(NTTIME *t); +time_t nt_time_to_unix(NTTIME *nt); time_t interpret_long_date(char *p); +void unix_to_nt_time(NTTIME *nt, time_t t); void put_long_date(char *p,time_t t); BOOL null_mtime(time_t mtime); void put_dos_date(char *buf,int offset,time_t unixdate); @@ -351,6 +352,7 @@ char *safe_strcat(char *dest, char *src, int maxlength); char *StrCpy(char *dest,char *src); char *StrnCpy(char *dest,char *src,int n); char *strncpyn(char *dest, char *src,int n, char c); +int strhex_to_str(char *p, int len, const char *strhex); BOOL in_list(char *s,char *list,BOOL casesensitive); BOOL string_init(char **dest,char *src); void string_free(char **s); @@ -364,6 +366,9 @@ char *skip_unicode_string(char *buf,int n); char *unistrn2(uint16 *buf, int len); char *unistr2(uint16 *buf); char *unistr2_to_str(UNISTR2 *str); +uint32 buffer2_to_uint32(BUFFER2 *str); +char *buffer2_to_str(BUFFER2 *str); +char *buffer2_to_multistr(BUFFER2 *str); int struni2(uint16 *p, char *buf); char *unistr(char *buf); int unistrcpy(char *dst, char *src); @@ -1206,7 +1211,6 @@ struct passdb_ops *file_initialize_password_db(void); /*The following definitions come from passdb/smbpassfile.c */ -BOOL do_file_lock(int fd, int waitsecs, int type); BOOL pw_file_lock(int fd, int type, int secs, int *plock_depth); BOOL pw_file_unlock(int fd, int *plock_depth); BOOL trust_password_lock( char *domain, char *name, BOOL update); @@ -1288,6 +1292,42 @@ void cli_nt_set_ntlmssp_flgs(struct cli_state *cli, uint32 ntlmssp_flgs); BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name); void cli_nt_session_close(struct cli_state *cli); +/*The following definitions come from rpc_client/cli_reg.c */ + +BOOL do_reg_open_policy(struct cli_state *cli, uint16 unknown_0, uint32 level, + POLICY_HND *hnd); +BOOL do_reg_open_unk_4(struct cli_state *cli, uint16 unknown_0, uint32 level, + POLICY_HND *hnd); +BOOL do_reg_query_key(struct cli_state *cli, POLICY_HND *hnd, + char *class, uint32 *class_len, + uint32 *num_subkeys, uint32 *max_subkeylen, + uint32 *max_subkeysize, uint32 *num_values, + uint32 *max_valnamelen, uint32 *max_valbufsize, + uint32 *sec_desc, NTTIME *mod_time); +BOOL do_reg_unknown_1a(struct cli_state *cli, POLICY_HND *hnd, uint32 *unk); +BOOL do_reg_query_info(struct cli_state *cli, POLICY_HND *hnd, + char *type, uint32 *unk_0, uint32 *unk_1); +BOOL do_reg_get_key_sec(struct cli_state *cli, POLICY_HND *hnd, + uint32 *sec_buf_size, SEC_DESC_BUF *sec_buf); +BOOL do_reg_create_key(struct cli_state *cli, POLICY_HND *hnd, + char *key_name, char *key_class, + SEC_INFO *sam_access, + POLICY_HND *key); +BOOL do_reg_enum_key(struct cli_state *cli, POLICY_HND *hnd, + int key_index, char *key_name, + uint32 *unk_1, uint32 *unk_2, + time_t *mod_time); +BOOL do_reg_create_val(struct cli_state *cli, POLICY_HND *hnd, + char *val_name, uint32 type, BUFFER3 *data); +BOOL do_reg_enum_val(struct cli_state *cli, POLICY_HND *hnd, + int val_index, int max_valnamelen, int max_valbufsize, + fstring val_name, + uint32 *val_type, BUFFER2 *value); +BOOL do_reg_open_entry(struct cli_state *cli, POLICY_HND *hnd, + char *key_name, uint32 unk_0, + POLICY_HND *key_hnd); +BOOL do_reg_close(struct cli_state *cli, POLICY_HND *hnd); + /*The following definitions come from rpc_client/cli_samr.c */ BOOL get_samr_query_usergroups(struct cli_state *cli, @@ -1414,21 +1454,28 @@ void make_str_hdr(STRHDR *hdr, int max_len, int len, uint32 buffer); void smb_io_strhdr(char *desc, STRHDR *hdr, prs_struct *ps, int depth); void make_uni_hdr(UNIHDR *hdr, int max_len, int len, uint32 buffer); void smb_io_unihdr(char *desc, UNIHDR *hdr, prs_struct *ps, int depth); +void make_buf_hdr(BUFHDR *hdr, int max_len, int len); +void smb_io_hdrbuf(char *desc, BUFHDR *hdr, prs_struct *ps, int depth); void make_uni_hdr2(UNIHDR2 *hdr, int max_len, int len, uint16 terminate); void smb_io_unihdr2(char *desc, UNIHDR2 *hdr2, prs_struct *ps, int depth); void make_unistr(UNISTR *str, char *buf); void smb_io_unistr(char *desc, UNISTR *uni, prs_struct *ps, int depth); -void make_uninotstr2(UNINOTSTR2 *str, char *buf, int len); -void smb_io_uninotstr2(char *desc, UNINOTSTR2 *uni2, uint32 buffer, prs_struct *ps, int depth); +void make_buffer3_uint32(BUFFER3 *str, uint32 val); +void make_buffer3_str(BUFFER3 *str, char *buf, int len); +void make_buffer3_hex(BUFFER3 *str, char *buf); +void make_buffer3_bytes(BUFFER3 *str, uint8 *buf, int len); +void smb_io_buffer3(char *desc, BUFFER3 *buf3, prs_struct *ps, int depth); +void make_buffer2(BUFFER2 *str, uint8 *buf, int len); +void smb_io_buffer2(char *desc, BUFFER2 *buf2, uint32 buffer, prs_struct *ps, int depth); void make_buf_unistr2(UNISTR2 *str, uint32 *ptr, char *buf); void copy_unistr2(UNISTR2 *str, UNISTR2 *from); void make_string2(STRING2 *str, char *buf, int len); void smb_io_string2(char *desc, STRING2 *str2, uint32 buffer, prs_struct *ps, int depth); void make_unistr2(UNISTR2 *str, char *buf, int len); void smb_io_unistr2(char *desc, UNISTR2 *uni2, uint32 buffer, prs_struct *ps, int depth); -void make_dom_rid2(DOM_RID2 *rid2, uint32 rid); +void make_dom_rid2(DOM_RID2 *rid2, uint32 rid, uint8 type); void smb_io_dom_rid2(char *desc, DOM_RID2 *rid2, prs_struct *ps, int depth); -void make_dom_rid3(DOM_RID3 *rid3, uint32 rid); +void make_dom_rid3(DOM_RID3 *rid3, uint32 rid, uint8 type); void smb_io_dom_rid3(char *desc, DOM_RID3 *rid3, prs_struct *ps, int depth); void make_dom_rid4(DOM_RID4 *rid4, uint16 unknown, uint16 attr, uint32 rid); void make_log_info(DOM_LOG_INFO *log, char *logon_srv, char *acct_name, @@ -1453,7 +1500,7 @@ void smb_io_gid(char *desc, DOM_GID *gid, prs_struct *ps, int depth); void smb_io_pol_hnd(char *desc, POLICY_HND *pol, prs_struct *ps, int depth); void smb_io_dom_query_3(char *desc, DOM_QUERY_3 *d_q, prs_struct *ps, int depth); void smb_io_dom_query_5(char *desc, DOM_QUERY_3 *d_q, prs_struct *ps, int depth); -void smb_io_dom_name(char *desc, DOM_NAME *name, prs_struct *ps, int depth); +void smb_io_unistr3(char *desc, UNISTR3 *name, prs_struct *ps, int depth); /*The following definitions come from rpc_parse/parse_net.c */ @@ -1547,24 +1594,71 @@ BOOL prs_uint16(char *name, prs_struct *ps, int depth, uint16 *data16); BOOL prs_uint32(char *name, prs_struct *ps, int depth, uint32 *data32); BOOL prs_uint8s(BOOL charmode, char *name, prs_struct *ps, int depth, uint8 *data8s, int len); BOOL prs_uint32s(BOOL charmode, char *name, prs_struct *ps, int depth, uint32 *data32s, int len); -BOOL prs_uninotstr2(BOOL charmode, char *name, prs_struct *ps, int depth, UNINOTSTR2 *str); +BOOL prs_buffer2(BOOL charmode, char *name, prs_struct *ps, int depth, BUFFER2 *str); BOOL prs_string2(BOOL charmode, char *name, prs_struct *ps, int depth, STRING2 *str); BOOL prs_unistr2(BOOL charmode, char *name, prs_struct *ps, int depth, UNISTR2 *str); +BOOL prs_unistr3(BOOL charmode, char *name, UNISTR3 *str, prs_struct *ps, int depth); BOOL prs_unistr(char *name, prs_struct *ps, int depth, UNISTR *str); BOOL prs_string(char *name, prs_struct *ps, int depth, char *str, uint16 len, uint16 max_buf_size); +BOOL prs_uint16_pre(char *name, prs_struct *ps, int depth, uint16 *data16, uint32 *off_ptr); +BOOL prs_uint16_post(char *name, prs_struct *ps, int depth, + uint32 ptr_uint16, uint32 start_offset); /*The following definitions come from rpc_parse/parse_reg.c */ +void make_reg_q_open_pol(REG_Q_OPEN_POLICY *q_o, + uint16 unknown_0, uint32 level); void reg_io_q_open_policy(char *desc, REG_Q_OPEN_POLICY *r_q, prs_struct *ps, int depth); void reg_io_r_open_policy(char *desc, REG_R_OPEN_POLICY *r_r, prs_struct *ps, int depth); +void make_reg_q_create_key(REG_Q_CREATE_KEY *q_c, POLICY_HND *hnd, + char *name, char *class, + SEC_INFO *sam_access); +void reg_io_q_create_key(char *desc, REG_Q_CREATE_KEY *r_q, prs_struct *ps, int depth); +void reg_io_r_create_key(char *desc, REG_R_CREATE_KEY *r_r, prs_struct *ps, int depth); +void make_reg_q_query_key(REG_Q_QUERY_KEY *q_o, POLICY_HND *hnd, + uint32 max_class_len); +void reg_io_q_query_key(char *desc, REG_Q_QUERY_KEY *r_q, prs_struct *ps, int depth); +void reg_io_r_query_key(char *desc, REG_R_QUERY_KEY *r_r, prs_struct *ps, int depth); +void make_reg_q_unk_1a(REG_Q_UNK_1A *q_o, POLICY_HND *hnd); +void reg_io_q_unk_1a(char *desc, REG_Q_UNK_1A *r_q, prs_struct *ps, int depth); +void reg_io_r_unk_1a(char *desc, REG_R_UNK_1A *r_r, prs_struct *ps, int depth); +void make_reg_q_open_unk_4(REG_Q_OPEN_UNK_4 *q_o, + uint16 unknown_0, uint32 level); +void reg_io_q_open_unk_4(char *desc, REG_Q_OPEN_UNK_4 *r_q, prs_struct *ps, int depth); +void reg_io_r_open_unk_4(char *desc, REG_R_OPEN_UNK_4 *r_r, prs_struct *ps, int depth); +void make_reg_q_close(REG_Q_CLOSE *q_c, POLICY_HND *hnd); void reg_io_q_close(char *desc, REG_Q_CLOSE *q_u, prs_struct *ps, int depth); void reg_io_r_close(char *desc, REG_R_CLOSE *r_u, prs_struct *ps, int depth); +void make_reg_q_get_key_sec(REG_Q_GET_KEY_SEC *q_i, POLICY_HND *pol, + uint32 buf_len, SEC_DESC_BUF *sec_buf); +void reg_io_q_get_key_sec(char *desc, REG_Q_GET_KEY_SEC *r_q, prs_struct *ps, int depth); +void make_reg_r_get_key_sec(REG_R_GET_KEY_SEC *r_i, POLICY_HND *pol, + uint32 buf_len, uint8 *buf, + uint32 status); +void reg_io_r_get_key_sec(char *desc, REG_R_GET_KEY_SEC *r_q, prs_struct *ps, int depth); +void make_reg_q_info(REG_Q_INFO *q_i, POLICY_HND *pol, char *product_type, + time_t unix_time, uint8 major, uint8 minor); void reg_io_q_info(char *desc, REG_Q_INFO *r_q, prs_struct *ps, int depth); void make_reg_r_info(REG_R_INFO *r_r, uint32 level, char *os_type, uint32 unknown_0, uint32 unknown_1, uint32 status); -void reg_io_r_info(char *desc, REG_R_INFO *r_r, prs_struct *ps, int depth); +void reg_io_r_info(char *desc, REG_R_INFO *r_r, prs_struct *ps, int depth); +void make_reg_q_enum_val(REG_Q_ENUM_VALUE *q_i, POLICY_HND *pol, + uint32 val_idx, uint32 max_val_len, + uint32 max_buf_len); +void reg_io_q_enum_val(char *desc, REG_Q_ENUM_VALUE *q_q, prs_struct *ps, int depth); +void reg_io_r_enum_val(char *desc, REG_R_ENUM_VALUE *r_q, prs_struct *ps, int depth); +void make_reg_q_create_val(REG_Q_CREATE_VALUE *q_i, POLICY_HND *pol, + char *val_name, uint32 type, + BUFFER3 *val); +void reg_io_q_create_val(char *desc, REG_Q_CREATE_VALUE *q_q, prs_struct *ps, int depth); +void reg_io_r_create_val(char *desc, REG_R_CREATE_VALUE *r_q, prs_struct *ps, int depth); +void make_reg_q_enum_key(REG_Q_ENUM_KEY *q_i, POLICY_HND *pol, uint32 key_idx); +void reg_io_q_enum_key(char *desc, REG_Q_ENUM_KEY *q_q, prs_struct *ps, int depth); +void reg_io_r_enum_key(char *desc, REG_R_ENUM_KEY *r_q, prs_struct *ps, int depth); +void make_reg_q_open_entry(REG_Q_OPEN_ENTRY *r_q, POLICY_HND *pol, + char *key_name, uint32 unk); void reg_io_q_open_entry(char *desc, REG_Q_OPEN_ENTRY *r_q, prs_struct *ps, int depth); void make_reg_r_open_entry(REG_R_OPEN_ENTRY *r_r, POLICY_HND *pol, uint32 status); @@ -1803,6 +1897,15 @@ void samr_io_q_chgpasswd_user(char *desc, SAMR_Q_CHGPASSWD_USER *q_u, prs_struct void make_samr_r_chgpasswd_user(SAMR_R_CHGPASSWD_USER *r_u, uint32 status); void samr_io_r_chgpasswd_user(char *desc, SAMR_R_CHGPASSWD_USER *r_u, prs_struct *ps, int depth); +/*The following definitions come from rpc_parse/parse_sec.c */ + +void sec_io_info(char *desc, SEC_INFO *t, prs_struct *ps, int depth); +void sec_io_ace(char *desc, SEC_ACE *t, prs_struct *ps, int depth); +void sec_io_acl(char *desc, SEC_ACL *t, prs_struct *ps, int depth); +void sec_io_desc(char *desc, SEC_DESC *t, prs_struct *ps, int depth); +void make_sec_desc_buf(SEC_DESC_BUF *buf, int len, uint32 buf_ptr); +void sec_io_desc_buf(char *desc, SEC_DESC_BUF *sec, prs_struct *ps, int depth); + /*The following definitions come from rpc_parse/parse_srv.c */ void make_srv_share_info1_str(SH_INFO_1_STR *sh1, char *net_name, char *remark); @@ -1970,6 +2073,15 @@ void cmd_lsa_lookup_sids(struct client_info *info); void cmd_netlogon_login_test(struct client_info *info); +/*The following definitions come from rpcclient/cmd_reg.c */ + +void cmd_reg_enum(struct client_info *info); +void cmd_reg_query_key(struct client_info *info); +void cmd_reg_test2(struct client_info *info); +void cmd_reg_create_val(struct client_info *info); +void cmd_reg_create_key(struct client_info *info); +void cmd_reg_get_key_sec(struct client_info *info); + /*The following definitions come from rpcclient/cmd_samr.c */ void cmd_sam_ntchange_pwd(struct client_info *info); @@ -2042,6 +2154,16 @@ void display_group_rid_info(FILE *out_hnd, enum action_type action, void display_alias_name_info(FILE *out_hnd, enum action_type action, uint32 num_aliases, fstring *alias_name, uint32 *num_als_usrs); void display_sam_user_info_21(FILE *out_hnd, enum action_type action, SAM_USER_INFO_21 *usr); +char *get_sec_perms_str(uint32 type); +void display_sec_info(FILE *out_hnd, enum action_type action, SEC_INFO *info); +void display_sec_ace(FILE *out_hnd, enum action_type action, SEC_ACE *ace); +void display_sec_acl(FILE *out_hnd, enum action_type action, SEC_ACL *acl); +void display_sec_desc(FILE *out_hnd, enum action_type action, SEC_DESC *sec); +char *get_reg_val_type_str(uint32 type); +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); /*The following definitions come from rpcclient/rpcclient.c */ diff --git a/source3/include/rpc_dce.h b/source3/include/rpc_dce.h index c6499853d6..70eb1b4e20 100644 --- a/source3/include/rpc_dce.h +++ b/source3/include/rpc_dce.h @@ -33,6 +33,7 @@ enum RPC_PKT_TYPE { RPC_REQUEST = 0x00, RPC_RESPONSE = 0x02, + RPC_FAULT = 0x03, RPC_BIND = 0x0B, RPC_BINDACK = 0x0C, RPC_BINDRESP = 0x10 /* not the real name! this is undocumented! */ diff --git a/source3/include/rpc_lsa.h b/source3/include/rpc_lsa.h index 44758936ae..b8aaa562f0 100644 --- a/source3/include/rpc_lsa.h +++ b/source3/include/rpc_lsa.h @@ -28,9 +28,14 @@ enum SID_NAME_USE { - SID_NAME_USER = 1, + SID_NAME_USER = 1, /* user */ SID_NAME_DOM_GRP = 2, /* domain group */ - SID_NAME_WKN_GRP = 5 /* well-known group */ + SID_NAME_DOMAIN = 3, /* domain: don't know what this is */ + SID_NAME_ALIAS = 4, /* local group */ + SID_NAME_WKN_GRP = 5, /* well-known group */ + SID_NAME_DELETED = 6, /* deleted account: needed for c2 rating */ + SID_NAME_INVALID = 7, /* invalid account */ + SID_NAME_UNKNOWN = 8 /* oops. */ }; /* ntlsa pipe */ @@ -284,14 +289,6 @@ typedef struct lsa_r_lookup_sids } LSA_R_LOOKUP_SIDS; -/* DOM_NAME - XXXX not sure about this structure */ -typedef struct dom_name_info -{ - uint32 uni_str_len; - UNISTR str; - -} DOM_NAME; - #define UNKNOWN_LEN 1 @@ -303,7 +300,7 @@ typedef struct lsa_q_lookup_rids uint32 num_entries2; uint32 buffer_dom_sid; /* undocumented domain SID buffer pointer */ uint32 buffer_dom_name; /* undocumented domain name buffer pointer */ - DOM_NAME lookup_name[MAX_LOOKUP_SIDS]; /* names to be looked up */ + UNISTR3 lookup_name[MAX_LOOKUP_SIDS]; /* names to be looked up */ uint8 undoc[UNKNOWN_LEN]; /* completely undocumented bytes of unknown length */ } LSA_Q_LOOKUP_RIDS; diff --git a/source3/include/rpc_misc.h b/source3/include/rpc_misc.h index 50daf27dfc..e984a4842b 100644 --- a/source3/include/rpc_misc.h +++ b/source3/include/rpc_misc.h @@ -91,8 +91,8 @@ typedef struct sid_info_2 /* STRHDR - string header */ typedef struct header_info { - uint16 str_max_len; uint16 str_str_len; + uint16 str_max_len; uint32 buffer; /* non-zero */ } STRHDR; @@ -100,8 +100,8 @@ typedef struct header_info /* UNIHDR - unicode string header */ typedef struct unihdr_info { - uint16 uni_max_len; uint16 uni_str_len; + uint16 uni_max_len; uint32 buffer; /* usually has a value of 4 */ } UNIHDR; @@ -117,6 +117,7 @@ typedef struct unihdr2_info /* clueless as to what maximum length should be */ #define MAX_UNISTRLEN 256 #define MAX_STRINGLEN 256 +#define MAX_BUFFERLEN 512 /* UNISTR - unicode string size and buffer */ typedef struct unistr_info @@ -125,17 +126,34 @@ typedef struct unistr_info } UNISTR; -/* UNINOTSTR2 - unicode string, size (in uint8 ascii chars) and buffer */ +/* BUFHDR - buffer header */ +typedef struct bufhdr_info +{ + uint32 buf_max_len; + uint32 buf_len; + +} BUFHDR; + +/* BUFFER2 - unicode string, size (in uint8 ascii chars) and buffer */ /* pathetic. some stupid team of \PIPE\winreg writers got the concept */ /* of a unicode string different from the other \PIPE\ writers */ -typedef struct uninotstr2_info +typedef struct buffer2_info { - uint32 uni_max_len; + uint32 buf_max_len; uint32 undoc; - uint32 uni_buf_len; + uint32 buf_len; uint16 buffer[MAX_UNISTRLEN]; /* unicode characters. **NOT** necessarily null-terminated */ -} UNINOTSTR2; +} BUFFER2; + +/* BUFFER3 */ +typedef struct buffer3_info +{ + uint32 buf_max_len; + uint8 buffer[MAX_BUFFERLEN]; /* data */ + uint32 buf_len; + +} BUFFER3; /* UNISTR2 - unicode string size (in uint16 unicode chars) and buffer */ typedef struct unistr2_info @@ -157,6 +175,14 @@ typedef struct string2_info } STRING2; +/* UNISTR3 - XXXX not sure about this structure */ +typedef struct unistr3_info +{ + uint32 uni_str_len; + UNISTR str; + +} UNISTR3; + /* DOM_RID2 - domain RID structure for ntlsa pipe */ typedef struct domrid2_info diff --git a/source3/include/rpc_reg.h b/source3/include/rpc_reg.h index 28d11710cd..9334810866 100644 --- a/source3/include/rpc_reg.h +++ b/source3/include/rpc_reg.h @@ -27,29 +27,231 @@ /* winreg pipe defines */ #define REG_OPEN_POLICY 0x02 +#define REG_OPEN_UNK_4 0x04 +#define REG_UNK_1A 0x1a +#define REG_QUERY_KEY 0x10 +#define REG_ENUM_KEY 0x09 +#define REG_CREATE_KEY 0x06 +#define REG_CREATE_VALUE 0x16 +#define REG_GET_KEY_SEC 0x0c +#define REG_ENUM_VALUE 0x0a #define REG_OPEN_ENTRY 0x0f #define REG_INFO 0x11 #define REG_CLOSE 0x05 + /* REG_Q_OPEN_POLICY */ typedef struct q_reg_open_policy_info { uint32 ptr; - uint16 unknown_0; /* 0x5da0 - 16 bit unknown */ - uint32 level; /* 0x0000 0001 - 32 bit unknown */ - uint16 unknown_1; /* 0x0200 - 16 bit unknown */ + uint16 unknown_0; /* 0xE084 - 16 bit unknown */ + uint16 unknown_1; /* random. changes */ + uint32 level; /* 0x0000 0002 - 32 bit unknown */ } REG_Q_OPEN_POLICY; /* REG_R_OPEN_POLICY */ typedef struct r_reg_open_policy_info { - POLICY_HND pol; /* policy handle */ + POLICY_HND pol; /* policy handle */ uint32 status; /* return status */ } REG_R_OPEN_POLICY; +/* REG_Q_OPEN_UNK_4 */ +typedef struct q_reg_open_unk4_info +{ + uint32 ptr; + uint16 unknown_0; /* 0xE084 - 16 bit unknown */ + uint16 unknown_1; /* random. changes */ + uint32 level; /* 0x0000 0002 - 32 bit unknown */ + +} REG_Q_OPEN_UNK_4; + +/* REG_R_OPEN_UNK_4 */ +typedef struct r_reg_open_unk4_info +{ + POLICY_HND pol; /* policy handle */ + uint32 status; /* return status */ + +} REG_R_OPEN_UNK_4; + + +/* REG_Q_GET_KEY_SEC */ +typedef struct q_reg_get_key_sec_info +{ + POLICY_HND pol; /* policy handle */ + + uint32 unknown; /* 0x0000 0007 */ + + uint32 ptr; /* pointer */ + BUFHDR hdr_sec; /* header for security data */ + SEC_DESC_BUF *data; /* security data */ + +} REG_Q_GET_KEY_SEC; + +/* REG_R_GET_KEY_SEC */ +typedef struct r_reg_get_key_sec_info +{ + uint32 unknown; /* 0x0000 0007 */ + + uint32 ptr; /* pointer */ + BUFHDR hdr_sec; /* header for security data */ + SEC_DESC_BUF *data; /* security data */ + + uint32 status; + +} REG_R_GET_KEY_SEC; + +/* REG_Q_CREATE_VALUE */ +typedef struct q_reg_create_value_info +{ + POLICY_HND pol; /* policy handle */ + + UNIHDR hdr_name; /* name of value */ + UNISTR2 uni_name; + + uint32 type; /* 1 = UNISTR, 3 = BYTES, 4 = DWORD, 7 = MULTI_UNISTR */ + + BUFFER3 *buf_value; /* value, in byte buffer */ + +} REG_Q_CREATE_VALUE; + +/* REG_R_CREATE_VALUE */ +typedef struct r_reg_create_value_info +{ + uint32 status; /* return status */ + +} REG_R_CREATE_VALUE; + +/* REG_Q_ENUM_VALUE */ +typedef struct q_reg_query_value_info +{ + POLICY_HND pol; /* policy handle */ + + uint32 val_index; /* index */ + + UNIHDR hdr_name; /* name of value */ + UNISTR2 uni_name; + + uint32 ptr_type; /* pointer */ + uint32 type; /* 1 = UNISTR, 3 = BYTES, 4 = DWORD, 7 = MULTI_UNISTR */ + + uint32 ptr_value; /* pointer */ + BUFFER2 buf_value; /* value, in byte buffer */ + + uint32 ptr1; /* pointer */ + uint32 len_value1; /* */ + + uint32 ptr2; /* pointer */ + uint32 len_value2; /* */ + +} REG_Q_ENUM_VALUE; + +/* REG_R_ENUM_VALUE */ +typedef struct r_reg_enum_value_info +{ + UNIHDR hdr_name; /* name of value */ + UNISTR2 uni_name; + + uint32 ptr_type; /* pointer */ + uint32 type; /* 1 = UNISTR, 3 = BYTES, 4 = DWORD, 7 = MULTI_UNISTR */ + + uint32 ptr_value; /* pointer */ + BUFFER2 *buf_value; /* value, in byte buffer */ + + uint32 ptr1; /* pointer */ + uint32 len_value1; /* */ + + uint32 ptr2; /* pointer */ + uint32 len_value2; /* */ + + uint32 status; /* return status */ + +} REG_R_ENUM_VALUE; + +/* REG_Q_CREATE_KEY */ +typedef struct q_reg_create_key_info +{ + POLICY_HND pnt_pol; /* parent key policy handle */ + + UNIHDR hdr_name; + UNISTR2 uni_name; + + UNIHDR hdr_class; + UNISTR2 uni_class; + + uint32 reserved; /* 0x0000 0000 */ + SEC_INFO sam_access; /* access rights flags, see rpc_secdes.h */ + + uint32 ptr1; + uint32 unknown_0; /* 0x0000 000C */ + + uint32 ptr2; + uint32 unk_len1; /* 0x0000 0014 */ + uint32 unk_len2; /* 0x0000 0014 */ + uint32 unknown_1; /* 0x0002 0000 */ + BUFFER2 buf_unk; /* 01 00 00 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 */ + + uint32 unknown_2; /* 0x0000 0000 */ +} REG_Q_CREATE_KEY; + +/* REG_R_CREATE_KEY */ +typedef struct r_reg_create_key_info +{ + POLICY_HND key_pol; /* policy handle */ + uint32 unknown; /* 0x0000 0000 */ + + uint32 status; /* return status */ + +} REG_R_CREATE_KEY; + +/* REG_Q_QUERY_KEY */ +typedef struct q_reg_query_info +{ + POLICY_HND pol; /* policy handle */ + UNIHDR hdr_class; + UNISTR2 uni_class; + +} REG_Q_QUERY_KEY; + +/* REG_R_QUERY_KEY */ +typedef struct r_reg_query_key_info +{ + UNIHDR hdr_class; + UNISTR2 uni_class; + + uint32 num_subkeys; + uint32 max_subkeylen; + uint32 max_subkeysize; /* 0x0000 0000 */ + uint32 num_values; + uint32 max_valnamelen; + uint32 max_valbufsize; + uint32 sec_desc; /* 0x0000 0078 */ + NTTIME mod_time; /* modified time */ + + uint32 status; /* return status */ + +} REG_R_QUERY_KEY; + + +/* REG_Q_UNK_1A */ +typedef struct q_reg_unk_1a_info +{ + POLICY_HND pol; /* policy handle */ + +} REG_Q_UNK_1A; + +/* REG_R_UNK_1A */ +typedef struct r_reg_unk_1a_info +{ + uint32 unknown; /* 0x0500 0000 */ + uint32 status; /* return status */ + +} REG_R_UNK_1A; + + /* REG_Q_CLOSE */ typedef struct reg_q_close_info { @@ -67,10 +269,55 @@ typedef struct reg_r_close_info } REG_R_CLOSE; +/* REG_Q_ENUM_KEY */ +typedef struct q_reg_enum_value_info +{ + POLICY_HND pol; /* policy handle */ + + uint32 key_index; + + uint16 key_name_len; /* 0x0000 */ + uint16 unknown_1; /* 0x0414 */ + + uint32 ptr1; /* pointer */ + uint32 unknown_2; /* 0x0000 020A */ + uint8 pad1[8]; /* padding - zeros */ + + uint32 ptr2; /* pointer */ + uint8 pad2[8]; /* padding - zeros */ + + uint32 ptr3; /* pointer */ + NTTIME time; /* current time? */ + +} REG_Q_ENUM_KEY; + +/* REG_R_ENUM_KEY */ +typedef struct r_reg_enum_key_info +{ + uint16 key_name_len; /* number of bytes in key name */ + uint16 unknown_1; /* 0x0414 - matches with query unknown_1 */ + + uint32 ptr1; /* pointer */ + uint32 unknown_2; /* 0x0000 020A */ + uint32 unknown_3; /* 0x0000 0000 */ + + UNISTR3 key_name; + + uint32 ptr2; /* pointer */ + uint8 pad2[8]; /* padding - zeros */ + + uint32 ptr3; /* pointer */ + NTTIME time; /* current time? */ + + uint32 status; /* return status */ + +} REG_R_ENUM_KEY; + + /* REG_Q_INFO */ typedef struct q_reg_info_info { - POLICY_HND pol; /* policy handle */ + POLICY_HND pol; /* policy handle */ UNIHDR hdr_type; /* unicode product type header */ UNISTR2 uni_type; /* unicode product type - "ProductType" */ @@ -97,8 +344,8 @@ typedef struct r_reg_info_info uint32 ptr1; /* buffer pointer */ uint32 level; /* 0x1 - info level? */ - uint32 ptr_type; /* pointer to o/s type */ - UNINOTSTR2 uni_type; /* unicode string o/s type - "LanmanNT" */ + uint32 ptr_type; /* pointer to o/s type */ + BUFFER2 uni_type; /* unicode string o/s type - "LanmanNT" */ uint32 ptr2; /* pointer to unknown_0 */ uint32 unknown_0; /* 0x12 */ @@ -114,14 +361,13 @@ typedef struct r_reg_info_info /* REG_Q_OPEN_ENTRY */ typedef struct q_reg_open_entry_info { - POLICY_HND pol; /* policy handle */ + POLICY_HND pol; /* policy handle */ UNIHDR hdr_name; /* unicode registry string header */ UNISTR2 uni_name; /* unicode registry string name */ uint32 unknown_0; /* 32 bit unknown - 0x0000 0000 */ - uint16 unknown_1; /* 16 bit unknown - 0x0000 */ - uint16 unknown_2; /* 16 bit unknown - 0x0200 */ + uint32 unknown_1; /* 32 bit unknown - 0x0200 0000 */ } REG_Q_OPEN_ENTRY; @@ -130,7 +376,7 @@ typedef struct q_reg_open_entry_info /* REG_R_OPEN_ENTRY */ typedef struct r_reg_open_entry_info { - POLICY_HND pol; /* policy handle */ + POLICY_HND pol; /* policy handle */ uint32 status; /* return status */ } REG_R_OPEN_ENTRY; diff --git a/source3/include/rpcclient.h b/source3/include/rpcclient.h index 1065b7c159..eab4d20703 100644 --- a/source3/include/rpcclient.h +++ b/source3/include/rpcclient.h @@ -57,17 +57,22 @@ struct nt_client_info NET_ID_INFO_CTR ctr; NET_USER_INFO_3 user_info3; + /************** \PIPE\winreg stuff ********************/ + + POLICY_HND reg_pol_connect; + POLICY_HND reg_pol_unk_4; + /************** \PIPE\lsarpc stuff ********************/ POLICY_HND lsa_info_pol; /* domain member */ - fstring level3_dom; fstring level3_sid; + fstring level5_sid; /* domain controller */ + fstring level3_dom; fstring level5_dom; - fstring level5_sid; /************** \PIPE\samr stuff ********************/ diff --git a/source3/include/smb.h b/source3/include/smb.h index a6566fb364..a8b0c745b2 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -337,10 +337,11 @@ implemented */ typedef char pstring[1024]; typedef char fstring[128]; -/* pipe strings */ +/* pipe string names */ #define PIPE_LANMAN "\\PIPE\\LANMAN" #define PIPE_SRVSVC "\\PIPE\\srvsvc" #define PIPE_SAMR "\\PIPE\\samr" +#define PIPE_WINREG "\\PIPE\\winreg" #define PIPE_WKSSVC "\\PIPE\\wkssvc" #define PIPE_NETLOGON "\\PIPE\\NETLOGON" #define PIPE_NTLSA "\\PIPE\\ntlsa" diff --git a/source3/lib/time.c b/source3/lib/time.c index ea96654108..3cea1a3e14 100644 --- a/source3/lib/time.c +++ b/source3/lib/time.c @@ -236,18 +236,6 @@ struct tm *LocalTime(time_t *t) return(gmtime(&t2)); } -/**************************************************************************** -take an NTTIME structure, containing high / low time. convert to unix time. -lkclXXXX this may need 2 SIVALs not a memcpy. we'll see... -****************************************************************************/ -time_t interpret_nt_time(NTTIME *t) -{ - char data[8]; - memcpy(data, t, sizeof(data)); - return interpret_long_date(data); -} - - #define TIME_FIXUP_CONSTANT (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60)) /**************************************************************************** @@ -259,22 +247,19 @@ its the GMT you get by taking a localtime and adding the serverzone. This is NOT the same as GMT in some cases. This routine converts this to real GMT. ****************************************************************************/ -time_t interpret_long_date(char *p) +time_t nt_time_to_unix(NTTIME *nt) { double d; time_t ret; - uint32 tlow,thigh; /* The next two lines are a fix needed for the broken SCO compiler. JRA. */ time_t l_time_min = TIME_T_MIN; time_t l_time_max = TIME_T_MAX; - tlow = IVAL(p,0); - thigh = IVAL(p,4); - if (thigh == 0) return(0); + if (nt->high == 0) return(0); - d = ((double)thigh)*4.0*(double)(1<<30); - d += (tlow&0xFFF00000); + d = ((double)nt->high)*4.0*(double)(1<<30); + d += (nt->low&0xFFF00000); d *= 1.0e-7; /* now adjust by 369 years to make the secs since 1970 */ @@ -293,37 +278,57 @@ time_t interpret_long_date(char *p) } + +/**************************************************************************** +interprets an nt time into a unix time_t +****************************************************************************/ +time_t interpret_long_date(char *p) +{ + NTTIME nt; + nt.low = IVAL(p,0); + nt.high = IVAL(p,4); + return nt_time_to_unix(&nt); +} + /**************************************************************************** put a 8 byte filetime from a time_t This takes real GMT as input and converts to kludge-GMT ****************************************************************************/ -void put_long_date(char *p,time_t t) +void unix_to_nt_time(NTTIME *nt, time_t t) { - uint32 tlow,thigh; - double d; + double d; - if (t==0) { - SIVAL(p,0,0); SIVAL(p,4,0); - return; - } - - /* this converts GMT to kludge-GMT */ - t -= LocTimeDiff(t) - serverzone; + if (t==0) + { + nt->low = 0; + nt->high = 0; + return; + } - d = (double) (t); + /* this converts GMT to kludge-GMT */ + t -= LocTimeDiff(t) - serverzone; - d += TIME_FIXUP_CONSTANT; + d = (double)(t); + d += TIME_FIXUP_CONSTANT; + d *= 1.0e7; - d *= 1.0e7; + nt->high = (uint32)(d * (1.0/(4.0*(double)(1<<30)))); + nt->low = (uint32)(d - ((double)nt->high)*4.0*(double)(1<<30)); +} - thigh = (uint32)(d * (1.0/(4.0*(double)(1<<30)))); - tlow = (uint32)(d - ((double)thigh)*4.0*(double)(1<<30)); - SIVAL(p,0,tlow); - SIVAL(p,4,thigh); +/**************************************************************************** +take an NTTIME structure, containing high / low time. convert to unix time. +lkclXXXX this may need 2 SIVALs not a memcpy. we'll see... +****************************************************************************/ +void put_long_date(char *p,time_t t) +{ + NTTIME nt; + unix_to_nt_time(&nt, t); + SIVAL(p, 0, nt.low); + SIVAL(p, 4, nt.high); } - /**************************************************************************** check if it's a null mtime ****************************************************************************/ diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index 7eb1494382..15eefb0001 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -857,6 +857,56 @@ char *strncpyn(char *dest, char *src,int n, char c) } +/************************************************************* + Routine to get hex characters and turn them into a 16 byte array. + the array can be variable length, and any non-hex-numeric + characters are skipped. "0xnn" or "0Xnn" is specially catered + for. + + valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n" + +**************************************************************/ +int strhex_to_str(char *p, int len, const char *strhex) +{ + int i; + int num_chars = 0; + unsigned char lonybble, hinybble; + char *hexchars = "0123456789ABCDEF"; + char *p1 = NULL, *p2 = NULL; + + for (i = 0; i < len && strhex[i] != 0; i++) + { + if (strnequal(hexchars, "0x", 2)) + { + i++; /* skip two chars */ + continue; + } + + while (!(p1 = strchr(hexchars, toupper(strhex[i])))) + { + continue; + } + + i++; /* next hex digit */ + + while (!(p2 = strchr(hexchars, toupper(strhex[i])))) + { + continue; + } + + /* get the two nybbles */ + hinybble = PTR_DIFF(p1, hexchars); + lonybble = PTR_DIFF(p2, hexchars); + + p[num_chars] = (hinybble << 4) | lonybble; + num_chars++; + + p1 = NULL; + p2 = NULL; + } + return num_chars; +} + /**************************************************************************** check if a string is part of a list ****************************************************************************/ diff --git a/source3/lib/util_unistr.c b/source3/lib/util_unistr.c index 2365090f24..49fb729267 100644 --- a/source3/lib/util_unistr.c +++ b/source3/lib/util_unistr.c @@ -118,6 +118,70 @@ char *unistr2_to_str(UNISTR2 *str) return lbuf; } +/******************************************************************* +Return a number stored in a buffer +********************************************************************/ +uint32 buffer2_to_uint32(BUFFER2 *str) +{ + if (str->buf_len == 4) + { + return IVAL(str->buffer, 0); + } + else + { + return 0; + } +} + +/******************************************************************* +Return a ascii version of a NOTunicode string +********************************************************************/ +char *buffer2_to_str(BUFFER2 *str) +{ + char *lbuf = lbufs[nexti]; + char *p; + uint16 *buf = str->buffer; + int max_size = MIN(sizeof(str->buffer)-2, str->buf_len/2); + + nexti = (nexti+1)%8; + + for (p = lbuf; *buf && p-lbuf < max_size; p++, buf++) + { + *p = *buf; + } + + *p = 0; + return lbuf; +} + +/******************************************************************* +Return a ascii version of a NOTunicode string +********************************************************************/ +char *buffer2_to_multistr(BUFFER2 *str) +{ + char *lbuf = lbufs[nexti]; + char *p; + uint16 *buf = str->buffer; + int max_size = MIN(sizeof(str->buffer)-2, str->buf_len/2); + + nexti = (nexti+1)%8; + + for (p = lbuf; p-lbuf < max_size; p++, buf++) + { + if (*buf == 0) + { + *p = ' '; + } + else + { + *p = *buf; + } + } + + *p = 0; + return lbuf; +} + /******************************************************************* create a null-terminated unicode string from a null-terminated ascii string. return number of unicode chars copied, excluding the null character. diff --git a/source3/lsarpcd/srv_lsa.c b/source3/lsarpcd/srv_lsa.c index 8f22f8f574..5e6e101883 100644 --- a/source3/lsarpcd/srv_lsa.c +++ b/source3/lsarpcd/srv_lsa.c @@ -189,7 +189,7 @@ static void make_reply_lookup_rids(LSA_R_LOOKUP_RIDS *r_l, for (i = 0; i < num_entries; i++) { - make_dom_rid2(&(r_l->dom_rid[i]), dom_rids[i]); + make_dom_rid2(&(r_l->dom_rid[i]), dom_rids[i], 0x01); } r_l->num_entries3 = num_entries; diff --git a/source3/rpc_client/cli_reg.c b/source3/rpc_client/cli_reg.c index 2f04facffd..da92ab90bb 100644 --- a/source3/rpc_client/cli_reg.c +++ b/source3/rpc_client/cli_reg.c @@ -147,18 +147,18 @@ BOOL do_reg_open_unk_4(struct cli_state *cli, uint16 unknown_0, uint32 level, } /**************************************************************************** -do a REG Query Unknown 10 +do a REG Query Key ****************************************************************************/ -BOOL do_reg_query_unk_10(struct cli_state *cli, POLICY_HND *hnd, - uint32 *unknown_0, uint32 *unknown_1, +BOOL do_reg_query_key(struct cli_state *cli, POLICY_HND *hnd, + char *class, uint32 *class_len, uint32 *num_subkeys, uint32 *max_subkeylen, - uint32 *unknown_4, uint32 *num_values, + uint32 *max_subkeysize, uint32 *num_values, uint32 *max_valnamelen, uint32 *max_valbufsize, - uint32 *unknown_8, NTTIME *mod_time) + uint32 *sec_desc, NTTIME *mod_time) { prs_struct rbuf; prs_struct buf; - REG_Q_QUERY_UNK_10 q_o; + REG_Q_QUERY_KEY q_o; BOOL valid_query = False; if (hnd == NULL) return False; @@ -166,30 +166,30 @@ BOOL do_reg_query_unk_10(struct cli_state *cli, POLICY_HND *hnd, 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_QUERY_UNK_10 */ + /* create and send a MSRPC command with api REG_QUERY_KEY */ - DEBUG(4,("REG Query Unknown 10\n")); + DEBUG(4,("REG Query Key\n")); - make_reg_q_query_unk_10(&q_o, hnd); + make_reg_q_query_key(&q_o, hnd, *class_len); /* turn parameters into data stream */ - reg_io_q_query_unk_10("", &q_o, &buf, 0); + reg_io_q_query_key("", &q_o, &buf, 0); /* send the data on \PIPE\ */ - if (rpc_api_pipe_req(cli, REG_QUERY_UNK_10, &buf, &rbuf)) + if (rpc_api_pipe_req(cli, REG_QUERY_KEY, &buf, &rbuf)) { - REG_R_QUERY_UNK_10 r_o; + REG_R_QUERY_KEY r_o; BOOL p; ZERO_STRUCT(r_o); - reg_io_r_query_unk_10("", &r_o, &rbuf, 0); + reg_io_r_query_key("", &r_o, &rbuf, 0); p = rbuf.offset != 0; if (p && r_o.status != 0) { /* report error code */ - DEBUG(0,("REG_QUERY_UNK_10: %s\n", get_nt_error_msg(r_o.status))); + DEBUG(0,("REG_QUERY_KEY: %s\n", get_nt_error_msg(r_o.status))); p = False; } @@ -197,16 +197,16 @@ BOOL do_reg_query_unk_10(struct cli_state *cli, POLICY_HND *hnd, { valid_query = True; - *unknown_0 = r_o.unknown_0 ; - *unknown_1 = r_o.unknown_1 ; + *class_len = r_o.hdr_class.uni_max_len; + fstrcpy(class, unistr2_to_str(&r_o.uni_class)); *num_subkeys = r_o.num_subkeys ; *max_subkeylen = r_o.max_subkeylen ; - *unknown_4 = r_o.unknown_4 ; + *max_subkeysize = r_o.max_subkeysize; *num_values = r_o.num_values ; *max_valnamelen = r_o.max_valnamelen; *max_valbufsize = r_o.max_valbufsize; - *unknown_8 = r_o.unknown_8 ; - *mod_time = r_o.mod_time ; + *sec_desc = r_o.sec_desc ; + *mod_time = r_o.mod_time ; } } @@ -394,6 +394,65 @@ BOOL do_reg_get_key_sec(struct cli_state *cli, POLICY_HND *hnd, return valid_query; } +/**************************************************************************** +do a REG Create Key +****************************************************************************/ +BOOL do_reg_create_key(struct cli_state *cli, POLICY_HND *hnd, + char *key_name, char *key_class, + SEC_INFO *sam_access, + POLICY_HND *key) +{ + prs_struct rbuf; + prs_struct buf; + REG_Q_CREATE_KEY q_o; + BOOL valid_create = 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 REG_CREATE_KEY */ + + DEBUG(4,("REG Create Key: %s %s 0x%08x\n", key_name, key_class, + sam_access != NULL ? sam_access->perms : 0)); + + make_reg_q_create_key(&q_o, hnd, key_name, key_class, sam_access); + + /* turn parameters into data stream */ + reg_io_q_create_key("", &q_o, &buf, 0); + + /* send the data on \PIPE\ */ + if (rpc_api_pipe_req(cli, REG_CREATE_KEY, &buf, &rbuf)) + { + REG_R_CREATE_KEY r_o; + BOOL p; + + ZERO_STRUCT(r_o); + + reg_io_r_create_key("", &r_o, &rbuf, 0); + p = rbuf.offset != 0; + + if (p && r_o.status != 0) + { + /* report error code */ + DEBUG(0,("REG_CREATE_KEY: %s\n", get_nt_error_msg(r_o.status))); + p = False; + } + + if (p) + { + valid_create = True; + memcpy(key, r_o.key_pol.data, sizeof(key->data)); + } + } + + prs_mem_free(&rbuf); + prs_mem_free(&buf ); + + return valid_create; +} + /**************************************************************************** do a REG Enum Key ****************************************************************************/ @@ -455,6 +514,61 @@ BOOL do_reg_enum_key(struct cli_state *cli, POLICY_HND *hnd, return valid_query; } +/**************************************************************************** +do a REG Create Value +****************************************************************************/ +BOOL do_reg_create_val(struct cli_state *cli, POLICY_HND *hnd, + char *val_name, uint32 type, BUFFER3 *data) +{ + prs_struct rbuf; + prs_struct buf; + REG_Q_CREATE_VALUE q_o; + BOOL valid_create = 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 REG_CREATE_VALUE */ + + DEBUG(4,("REG Create Value: %s\n", val_name)); + + make_reg_q_create_val(&q_o, hnd, val_name, type, data); + + /* turn parameters into data stream */ + reg_io_q_create_val("", &q_o, &buf, 0); + + /* send the data on \PIPE\ */ + if (rpc_api_pipe_req(cli, REG_CREATE_VALUE, &buf, &rbuf)) + { + REG_R_CREATE_VALUE r_o; + BOOL p; + + ZERO_STRUCT(r_o); + + reg_io_r_create_val("", &r_o, &rbuf, 0); + p = rbuf.offset != 0; + + if (p && r_o.status != 0) + { + /* report error code */ + DEBUG(0,("REG_CREATE_VALUE: %s\n", get_nt_error_msg(r_o.status))); + p = False; + } + + if (p) + { + valid_create = True; + } + } + + prs_mem_free(&rbuf); + prs_mem_free(&buf ); + + return valid_create; +} + /**************************************************************************** do a REG Enum Value ****************************************************************************/ diff --git a/source3/rpc_parse/parse_lsa.c b/source3/rpc_parse/parse_lsa.c index cc60ace9fc..a5c523fdb6 100644 --- a/source3/rpc_parse/parse_lsa.c +++ b/source3/rpc_parse/parse_lsa.c @@ -692,7 +692,7 @@ void lsa_io_q_lookup_rids(char *desc, LSA_Q_LOOKUP_RIDS *q_r, prs_struct *ps, i for (i = 0; i < q_r->num_entries; i++) { - smb_io_dom_name("", &(q_r->lookup_name[i]), ps, depth); /* names to be looked up */ + smb_io_unistr3("", &(q_r->lookup_name[i]), ps, depth); /* names to be looked up */ } prs_uint8s (False, "undoc ", ps, depth, q_r->undoc, UNKNOWN_LEN); diff --git a/source3/rpc_parse/parse_misc.c b/source3/rpc_parse/parse_misc.c index 0f242c4738..3a74d11e52 100644 --- a/source3/rpc_parse/parse_misc.c +++ b/source3/rpc_parse/parse_misc.c @@ -261,8 +261,8 @@ creates a UNIHDR structure. ********************************************************************/ void make_uni_hdr(UNIHDR *hdr, int max_len, int len, uint32 buffer) { - hdr->uni_max_len = 2 * max_len; hdr->uni_str_len = 2 * len; + hdr->uni_max_len = 2 * max_len; hdr->buffer = buffer; } @@ -287,6 +287,35 @@ void smb_io_unihdr(char *desc, UNIHDR *hdr, prs_struct *ps, int depth) if (hdr->uni_str_len > MAX_UNISTRLEN) hdr->uni_str_len = MAX_UNISTRLEN; } +/******************************************************************* +creates a BUFHDR structure. +********************************************************************/ +void make_buf_hdr(BUFHDR *hdr, int max_len, int len) +{ + hdr->buf_max_len = max_len; + hdr->buf_len = len; +} + +/******************************************************************* +reads or writes a BUFHDR structure. +********************************************************************/ +void smb_io_hdrbuf(char *desc, BUFHDR *hdr, prs_struct *ps, int depth) +{ + if (hdr == NULL) return; + + prs_debug(ps, depth, desc, "smb_io_hdrbuf"); + depth++; + + prs_align(ps); + + prs_uint32("buf_max_len", ps, depth, &(hdr->buf_max_len)); + prs_uint32("buf_len ", ps, depth, &(hdr->buf_len )); + + /* oops! XXXX maybe issue a warning that this is happening... */ + if (hdr->buf_max_len > MAX_BUFFERLEN) hdr->buf_max_len = MAX_BUFFERLEN; + if (hdr->buf_len > MAX_BUFFERLEN) hdr->buf_len = MAX_BUFFERLEN; +} + /******************************************************************* creates a UNIHDR2 structure. ********************************************************************/ @@ -337,53 +366,133 @@ void smb_io_unistr(char *desc, UNISTR *uni, prs_struct *ps, int depth) } /******************************************************************* -creates a UNINOTSTR2 structure. +creates a BUFFER3 structure from a uint32 ********************************************************************/ -void make_uninotstr2(UNINOTSTR2 *str, char *buf, int len) +void make_buffer3_uint32(BUFFER3 *str, uint32 val) { - /* set up string lengths. add one if string is not null-terminated */ - str->uni_max_len = (len+1)*2; + ZERO_STRUCTP(str); + + /* set up string lengths. */ + str->buf_max_len = sizeof(uint32); + str->buf_len = sizeof(uint32); + + SIVAL(str->buffer, 0, val); +} + +/******************************************************************* +creates a BUFFER3 structure. +********************************************************************/ +void make_buffer3_str(BUFFER3 *str, char *buf, int len) +{ + ZERO_STRUCTP(str); + + /* set up string lengths. */ + str->buf_max_len = len * 2; + str->buf_len = len * 2; + + /* store the string (null-terminated 8 bit chars into 16 bit chars) */ + struni2((uint16*)str->buffer, buf); +} + +/******************************************************************* +creates a BUFFER3 structure from a hex string. +********************************************************************/ +void make_buffer3_hex(BUFFER3 *str, char *buf) +{ + ZERO_STRUCTP(str); + str->buf_max_len = str->buf_len = strhex_to_str(str->buffer, sizeof(str->buffer), buf); +} + +/******************************************************************* +creates a BUFFER3 structure. +********************************************************************/ +void make_buffer3_bytes(BUFFER3 *str, uint8 *buf, int len) +{ + ZERO_STRUCTP(str); + + /* max buffer size (allocated size) */ + str->buf_max_len = len; + if (buf != NULL) + { + memcpy(str->buffer, buf, MIN(str->buf_len, sizeof(str->buffer))); + } + str->buf_len = buf != NULL ? len : 0; +} + +/******************************************************************* +reads or writes a BUFFER3 structure. + the uni_max_len member tells you how large the buffer is. + the uni_str_len member tells you how much of the buffer is really used. +********************************************************************/ +void smb_io_buffer3(char *desc, BUFFER3 *buf3, prs_struct *ps, int depth) +{ + if (buf3 == NULL) return; + + prs_debug(ps, depth, desc, "smb_io_buffer3"); + depth++; + + prs_align(ps); + + prs_uint32("uni_max_len", ps, depth, &(buf3->buf_max_len)); + if (buf3->buf_max_len > MAX_UNISTRLEN) buf3->buf_max_len = MAX_UNISTRLEN; + + prs_uint8s(True, "buffer ", ps, depth, buf3->buffer, buf3->buf_max_len); + + prs_uint32("buf_len ", ps, depth, &(buf3->buf_len)); + if (buf3->buf_len > MAX_UNISTRLEN) buf3->buf_len = MAX_UNISTRLEN; +} + +/******************************************************************* +creates a BUFFER2 structure. +********************************************************************/ +void make_buffer2(BUFFER2 *str, uint8 *buf, int len) +{ + ZERO_STRUCTP(str); + + /* max buffer size (allocated size) */ + str->buf_max_len = len; str->undoc = 0; - str->uni_buf_len = (len+1)*2; + str->buf_len = buf != NULL ? len : 0; - /* store the string (null-terminated copy) */ - struni2(str->buffer, buf); + if (buf != NULL) + { + memcpy(str->buffer, buf, MIN(str->buf_len, sizeof(str->buffer))); + } } /******************************************************************* -reads or writes a UNINOTSTR2 structure. -XXXX NOTE: UNISTR2 structures need NOT be null-terminated. - the uni_str_len member tells you how long the string is; +reads or writes a BUFFER2 structure. the uni_max_len member tells you how large the buffer is. + the uni_str_len member tells you how much of the buffer is really used. ********************************************************************/ -void smb_io_uninotstr2(char *desc, UNINOTSTR2 *uni2, uint32 buffer, prs_struct *ps, int depth) +void smb_io_buffer2(char *desc, BUFFER2 *buf2, uint32 buffer, prs_struct *ps, int depth) { - if (uni2 == NULL) return; + if (buf2 == NULL) return; if (buffer) { - prs_debug(ps, depth, desc, "smb_io_uninotstr2"); + prs_debug(ps, depth, desc, "smb_io_buffer2"); depth++; prs_align(ps); - prs_uint32("uni_max_len", ps, depth, &(uni2->uni_max_len)); - prs_uint32("undoc ", ps, depth, &(uni2->undoc )); - prs_uint32("uni_buf_len", ps, depth, &(uni2->uni_buf_len)); + prs_uint32("uni_max_len", ps, depth, &(buf2->buf_max_len)); + prs_uint32("undoc ", ps, depth, &(buf2->undoc )); + prs_uint32("buf_len ", ps, depth, &(buf2->buf_len)); /* oops! XXXX maybe issue a warning that this is happening... */ - if (uni2->uni_max_len > MAX_UNISTRLEN) uni2->uni_max_len = MAX_UNISTRLEN; - if (uni2->uni_buf_len > MAX_UNISTRLEN) uni2->uni_buf_len = MAX_UNISTRLEN; + if (buf2->buf_max_len > MAX_UNISTRLEN) buf2->buf_max_len = MAX_UNISTRLEN; + if (buf2->buf_len > MAX_UNISTRLEN) buf2->buf_len = MAX_UNISTRLEN; /* buffer advanced by indicated length of string NOT by searching for null-termination */ - prs_uninotstr2(True, "buffer ", ps, depth, uni2); + prs_buffer2(True, "buffer ", ps, depth, buf2); } else { - prs_debug(ps, depth, desc, "smb_io_uninotstr2 - NULL"); + prs_debug(ps, depth, desc, "smb_io_buffer2 - NULL"); depth++; - bzero(uni2, sizeof(*uni2)); + bzero(buf2, sizeof(*buf2)); } } @@ -475,7 +584,7 @@ creates a UNISTR2 structure. ********************************************************************/ void make_unistr2(UNISTR2 *str, char *buf, int len) { - ZERO_STRUCTP(str); + ZERO_STRUCTP(str); /* set up string lengths. */ str->uni_max_len = len; @@ -526,9 +635,9 @@ void smb_io_unistr2(char *desc, UNISTR2 *uni2, uint32 buffer, prs_struct *ps, i /******************************************************************* creates a DOM_RID2 structure. ********************************************************************/ -void make_dom_rid2(DOM_RID2 *rid2, uint32 rid) +void make_dom_rid2(DOM_RID2 *rid2, uint32 rid, uint8 type) { - rid2->type = 0x5; + rid2->type = type; rid2->undoc = 0x5; rid2->rid = rid; rid2->rid_idx = 0; @@ -561,10 +670,10 @@ void smb_io_dom_rid2(char *desc, DOM_RID2 *rid2, prs_struct *ps, int depth) /******************************************************************* creates a DOM_RID3 structure. ********************************************************************/ -void make_dom_rid3(DOM_RID3 *rid3, uint32 rid) +void make_dom_rid3(DOM_RID3 *rid3, uint32 rid, uint8 type) { rid3->rid = rid; - rid3->type1 = 0x1; + rid3->type1 = type; rid3->ptr_type = 0x1; /* non-zero, basically. */ rid3->type2 = 0x1; } @@ -946,13 +1055,13 @@ void smb_io_dom_query_5(char *desc, DOM_QUERY_3 *d_q, prs_struct *ps, int depth /******************************************************************* -reads or writes a DOM_NAME structure. +reads or writes a UNISTR3 structure. ********************************************************************/ -void smb_io_dom_name(char *desc, DOM_NAME *name, prs_struct *ps, int depth) +void smb_io_unistr3(char *desc, UNISTR3 *name, prs_struct *ps, int depth) { if (name == NULL) return; - prs_debug(ps, depth, desc, "smb_io_dom_name"); + prs_debug(ps, depth, desc, "smb_io_unistr3"); depth++; prs_align(ps); @@ -962,7 +1071,7 @@ void smb_io_dom_name(char *desc, DOM_NAME *name, prs_struct *ps, int depth) /* don't know if len is specified by uni_str_len member... */ /* assume unicode string is unicode-null-terminated, instead */ - smb_io_unistr("", &(name->str), ps, depth); + prs_unistr3(True, "unistr", name, ps, depth); } diff --git a/source3/rpc_parse/parse_prs.c b/source3/rpc_parse/parse_prs.c index d031a828f1..873a689792 100644 --- a/source3/rpc_parse/parse_prs.c +++ b/source3/rpc_parse/parse_prs.c @@ -175,13 +175,13 @@ BOOL prs_uint32s(BOOL charmode, char *name, prs_struct *ps, int depth, uint32 *d stream a "not" unicode string, length/buffer specified separately, in byte chars ********************************************************************/ -BOOL prs_uninotstr2(BOOL charmode, char *name, prs_struct *ps, int depth, UNINOTSTR2 *str) +BOOL prs_buffer2(BOOL charmode, char *name, prs_struct *ps, int depth, BUFFER2 *str) { char *q = mem_data(&(ps->data), ps->offset); if (q == NULL) return False; - DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, q, str->buffer, str->uni_max_len) - ps->offset += str->uni_buf_len; + DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, q, str->buffer, str->buf_len/2) + ps->offset += str->buf_len; return True; } @@ -210,7 +210,22 @@ BOOL prs_unistr2(BOOL charmode, char *name, prs_struct *ps, int depth, UNISTR2 * char *q = mem_data(&(ps->data), ps->offset); if (q == NULL) return False; - DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, q, str->buffer, str->uni_max_len) + DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, q, str->buffer, str->uni_str_len) + ps->offset += str->uni_str_len * sizeof(uint16); + + return True; +} + +/****************************************************************** + stream a unicode string, length/buffer specified separately, + in uint16 chars. + ********************************************************************/ +BOOL prs_unistr3(BOOL charmode, char *name, UNISTR3 *str, prs_struct *ps, int depth) +{ + char *q = mem_data(&(ps->data), ps->offset); + if (q == NULL) return False; + + DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, q, str->str.buffer, str->uni_str_len) ps->offset += str->uni_str_len * sizeof(uint16); return True; @@ -284,3 +299,38 @@ BOOL prs_string(char *name, prs_struct *ps, int depth, char *str, uint16 len, ui return True; } +/******************************************************************* + prs_uint16 wrapper. call this and it sets up a pointer to where the + uint16 should be stored, or gets the size if reading + ********************************************************************/ +BOOL prs_uint16_pre(char *name, prs_struct *ps, int depth, uint16 *data16, uint32 *off_ptr) +{ + (*off_ptr) = ps->offset; + if (ps->io) + { + /* reading. */ + return prs_uint16(name, ps, depth, data16); + } + return True; +} + +/******************************************************************* + prs_uint16 wrapper. call this and it retrospectively stores the size. + does nothing on reading, as that is already handled by ...._pre() + ********************************************************************/ +BOOL prs_uint16_post(char *name, prs_struct *ps, int depth, + uint32 ptr_uint16, uint32 start_offset) +{ + if (!ps->io) + { + /* storing: go back and do a retrospective job. i hate this */ + uint16 data_size = ps->offset - start_offset; + uint32 old_offset = ps->offset; + + ps->offset = ptr_uint16; + prs_uint16(name, ps, depth, &data_size); + ps->offset = old_offset; + } + return True; +} + diff --git a/source3/rpc_parse/parse_reg.c b/source3/rpc_parse/parse_reg.c index 6b464645e5..329da974fb 100644 --- a/source3/rpc_parse/parse_reg.c +++ b/source3/rpc_parse/parse_reg.c @@ -27,6 +27,18 @@ extern int DEBUGLEVEL; +/******************************************************************* +creates a structure. +********************************************************************/ +void make_reg_q_open_pol(REG_Q_OPEN_POLICY *q_o, + uint16 unknown_0, uint32 level) +{ + q_o->ptr = 1; + q_o->unknown_0 = unknown_0; + q_o->unknown_1 = 0x0; /* random - changes */ + q_o->level = level; +} + /******************************************************************* reads or writes a structure. ********************************************************************/ @@ -43,8 +55,8 @@ void reg_io_q_open_policy(char *desc, REG_Q_OPEN_POLICY *r_q, prs_struct *ps, i if (r_q->ptr != 0) { prs_uint16("unknown_0", ps, depth, &(r_q->unknown_0)); - prs_uint32("level ", ps, depth, &(r_q->level )); prs_uint16("unknown_1", ps, depth, &(r_q->unknown_1)); + prs_uint32("level ", ps, depth, &(r_q->level )); } } @@ -67,6 +79,286 @@ void reg_io_r_open_policy(char *desc, REG_R_OPEN_POLICY *r_r, prs_struct *ps, i } + +/******************************************************************* +creates a structure. +********************************************************************/ +void make_reg_q_create_key(REG_Q_CREATE_KEY *q_c, POLICY_HND *hnd, + char *name, char *class, + SEC_INFO *sam_access) +{ + int len_name = name != NULL ? strlen(name ) + 1: 0; + int len_class = class != NULL ? strlen(class) + 1: 0; + + static char data[] = + { + 0x01, 0x00, 0x00, 0x80, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; + + ZERO_STRUCTP(q_c); + + memcpy(&(q_c->pnt_pol), hnd, sizeof(q_c->pnt_pol)); + + make_uni_hdr(&(q_c->hdr_name), len_name, len_name, 1); + make_unistr2(&(q_c->uni_name), name, len_name); + + make_uni_hdr(&(q_c->hdr_class), len_class, len_class, 1); + make_unistr2(&(q_c->uni_class), class, len_class); + + q_c->reserved = 0x00000000; + memcpy(&(q_c->sam_access), sam_access, sizeof(q_c->sam_access)); + + q_c->ptr1 = 1; + q_c->unknown_0 = 0x0000000C; + + q_c->ptr2 = 1; + q_c->unk_len1 = 0x14; + q_c->unk_len2 = 0x14; + q_c->unknown_1 = 0x00020000; + + make_buffer2(&q_c->buf_unk, data, sizeof(data)); + + q_c->unknown_2 = 0x00000000; +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ +void reg_io_q_create_key(char *desc, REG_Q_CREATE_KEY *r_q, prs_struct *ps, int depth) +{ + if (r_q == NULL) return; + + prs_debug(ps, depth, desc, "reg_io_q_create_key"); + depth++; + + prs_align(ps); + + smb_io_pol_hnd("", &(r_q->pnt_pol), ps, depth); + + smb_io_unihdr ("", &(r_q->hdr_name), ps, depth); + smb_io_unistr2("", &(r_q->uni_name), r_q->hdr_name.buffer, ps, depth); + prs_align(ps); + + smb_io_unihdr ("", &(r_q->hdr_class), ps, depth); + smb_io_unistr2("", &(r_q->uni_class), r_q->hdr_class.buffer, ps, depth); + prs_align(ps); + + prs_uint32("reserved", ps, depth, &(r_q->reserved)); + sec_io_info("sam_access", &r_q->sam_access, ps, depth); + + prs_uint32("ptr1", ps, depth, &(r_q->ptr1)); + if (r_q->ptr2 != 0) + { + prs_uint32("unknown_0", ps, depth, &(r_q->unknown_0)); + } + + prs_uint32("ptr2", ps, depth, &(r_q->ptr2)); + if (r_q->ptr2) + { + prs_uint32("unk_len1", ps, depth, &(r_q->unk_len1)); + prs_uint32("unk_len2", ps, depth, &(r_q->unk_len2)); + prs_uint32("unknown_1", ps, depth, &(r_q->unknown_1)); + smb_io_buffer2("buf_unk", &r_q->buf_unk, 1, ps, depth); + prs_align(ps); + + prs_uint32("unknown_2", ps, depth, &(r_q->unknown_2)); + } + + prs_align(ps); +} + + +/******************************************************************* +reads or writes a structure. +********************************************************************/ +void reg_io_r_create_key(char *desc, REG_R_CREATE_KEY *r_r, prs_struct *ps, int depth) +{ + if (r_r == NULL) return; + + prs_debug(ps, depth, desc, "reg_io_r_create_key"); + depth++; + + prs_align(ps); + + smb_io_pol_hnd("", &(r_r->key_pol), ps, depth); + prs_uint32("unknown", ps, depth, &(r_r->unknown)); + + prs_uint32("status", ps, depth, &(r_r->status)); +} + + +/******************************************************************* +creates a structure. +********************************************************************/ +void make_reg_q_query_key(REG_Q_QUERY_KEY *q_o, POLICY_HND *hnd, + uint32 max_class_len) +{ + ZERO_STRUCTP(q_o); + + memcpy(&(q_o->pol), hnd, sizeof(q_o->pol)); + make_uni_hdr(&q_o->hdr_class, max_class_len, 0, max_class_len > 0 ? 1 : 0); + q_o->uni_class.uni_max_len = max_class_len; +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ +void reg_io_q_query_key(char *desc, REG_Q_QUERY_KEY *r_q, prs_struct *ps, int depth) +{ + if (r_q == NULL) return; + + prs_debug(ps, depth, desc, "reg_io_q_query_key"); + depth++; + + prs_align(ps); + + smb_io_pol_hnd("", &(r_q->pol), ps, depth); + smb_io_unihdr ("", &(r_q->hdr_class), ps, depth); + smb_io_unistr2("", &(r_q->uni_class), r_q->hdr_class.buffer, ps, depth); + + prs_align(ps); +} + + +/******************************************************************* +reads or writes a structure. +********************************************************************/ +void reg_io_r_query_key(char *desc, REG_R_QUERY_KEY *r_r, prs_struct *ps, int depth) +{ + if (r_r == NULL) return; + + prs_debug(ps, depth, desc, "reg_io_r_query_key"); + depth++; + + prs_align(ps); + + smb_io_unihdr ("", &(r_r->hdr_class), ps, depth); + smb_io_unistr2("", &(r_r->uni_class), r_r->hdr_class.buffer, ps, depth); + + prs_align(ps); + + prs_uint32("num_subkeys ", ps, depth, &(r_r->num_subkeys )); + prs_uint32("max_subkeylen ", ps, depth, &(r_r->max_subkeylen )); + prs_uint32("mak_subkeysize", ps, depth, &(r_r->max_subkeysize)); + prs_uint32("num_values ", ps, depth, &(r_r->num_values )); + prs_uint32("max_valnamelen", ps, depth, &(r_r->max_valnamelen)); + prs_uint32("max_valbufsize", ps, depth, &(r_r->max_valbufsize)); + prs_uint32("sec_desc ", ps, depth, &(r_r->sec_desc )); + smb_io_time("mod_time ", &(r_r->mod_time), ps, depth); + + prs_uint32("status", ps, depth, &(r_r->status)); +} + + +/******************************************************************* +creates a structure. +********************************************************************/ +void make_reg_q_unk_1a(REG_Q_UNK_1A *q_o, POLICY_HND *hnd) +{ + memcpy(&(q_o->pol), hnd, sizeof(q_o->pol)); +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ +void reg_io_q_unk_1a(char *desc, REG_Q_UNK_1A *r_q, prs_struct *ps, int depth) +{ + if (r_q == NULL) return; + + prs_debug(ps, depth, desc, "reg_io_q_unk_1a"); + depth++; + + prs_align(ps); + + smb_io_pol_hnd("", &(r_q->pol), ps, depth); +} + + +/******************************************************************* +reads or writes a structure. +********************************************************************/ +void reg_io_r_unk_1a(char *desc, REG_R_UNK_1A *r_r, prs_struct *ps, int depth) +{ + if (r_r == NULL) return; + + prs_debug(ps, depth, desc, "reg_io_r_unk_1a"); + depth++; + + prs_align(ps); + + prs_uint32("unknown", ps, depth, &(r_r->unknown)); + prs_uint32("status" , ps, depth, &(r_r->status )); +} + + +/******************************************************************* +creates a structure. +********************************************************************/ +void make_reg_q_open_unk_4(REG_Q_OPEN_UNK_4 *q_o, + uint16 unknown_0, uint32 level) +{ + q_o->ptr = 1; + q_o->unknown_0 = unknown_0; + q_o->unknown_1 = 0x0; /* random - changes */ + q_o->level = level; +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ +void reg_io_q_open_unk_4(char *desc, REG_Q_OPEN_UNK_4 *r_q, prs_struct *ps, int depth) +{ + if (r_q == NULL) return; + + prs_debug(ps, depth, desc, "reg_io_q_open_unk_4"); + depth++; + + prs_align(ps); + + prs_uint32("ptr ", ps, depth, &(r_q->ptr )); + if (r_q->ptr != 0) + { + prs_uint16("unknown_0", ps, depth, &(r_q->unknown_0)); + prs_uint16("unknown_1", ps, depth, &(r_q->unknown_1)); + prs_uint32("level ", ps, depth, &(r_q->level )); + } +} + + +/******************************************************************* +reads or writes a structure. +********************************************************************/ +void reg_io_r_open_unk_4(char *desc, REG_R_OPEN_UNK_4 *r_r, prs_struct *ps, int depth) +{ + if (r_r == NULL) return; + + prs_debug(ps, depth, desc, "reg_io_r_open_unk_4"); + depth++; + + prs_align(ps); + + smb_io_pol_hnd("", &(r_r->pol), ps, depth); + + prs_uint32("status", ps, depth, &(r_r->status)); +} + + +/******************************************************************* +makes an REG_Q_CLOSE structure. +********************************************************************/ +void make_reg_q_close(REG_Q_CLOSE *q_c, POLICY_HND *hnd) +{ + if (q_c == NULL || hnd == NULL) return; + + DEBUG(5,("make_reg_q_close\n")); + + memcpy(&(q_c->pol), hnd, sizeof(q_c->pol)); +} + /******************************************************************* reads or writes a structure. ********************************************************************/ @@ -101,6 +393,123 @@ void reg_io_r_close(char *desc, REG_R_CLOSE *r_u, prs_struct *ps, int depth) prs_uint32("status", ps, depth, &(r_u->status)); } +/******************************************************************* +makes a structure. +********************************************************************/ +void make_reg_q_get_key_sec(REG_Q_GET_KEY_SEC *q_i, POLICY_HND *pol, + uint32 buf_len, SEC_DESC_BUF *sec_buf) +{ + if (q_i == NULL) return; + + memcpy(&(q_i->pol), pol, sizeof(q_i->pol)); + + q_i->unknown = 0x7; + + q_i->ptr = 1; + q_i->data = sec_buf; + + make_buf_hdr(&(q_i->hdr_sec), buf_len, 0); + make_sec_desc_buf(q_i->data, buf_len, 0); +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ +void reg_io_q_get_key_sec(char *desc, REG_Q_GET_KEY_SEC *r_q, prs_struct *ps, int depth) +{ + if (r_q == NULL) return; + + prs_debug(ps, depth, desc, "reg_io_q_get_key_sec"); + depth++; + + prs_align(ps); + + smb_io_pol_hnd("", &(r_q->pol), ps, depth); + + prs_uint32("unknown", ps, depth, &(r_q->unknown)); + prs_uint32("ptr ", ps, depth, &(r_q->ptr )); + + if (r_q->ptr != 0) + { + smb_io_hdrbuf ("hdr_sec", &(r_q->hdr_sec), ps, depth); + sec_io_desc_buf("data ", r_q->data , ps, depth); + + prs_align(ps); + } +} + +/******************************************************************* +makes a structure. +********************************************************************/ +void make_reg_r_get_key_sec(REG_R_GET_KEY_SEC *r_i, POLICY_HND *pol, + uint32 buf_len, uint8 *buf, + uint32 status) +{ + if (r_i == NULL) return; + + r_i->ptr = 1; + make_buf_hdr(&(r_i->hdr_sec), buf_len, buf_len); + make_sec_desc_buf(r_i->data, buf_len, 1); + + r_i->status = status; /* 0x0000 0000 or 0x0000 007a */ +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ +void reg_io_r_get_key_sec(char *desc, REG_R_GET_KEY_SEC *r_q, prs_struct *ps, int depth) +{ + if (r_q == NULL) return; + + prs_debug(ps, depth, desc, "reg_io_r_get_key_sec"); + depth++; + + prs_align(ps); + + prs_uint32("ptr ", ps, depth, &(r_q->ptr )); + + if (r_q->ptr != 0) + { + smb_io_hdrbuf("", &(r_q->hdr_sec), ps, depth); + sec_io_desc_buf("", r_q->data, ps, depth); + + prs_align(ps); + } + + prs_uint32("status", ps, depth, &(r_q->status)); +} + + +/******************************************************************* +makes a structure. +********************************************************************/ +void make_reg_q_info(REG_Q_INFO *q_i, POLICY_HND *pol, char *product_type, + time_t unix_time, uint8 major, uint8 minor) +{ + int len_type = strlen(product_type); + + if (q_i == NULL) return; + + memcpy(&(q_i->pol), pol, sizeof(q_i->pol)); + + make_uni_hdr(&(q_i->hdr_type), len_type, len_type, 1); + make_unistr2(&(q_i->uni_type), product_type, len_type); + + q_i->ptr1 = 1; + unix_to_nt_time(&(q_i->time), unix_time); + q_i->major_version1 = major; + q_i->minor_version1 = minor; + memset(q_i->pad1, 0, sizeof(q_i->pad1)); + + q_i->ptr2 = 1; + q_i->major_version2 = major; + q_i->minor_version2 = minor; + memset(q_i->pad2, 0, sizeof(q_i->pad2)); + + q_i->ptr3 = 1; + q_i->unknown = 0x00000000; +} + /******************************************************************* reads or writes a structure. ********************************************************************/ @@ -117,6 +526,8 @@ void reg_io_q_info(char *desc, REG_Q_INFO *r_q, prs_struct *ps, int depth) smb_io_unihdr ("", &(r_q->hdr_type), ps, depth); smb_io_unistr2("", &(r_q->uni_type), r_q->hdr_type.buffer, ps, depth); + prs_align(ps); + prs_uint32("ptr1", ps, depth, &(r_q->ptr1)); if (r_q->ptr1 != 0) @@ -153,13 +564,14 @@ void make_reg_r_info(REG_R_INFO *r_r, uint32 unknown_0, uint32 unknown_1, uint32 status) { - int type_len = strlen(os_type); + uint8 buf[512]; + int len = struni2((uint16*)buf, os_type); r_r->ptr1 = 1; r_r->level = level; r_r->ptr_type = 1; - make_uninotstr2(&(r_r->uni_type), os_type, type_len); + make_buffer2(&(r_r->uni_type), buf, len*2); r_r->ptr2 = 1; r_r->unknown_0 = unknown_0; @@ -173,7 +585,7 @@ void make_reg_r_info(REG_R_INFO *r_r, /******************************************************************* reads or writes a structure. ********************************************************************/ -void reg_io_r_info(char *desc, REG_R_INFO *r_r, prs_struct *ps, int depth) +void reg_io_r_info(char *desc, REG_R_INFO *r_r, prs_struct *ps, int depth) { if (r_r == NULL) return; @@ -187,10 +599,9 @@ void reg_io_r_info(char *desc, REG_R_INFO *r_r, prs_struct *ps, int depth) if (r_r->ptr1 != 0) { prs_uint32("level", ps, depth, &(r_r->level)); - prs_uint32("ptr_type", ps, depth, &(r_r->ptr_type)); - smb_io_uninotstr2("", &(r_r->uni_type), r_r->ptr_type, ps, depth); - prs_align(ps); + + smb_io_buffer2("uni_type", &(r_r->uni_type), r_r->ptr_type, ps, depth); prs_uint32("ptr2", ps, depth, &(r_r->ptr2)); @@ -205,11 +616,311 @@ void reg_io_r_info(char *desc, REG_R_INFO *r_r, prs_struct *ps, int depth) { prs_uint32("unknown_1", ps, depth, &(r_r->unknown_1)); } - } + } prs_uint32("status", ps, depth, &(r_r->status)); } +/******************************************************************* +makes a structure. +********************************************************************/ +void make_reg_q_enum_val(REG_Q_ENUM_VALUE *q_i, POLICY_HND *pol, + uint32 val_idx, uint32 max_val_len, + uint32 max_buf_len) +{ + if (q_i == NULL) return; + + ZERO_STRUCTP(q_i); + + memcpy(&(q_i->pol), pol, sizeof(q_i->pol)); + + q_i->val_index = val_idx; + make_uni_hdr(&q_i->hdr_name, max_val_len, 0, 1); + q_i->uni_name.uni_max_len = max_val_len; + + q_i->ptr_type = 1; + q_i->type = 0x0; + + q_i->ptr_value = 1; + q_i->buf_value.buf_max_len = max_buf_len; + + q_i->ptr1 = 1; + q_i->len_value1 = max_buf_len; + + q_i->ptr2 = 1; + q_i->len_value2 = 0; +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ +void reg_io_q_enum_val(char *desc, REG_Q_ENUM_VALUE *q_q, prs_struct *ps, int depth) +{ + if (q_q == NULL) return; + + prs_debug(ps, depth, desc, "reg_io_q_enum_val"); + depth++; + + prs_align(ps); + + smb_io_pol_hnd("", &(q_q->pol), ps, depth); + + prs_uint32("val_index", ps, depth, &(q_q->val_index)); + smb_io_unihdr ("hdr_name", &(q_q->hdr_name), ps, depth); + smb_io_unistr2("uni_name", &(q_q->uni_name), q_q->hdr_name.buffer, ps, depth); + prs_align(ps); + + prs_uint32("ptr_type", ps, depth, &(q_q->ptr_type)); + + if (q_q->ptr_type != 0) + { + prs_uint32("type", ps, depth, &(q_q->type)); + } + + prs_uint32("ptr_value", ps, depth, &(q_q->ptr_value)); + smb_io_buffer2("buf_value", &(q_q->buf_value), q_q->ptr_value, ps, depth); + prs_align(ps); + + prs_uint32("ptr1", ps, depth, &(q_q->ptr1)); + if (q_q->ptr1 != 0) + { + prs_uint32("len_value1", ps, depth, &(q_q->len_value1)); + } + prs_uint32("ptr2", ps, depth, &(q_q->ptr2)); + if (q_q->ptr2 != 0) + { + prs_uint32("len_value2", ps, depth, &(q_q->len_value2)); + } +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ +void reg_io_r_enum_val(char *desc, REG_R_ENUM_VALUE *r_q, prs_struct *ps, int depth) +{ + if (r_q == NULL) return; + + prs_debug(ps, depth, desc, "reg_io_r_enum_val"); + depth++; + + prs_align(ps); + + smb_io_unihdr ("hdr_name", &(r_q->hdr_name), ps, depth); + smb_io_unistr2("uni_name", &(r_q->uni_name), r_q->hdr_name.buffer, ps, depth); + prs_align(ps); + + prs_uint32("ptr_type", ps, depth, &(r_q->ptr_type)); + + if (r_q->ptr_type != 0) + { + prs_uint32("type", ps, depth, &(r_q->type)); + } + + prs_uint32("ptr_value", ps, depth, &(r_q->ptr_value)); + smb_io_buffer2("buf_value", r_q->buf_value, r_q->ptr_value, ps, depth); + prs_align(ps); + + prs_uint32("ptr1", ps, depth, &(r_q->ptr1)); + if (r_q->ptr1 != 0) + { + prs_uint32("len_value1", ps, depth, &(r_q->len_value1)); + } + + prs_uint32("ptr2", ps, depth, &(r_q->ptr2)); + if (r_q->ptr2 != 0) + { + prs_uint32("len_value2", ps, depth, &(r_q->len_value2)); + } + + prs_uint32("status", ps, depth, &(r_q->status)); +} + +/******************************************************************* +makes a structure. +********************************************************************/ +void make_reg_q_create_val(REG_Q_CREATE_VALUE *q_i, POLICY_HND *pol, + char *val_name, uint32 type, + BUFFER3 *val) +{ + int val_len = strlen(val_name) + 1; + + if (q_i == NULL) return; + + ZERO_STRUCTP(q_i); + + memcpy(&(q_i->pol), pol, sizeof(q_i->pol)); + + make_uni_hdr(&q_i->hdr_name, val_len, val_len, 1); + make_unistr2(&(q_i->uni_name), val_name, val_len); + + q_i->type = type; + q_i->buf_value = val; +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ +void reg_io_q_create_val(char *desc, REG_Q_CREATE_VALUE *q_q, prs_struct *ps, int depth) +{ + if (q_q == NULL) return; + + prs_debug(ps, depth, desc, "reg_io_q_create_val"); + depth++; + + prs_align(ps); + + smb_io_pol_hnd("", &(q_q->pol), ps, depth); + + smb_io_unihdr ("hdr_name", &(q_q->hdr_name), ps, depth); + smb_io_unistr2("uni_name", &(q_q->uni_name), q_q->hdr_name.buffer, ps, depth); + prs_align(ps); + + prs_uint32("type", ps, depth, &(q_q->type)); + smb_io_buffer3("buf_value", q_q->buf_value, ps, depth); + prs_align(ps); +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ +void reg_io_r_create_val(char *desc, REG_R_CREATE_VALUE *r_q, prs_struct *ps, int depth) +{ + if (r_q == NULL) return; + + prs_debug(ps, depth, desc, "reg_io_r_create_val"); + depth++; + + prs_align(ps); + + prs_uint32("status", ps, depth, &(r_q->status)); +} + +/******************************************************************* +makes a structure. +********************************************************************/ +void make_reg_q_enum_key(REG_Q_ENUM_KEY *q_i, POLICY_HND *pol, uint32 key_idx) +{ + if (q_i == NULL) return; + + memcpy(&(q_i->pol), pol, sizeof(q_i->pol)); + + q_i->key_index = key_idx; + q_i->key_name_len = 0; + q_i->unknown_1 = 0x0414; + + q_i->ptr1 = 1; + q_i->unknown_2 = 0x0000020A; + memset(q_i->pad1, 0, sizeof(q_i->pad1)); + + q_i->ptr2 = 1; + memset(q_i->pad2, 0, sizeof(q_i->pad2)); + + q_i->ptr3 = 1; + unix_to_nt_time(&q_i->time, 0); /* current time? */ +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ +void reg_io_q_enum_key(char *desc, REG_Q_ENUM_KEY *q_q, prs_struct *ps, int depth) +{ + if (q_q == NULL) return; + + prs_debug(ps, depth, desc, "reg_io_q_enum_key"); + depth++; + + prs_align(ps); + + smb_io_pol_hnd("", &(q_q->pol), ps, depth); + + prs_uint32("key_index", ps, depth, &(q_q->key_index)); + prs_uint16("key_name_len", ps, depth, &(q_q->key_name_len)); + prs_uint16("unknown_1", ps, depth, &(q_q->unknown_1)); + + prs_uint32("ptr1", ps, depth, &(q_q->ptr1)); + + if (q_q->ptr1 != 0) + { + prs_uint32("unknown_2", ps, depth, &(q_q->unknown_2)); + prs_uint8s(False, "pad1", ps, depth, q_q->pad1, sizeof(q_q->pad1)); + } + + prs_uint32("ptr2", ps, depth, &(q_q->ptr2)); + + if (q_q->ptr2 != 0) + { + prs_uint8s(False, "pad2", ps, depth, q_q->pad2, sizeof(q_q->pad2)); + } + + prs_uint32("ptr3", ps, depth, &(q_q->ptr3)); + + if (q_q->ptr3 != 0) + { + smb_io_time("", &(q_q->time), ps, depth); + } +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ +void reg_io_r_enum_key(char *desc, REG_R_ENUM_KEY *r_q, prs_struct *ps, int depth) +{ + if (r_q == NULL) return; + + prs_debug(ps, depth, desc, "reg_io_r_enum_key"); + depth++; + + prs_align(ps); + + prs_uint16("key_name_len", ps, depth, &(r_q->key_name_len)); + prs_uint16("unknown_1", ps, depth, &(r_q->unknown_1)); + + prs_uint32("ptr1", ps, depth, &(r_q->ptr1)); + + if (r_q->ptr1 != 0) + { + prs_uint32("unknown_2", ps, depth, &(r_q->unknown_2)); + prs_uint32("unknown_3", ps, depth, &(r_q->unknown_3)); + smb_io_unistr3("key_name", &(r_q->key_name), ps, depth); + prs_align(ps); + } + + prs_uint32("ptr2", ps, depth, &(r_q->ptr2)); + + if (r_q->ptr2 != 0) + { + prs_uint8s(False, "pad2", ps, depth, r_q->pad2, sizeof(r_q->pad2)); + } + + prs_uint32("ptr3", ps, depth, &(r_q->ptr3)); + + if (r_q->ptr3 != 0) + { + smb_io_time("", &(r_q->time), ps, depth); + } + + prs_uint32("status", ps, depth, &(r_q->status)); +} + + +/******************************************************************* +makes a structure. +********************************************************************/ +void make_reg_q_open_entry(REG_Q_OPEN_ENTRY *r_q, POLICY_HND *pol, + char *key_name, uint32 unk) +{ + int len_name = strlen(key_name)+1; + + if (r_q == NULL) return; + + memcpy(&(r_q->pol), pol, sizeof(r_q->pol)); + + make_uni_hdr(&(r_q->hdr_name), len_name, len_name, 1); + make_unistr2(&(r_q->uni_name), key_name, len_name); + + r_q->unknown_0 = 0x00000000; + r_q->unknown_1 = unk; +} /******************************************************************* reads or writes a structure. @@ -227,9 +938,10 @@ void reg_io_q_open_entry(char *desc, REG_Q_OPEN_ENTRY *r_q, prs_struct *ps, int smb_io_unihdr ("", &(r_q->hdr_name), ps, depth); smb_io_unistr2("", &(r_q->uni_name), r_q->hdr_name.buffer, ps, depth); + prs_align(ps); + prs_uint32("unknown_0", ps, depth, &(r_q->unknown_0)); - prs_uint16("unknown_1", ps, depth, &(r_q->unknown_1)); - prs_uint16("unknown_2", ps, depth, &(r_q->unknown_2)); + prs_uint32("unknown_1", ps, depth, &(r_q->unknown_1)); } diff --git a/source3/rpc_parse/parse_samr.c b/source3/rpc_parse/parse_samr.c index ba6a8d3556..ec4411b783 100644 --- a/source3/rpc_parse/parse_samr.c +++ b/source3/rpc_parse/parse_samr.c @@ -1810,7 +1810,7 @@ void make_samr_r_lookup_names(SAMR_R_LOOKUP_NAMES *r_u, for (i = 0; i < num_rids; i++) { - make_dom_rid3(&(r_u->dom_rid[i]), rid[i]); + make_dom_rid3(&(r_u->dom_rid[i]), rid[i], 0x01); } r_u->num_entries3 = num_rids; diff --git a/source3/rpc_server/srv_lsa.c b/source3/rpc_server/srv_lsa.c index 8f22f8f574..5e6e101883 100644 --- a/source3/rpc_server/srv_lsa.c +++ b/source3/rpc_server/srv_lsa.c @@ -189,7 +189,7 @@ static void make_reply_lookup_rids(LSA_R_LOOKUP_RIDS *r_l, for (i = 0; i < num_entries; i++) { - make_dom_rid2(&(r_l->dom_rid[i]), dom_rids[i]); + make_dom_rid2(&(r_l->dom_rid[i]), dom_rids[i], 0x01); } r_l->num_entries3 = num_entries; diff --git a/source3/rpcclient/cmd_reg.c b/source3/rpcclient/cmd_reg.c index 399fb30603..48b6d385bb 100644 --- a/source3/rpcclient/cmd_reg.c +++ b/source3/rpcclient/cmd_reg.c @@ -42,9 +42,6 @@ nt registry enum ****************************************************************************/ void cmd_reg_enum(struct client_info *info) { - fstring type; - uint32 unk_0; - uint32 unk_1; BOOL res = True; BOOL res1 = True; BOOL res2 = True; @@ -57,15 +54,15 @@ void cmd_reg_enum(struct client_info *info) * query key info */ - uint32 unknown_0; - uint32 unknown_1; + fstring key_class; + uint32 max_class_len = 0; uint32 num_subkeys; uint32 max_subkeylen; - uint32 unknown_4; + uint32 max_subkeysize; uint32 num_values; uint32 max_valnamelen; uint32 max_valbufsize; - uint32 unknown_8; + uint32 sec_desc; NTTIME mod_time; /* @@ -94,28 +91,12 @@ void cmd_reg_enum(struct client_info *info) res1 = res ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect, key_name, 0x02000000, &key_pol) : False; - /* query it */ - res1 = res1 ? do_reg_query_info(smb_cli, &key_pol, - type, &unk_0, &unk_1) : False; - - res1 = res1 ? do_reg_query_unk_10(smb_cli, + res1 = res1 ? do_reg_query_key(smb_cli, &key_pol, - &unknown_0, &unknown_1, - &num_subkeys, &max_subkeylen, - &unknown_4, &num_values, - &max_valnamelen, &max_valbufsize, - &unknown_8, &mod_time) : False; - - if (res1) - { - fprintf(out_hnd,"Registry Query Info Key\n"); - fprintf(out_hnd,"unk_0,1 : 0x%x 0x%x\n", unknown_0, unknown_1); - fprintf(out_hnd,"subkeys, max_len: %d %d\n", num_subkeys, max_subkeylen); - fprintf(out_hnd,"unk_4 : 0x%x\n", unknown_4); - fprintf(out_hnd,"vals, max_len, max_size: 0x%x 0x%x 0x%x\n", num_values, max_valnamelen, max_valbufsize); - fprintf(out_hnd,"unk_8: 0x%x\n", unknown_8); - fprintf(out_hnd,"mod time: %s\n", http_timestring(nt_time_to_unix(&mod_time))); - } + key_class, &max_class_len, + &num_subkeys, &max_subkeylen, &max_subkeysize, + &num_values, &max_valnamelen, &max_valbufsize, + &sec_desc, &mod_time) : False; for (i = 0; i < num_subkeys; i++) { @@ -194,8 +175,6 @@ void cmd_reg_enum(struct client_info *info) if (res && res1 && res2) { DEBUG(5,("cmd_reg_enum: query succeeded\n")); - fprintf(out_hnd,"Registry Enumeration\n"); - fprintf(out_hnd,"Type: %s unk_0:%x unk_1:%x\n", type, unk_0, unk_1); } else { @@ -203,6 +182,96 @@ void cmd_reg_enum(struct client_info *info) } } +/**************************************************************************** +nt registry query key +****************************************************************************/ +void cmd_reg_query_key(struct client_info *info) +{ + BOOL res = True; + BOOL res1 = True; + + POLICY_HND key_pol; + fstring key_name; + + /* + * query key info + */ + + fstring key_class; + uint32 key_class_len = 0; + uint32 num_subkeys; + uint32 max_subkeylen; + uint32 max_subkeysize; + uint32 num_values; + uint32 max_valnamelen; + uint32 max_valbufsize; + uint32 sec_desc; + NTTIME mod_time; + + DEBUG(5, ("cmd_reg_enum: smb_cli->fd:%d\n", smb_cli->fd)); + + if (!next_token(NULL, key_name, NULL, sizeof(key_name))) + { + fprintf(out_hnd, "regquery key_name\n"); + return; + } + + /* open WINREG session. */ + res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False; + + /* open registry receive a policy handle */ + res = res ? do_reg_open_policy(smb_cli, + 0x84E0, 0x02000000, + &info->dom.reg_pol_connect) : False; + + /* open an entry */ + res1 = res ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect, + key_name, 0x02000000, &key_pol) : False; + + res1 = res1 ? do_reg_query_key(smb_cli, + &key_pol, + key_class, &key_class_len, + &num_subkeys, &max_subkeylen, &max_subkeysize, + &num_values, &max_valnamelen, &max_valbufsize, + &sec_desc, &mod_time) : False; + + if (res1 && key_class_len != 0) + { + res1 = res1 ? do_reg_query_key(smb_cli, + &key_pol, + key_class, &key_class_len, + &num_subkeys, &max_subkeylen, &max_subkeysize, + &num_values, &max_valnamelen, &max_valbufsize, + &sec_desc, &mod_time) : False; + } + + if (res1) + { + fprintf(out_hnd,"Registry Query Info Key\n"); + fprintf(out_hnd,"key class: %s\n", key_class); + fprintf(out_hnd,"subkeys, max_len, max_size: %d %d %d\n", num_subkeys, max_subkeylen, max_subkeysize); + fprintf(out_hnd,"vals, max_len, max_size: 0x%x 0x%x 0x%x\n", num_values, max_valnamelen, max_valbufsize); + fprintf(out_hnd,"sec desc: 0x%x\n", sec_desc); + fprintf(out_hnd,"mod time: %s\n", http_timestring(nt_time_to_unix(&mod_time))); + } + + /* close the handles */ + res1 = res1 ? do_reg_close(smb_cli, &key_pol) : False; + res = res ? do_reg_close(smb_cli, &info->dom.reg_pol_connect) : False; + + /* close the session */ + cli_nt_session_close(smb_cli); + + if (res && res1) + { + DEBUG(5,("cmd_reg_query: query succeeded\n")); + } + else + { + DEBUG(5,("cmd_reg_query: query failed\n")); + } +} + /**************************************************************************** nt registry test ****************************************************************************/ @@ -211,21 +280,23 @@ void cmd_reg_test2(struct client_info *info) BOOL res = True; BOOL res1 = True; BOOL res2 = True; + BOOL res3 = True; int i; /* * query key info */ - uint32 unknown_0; - uint32 unknown_1; + POLICY_HND key_pol; + fstring key_class; + uint32 max_class_len; uint32 num_subkeys; uint32 max_subkeylen; - uint32 unknown_4; + uint32 max_subkeysize; uint32 num_values; uint32 max_valnamelen; - uint32 unknown_7; - uint32 unknown_8; + uint32 max_valbufsize; + uint32 sec_desc; NTTIME mod_time; /* @@ -257,43 +328,31 @@ void cmd_reg_test2(struct client_info *info) 0x84E0, 0x02000000, &info->dom.reg_pol_unk_4 ) : False; - res2 = res1 ? do_reg_query_unk_10(smb_cli, - &info->dom.reg_pol_connect, - &unknown_0, &unknown_1, - &num_subkeys, &max_subkeylen, - &unknown_4, &num_values, - &max_valnamelen, &unknown_7, - &unknown_8, &mod_time) : False; - - if (res2) - { - fprintf(out_hnd,"Registry Query Info Key\n"); - fprintf(out_hnd,"unk_0,1 : 0x%x 0x%x\n", unknown_0, unknown_1); - fprintf(out_hnd,"subkeys, max_len: %d %d\n", num_subkeys, max_subkeylen); - fprintf(out_hnd,"unk_4 : 0x%x\n", unknown_4); - fprintf(out_hnd,"vals, max_len : 0x%x 0x%x\n", num_values, max_valnamelen); - fprintf(out_hnd,"unk_7, 8: 0x%x 0x%x\n", unknown_7, unknown_8); - fprintf(out_hnd,"mod time: %s\n", http_timestring(nt_time_to_unix(&mod_time))); - } + res2 = res1 ? do_reg_query_key(smb_cli, + &key_pol, + key_class, &max_class_len, + &num_subkeys, &max_subkeylen, &max_subkeysize, + &num_values, &max_valnamelen, &max_valbufsize, + &sec_desc, &mod_time) : False; for (i = 0; i < num_subkeys; i++) { /* unknown 1a it */ - res2 = res1 ? do_reg_unknown_1a(smb_cli, &info->dom.reg_pol_connect, + res3 = res2 ? do_reg_unknown_1a(smb_cli, &info->dom.reg_pol_connect, &unk_1a_response) : False; - if (res2) + if (res3) { fprintf(out_hnd,"Unknown 1a response: %x\n", unk_1a_response); } /* enum key */ - res2 = res2 ? do_reg_enum_key(smb_cli, &info->dom.reg_pol_connect, + res3 = res3 ? do_reg_enum_key(smb_cli, &info->dom.reg_pol_connect, i, enum_name, &enum_unk1, &enum_unk2, &key_mod_time) : False; - if (res2) + if (res3) { fprintf(out_hnd,"Enum Key: %s ", enum_name); fprintf(out_hnd,"unk (%08x %08x) ", enum_unk1, enum_unk2); @@ -302,6 +361,7 @@ void cmd_reg_test2(struct client_info *info) } /* close the handles */ + res2 = res2 ? do_reg_close(smb_cli, &key_pol ) : False; res1 = res1 ? do_reg_close(smb_cli, &info->dom.reg_pol_unk_4 ) : False; res = res ? do_reg_close(smb_cli, &info->dom.reg_pol_connect) : False; @@ -319,6 +379,221 @@ void cmd_reg_test2(struct client_info *info) } } +/**************************************************************************** +nt registry create value +****************************************************************************/ +void cmd_reg_create_val(struct client_info *info) +{ + BOOL res = True; + BOOL res3 = True; + BOOL res4 = True; + + POLICY_HND parent_pol; + fstring parent_name; + fstring val_name; + fstring tmp; + uint32 val_type; + BUFFER3 value; + +#if 0 + uint32 unk_0; + uint32 unk_1; + /* query it */ + res1 = res1 ? do_reg_query_info(smb_cli, &val_pol, + type, &unk_0, &unk_1) : False; +#endif + + DEBUG(5, ("cmd_reg_get_val_sec: smb_cli->fd:%d\n", smb_cli->fd)); + + if (!next_token(NULL, parent_name, NULL, sizeof(parent_name))) + { + fprintf(out_hnd, "regcreate \n"); + return; + } + + if (!next_token(NULL, val_name , NULL, sizeof(val_name ))) + { + fprintf(out_hnd, "regcreate \n"); + return; + } + + if (!next_token(NULL, tmp, NULL, sizeof(tmp))) + { + fprintf(out_hnd, "regcreate \n"); + return; + } + + val_type = atoi(tmp); + + if (val_type != 1 && val_type != 3 && val_type != 4) + { + fprintf(out_hnd, "val_type 1=UNISTR, 3=BYTES, 4=DWORD supported\n"); + return; + } + + if (!next_token(NULL, tmp, NULL, sizeof(tmp))) + { + fprintf(out_hnd, "regcreate \n"); + return; + } + + switch (val_type) + { + case 0x01: /* UNISTR */ + { + make_buffer3_str(&value, tmp, strlen(tmp)+1); + break; + } + case 0x03: /* BYTES */ + { + make_buffer3_hex(&value, tmp); + break; + } + case 0x04: /* DWORD */ + { + uint32 tmp_val; + if (strnequal(tmp, "0x", 2)) + { + tmp_val = strtol(tmp, (char**)NULL, 16); + } + else + { + tmp_val = strtol(tmp, (char**)NULL, 10); + } + make_buffer3_uint32(&value, tmp_val); + break; + } + default: + { + fprintf(out_hnd, "i told you i only deal with UNISTR, DWORD and BYTES!\n"); + return; + } + } + + DEBUG(10,("key data:\n")); + dump_data(10, value.buffer, value.buf_len); + + /* open WINREG session. */ + res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False; + + /* open registry receive a policy handle */ + res = res ? do_reg_open_policy(smb_cli, + 0x84E0, 0x02000000, + &info->dom.reg_pol_connect) : False; + + /* open an entry */ + res3 = res ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect, + parent_name, 0x02000000, &parent_pol) : False; + + /* create an entry */ + res4 = res3 ? do_reg_create_val(smb_cli, &parent_pol, + val_name, val_type, &value) : False; + + /* close the val handle */ + res3 = res3 ? do_reg_close(smb_cli, &parent_pol) : False; + + /* close the registry handles */ + res = res ? do_reg_close(smb_cli, &info->dom.reg_pol_connect) : False; + + /* close the session */ + cli_nt_session_close(smb_cli); + + if (res && res3 && res4) + { + DEBUG(5,("cmd_reg_create_val: query succeeded\n")); + fprintf(out_hnd,"OK\n"); + } + else + { + DEBUG(5,("cmd_reg_create_val: query failed\n")); + } +} + +/**************************************************************************** +nt registry create key +****************************************************************************/ +void cmd_reg_create_key(struct client_info *info) +{ + BOOL res = True; + BOOL res3 = True; + BOOL res4 = True; + + POLICY_HND parent_pol; + POLICY_HND key_pol; + fstring parent_name; + fstring key_name; + fstring key_class; + SEC_INFO sam_access; + +#if 0 + uint32 unk_0; + uint32 unk_1; + /* query it */ + res1 = res1 ? do_reg_query_info(smb_cli, &key_pol, + type, &unk_0, &unk_1) : False; +#endif + + DEBUG(5, ("cmd_reg_create_key: smb_cli->fd:%d\n", smb_cli->fd)); + + if (!next_token(NULL, parent_name, NULL, sizeof(parent_name))) + { + fprintf(out_hnd, "regcreate [key_class]\n"); + return; + } + + if (!next_token(NULL, key_name , NULL, sizeof(key_name ))) + { + fprintf(out_hnd, "regcreate [key_class]\n"); + return; + } + + if (!next_token(NULL, key_class, NULL, sizeof(key_class))) + { + memset(key_class, 0, sizeof(key_class)); + } + + /* set access permissions */ + sam_access.perms = SEC_RIGHTS_READ; + + /* open WINREG session. */ + res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False; + + /* open registry receive a policy handle */ + res = res ? do_reg_open_policy(smb_cli, + 0x84E0, 0x02000000, + &info->dom.reg_pol_connect) : False; + + /* open an entry */ + res3 = res ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect, + parent_name, 0x02000000, &parent_pol) : False; + + /* create an entry */ + res4 = res3 ? do_reg_create_key(smb_cli, &parent_pol, + key_name, key_class, &sam_access, &key_pol) : False; + + /* close the key handle */ + res4 = res4 ? do_reg_close(smb_cli, &key_pol) : False; + + /* close the key handle */ + res3 = res3 ? do_reg_close(smb_cli, &parent_pol) : False; + + /* close the registry handles */ + res = res ? do_reg_close(smb_cli, &info->dom.reg_pol_connect) : False; + + /* close the session */ + cli_nt_session_close(smb_cli); + + if (res && res3 && res4) + { + DEBUG(5,("cmd_reg_create_key: query succeeded\n")); + fprintf(out_hnd,"OK\n"); + } + else + { + DEBUG(5,("cmd_reg_create_key: query failed\n")); + } +} + /**************************************************************************** nt registry security info ****************************************************************************/ diff --git a/source3/rpcclient/display.c b/source3/rpcclient/display.c index f399b7fc03..e173ced009 100644 --- a/source3/rpcclient/display.c +++ b/source3/rpcclient/display.c @@ -977,12 +977,12 @@ void display_sam_user_info_21(FILE *out_hnd, enum action_type action, SAM_USER_I fprintf(out_hnd, "\t\tUnknown Str : %s\n", unistrn2(usr->uni_unknown_str .buffer, usr->uni_unknown_str .uni_str_len)); /* unknown string unicode string */ fprintf(out_hnd, "\t\tRemote Dial : %s\n", unistrn2(usr->uni_munged_dial .buffer, usr->uni_munged_dial .uni_str_len)); /* munged remote access unicode string */ - fprintf(out_hnd, "\t\tLogon Time : %s\n", http_timestring(interpret_nt_time(&(usr->logon_time )))); - fprintf(out_hnd, "\t\tLogoff Time : %s\n", http_timestring(interpret_nt_time(&(usr->logoff_time )))); - fprintf(out_hnd, "\t\tKickoff Time : %s\n", http_timestring(interpret_nt_time(&(usr->kickoff_time )))); - fprintf(out_hnd, "\t\tPassword last set Time : %s\n", http_timestring(interpret_nt_time(&(usr->pass_last_set_time )))); - fprintf(out_hnd, "\t\tPassword can change Time : %s\n", http_timestring(interpret_nt_time(&(usr->pass_can_change_time )))); - fprintf(out_hnd, "\t\tPassword must change Time: %s\n", http_timestring(interpret_nt_time(&(usr->pass_must_change_time)))); + fprintf(out_hnd, "\t\tLogon Time : %s\n", http_timestring(nt_time_to_unix(&(usr->logon_time )))); + fprintf(out_hnd, "\t\tLogoff Time : %s\n", http_timestring(nt_time_to_unix(&(usr->logoff_time )))); + fprintf(out_hnd, "\t\tKickoff Time : %s\n", http_timestring(nt_time_to_unix(&(usr->kickoff_time )))); + fprintf(out_hnd, "\t\tPassword last set Time : %s\n", http_timestring(nt_time_to_unix(&(usr->pass_last_set_time )))); + fprintf(out_hnd, "\t\tPassword can change Time : %s\n", http_timestring(nt_time_to_unix(&(usr->pass_can_change_time )))); + fprintf(out_hnd, "\t\tPassword must change Time: %s\n", http_timestring(nt_time_to_unix(&(usr->pass_must_change_time)))); fprintf(out_hnd, "\t\tunknown_2[0..31]...\n"); /* user passwords? */ @@ -1011,3 +1011,366 @@ void display_sam_user_info_21(FILE *out_hnd, enum action_type action, SAM_USER_I } } + +/**************************************************************************** +convert a security permissions into a string +****************************************************************************/ +char *get_sec_perms_str(uint32 type) +{ + static fstring typestr; + int i; + + switch (type) + { + case SEC_RIGHTS_FULL_CONTROL: + { + fstrcpy(typestr, "Full Control"); + return typestr; + } + + case SEC_RIGHTS_READ: + { + fstrcpy(typestr, "Read"); + return typestr; + } + default: + { + break; + } + } + + typestr[0] = 0; + for (i = 0; i < 32; i++) + { + if (IS_BITS_SET_ALL(type, 1 << i)) + { + switch (1 << i) + { + case SEC_RIGHTS_QUERY_VALUE : fstrcat(typestr, "Query " ); break; + case SEC_RIGHTS_SET_VALUE : fstrcat(typestr, "Set " ); break; + case SEC_RIGHTS_CREATE_SUBKEY : fstrcat(typestr, "Create "); break; + case SEC_RIGHTS_ENUM_SUBKEYS : fstrcat(typestr, "Enum "); break; + case SEC_RIGHTS_NOTIFY : fstrcat(typestr, "Notify "); break; + case SEC_RIGHTS_CREATE_LINK : fstrcat(typestr, "CreateLink "); break; + case SEC_RIGHTS_DELETE : fstrcat(typestr, "Delete "); break; + case SEC_RIGHTS_READ_CONTROL : fstrcat(typestr, "ReadControl "); break; + case SEC_RIGHTS_WRITE_DAC : fstrcat(typestr, "WriteDAC "); break; + case SEC_RIGHTS_WRITE_OWNER : fstrcat(typestr, "WriteOwner "); break; + } + type &= ~(1 << i); + } + } + + /* remaining bits get added on as-is */ + if (type != 0) + { + fstring tmp; + snprintf(tmp, sizeof(tmp), "[%08x]", type); + fstrcat(typestr, tmp); + } + + /* remove last space */ + i = strlen(typestr)-1; + if (typestr[i] == ' ') typestr[i] = 0; + + return typestr; +} + +/**************************************************************************** + display sec_info structure + ****************************************************************************/ +void display_sec_info(FILE *out_hnd, enum action_type action, SEC_INFO *info) +{ + switch (action) + { + case ACTION_HEADER: + { + break; + } + case ACTION_ENUMERATE: + { + fprintf(out_hnd, "\t\tPermissions: %s\n", + get_sec_perms_str(info->perms)); + } + case ACTION_FOOTER: + { + break; + } + } +} + +/**************************************************************************** + display sec_ace structure + ****************************************************************************/ +void display_sec_ace(FILE *out_hnd, enum action_type action, SEC_ACE *ace) +{ + switch (action) + { + case ACTION_HEADER: + { + fprintf(out_hnd, "\tACE\n"); + break; + } + case ACTION_ENUMERATE: + { + fstring sid_str; + + display_sec_info(out_hnd, ACTION_HEADER , &ace->info); + display_sec_info(out_hnd, ACTION_ENUMERATE, &ace->info); + display_sec_info(out_hnd, ACTION_FOOTER , &ace->info); + + sid_to_string(sid_str, &ace->sid); + fprintf(out_hnd, "\t\tSID: %s\n", sid_str); + } + case ACTION_FOOTER: + { + break; + } + } +} + +/**************************************************************************** + display sec_acl structure + ****************************************************************************/ +void display_sec_acl(FILE *out_hnd, enum action_type action, SEC_ACL *acl) +{ + switch (action) + { + case ACTION_HEADER: + { + fprintf(out_hnd, "\tACL\tNum ACEs: %d\tunk 1: %x\n", acl->num_aces, acl->unknown_1); + fprintf(out_hnd, "\t---\n"); + + break; + } + case ACTION_ENUMERATE: + { + if (acl->acl_size != 0 && acl->num_aces != 0) + { + int i; + for (i = 0; i < acl->num_aces; i++) + { + display_sec_ace(out_hnd, ACTION_HEADER , &acl->ace[i]); + display_sec_ace(out_hnd, ACTION_ENUMERATE, &acl->ace[i]); + display_sec_ace(out_hnd, ACTION_FOOTER , &acl->ace[i]); + } + } + + break; + } + case ACTION_FOOTER: + { + fprintf(out_hnd, "\n"); + break; + } + } +} + +/**************************************************************************** + display sec_desc structure + ****************************************************************************/ +void display_sec_desc(FILE *out_hnd, enum action_type action, SEC_DESC *sec) +{ + switch (action) + { + case ACTION_HEADER: + { + fprintf(out_hnd, "\tSecurity Descriptor\tunk 1,2: %x %x\n", sec->unknown_1, sec->unknown_2); + fprintf(out_hnd, "\t-------------------\n"); + + break; + } + case ACTION_ENUMERATE: + { + fstring sid_str; + + if (sec->off_acl != 0) + { + display_sec_acl(out_hnd, ACTION_HEADER , &sec->acl); + display_sec_acl(out_hnd, ACTION_ENUMERATE, &sec->acl); + display_sec_acl(out_hnd, ACTION_FOOTER , &sec->acl); + } + if (sec->off_owner_sid != 0) + { + sid_to_string(sid_str, &sec->owner_sid); + fprintf(out_hnd, "\tOwner SID: %s\n", sid_str); + } + if (sec->off_pnt_sid != 0) + { + sid_to_string(sid_str, &sec->parent_sid); + fprintf(out_hnd, "\tParent SID: %s\n", sid_str); + } + + break; + } + case ACTION_FOOTER: + { + fprintf(out_hnd, "\n"); + break; + } + } +} + +/**************************************************************************** +convert a security permissions into a string +****************************************************************************/ +char *get_reg_val_type_str(uint32 type) +{ + static fstring typestr; + + switch (type) + { + case 0x01: + { + fstrcpy(typestr, "string"); + return typestr; + } + + case 0x03: + { + fstrcpy(typestr, "bytes"); + return typestr; + } + + case 0x04: + { + fstrcpy(typestr, "uint32"); + return typestr; + } + + case 0x07: + { + fstrcpy(typestr, "multi"); + return typestr; + } + default: + { + snprintf(typestr, sizeof(typestr), "[%d]", type); + return typestr; + break; + } + } + return typestr; +} + + +static void print_reg_value(FILE *out_hnd, char *val_name, uint32 val_type, BUFFER2 *value) +{ + fstring type; + fstrcpy(type, get_reg_val_type_str(val_type)); + + switch (val_type) + { + case 0x01: /* unistr */ + { + fprintf(out_hnd,"\t%s:\t%s:\t%s\n", val_name, type, buffer2_to_str(value)); + break; + } + + default: /* unknown */ + case 0x03: /* bytes */ + { + if (value->buf_len <= 8) + { + fprintf(out_hnd,"\t%s:\t%s:\t", val_name, type); + out_data(out_hnd, (char*)value->buffer, value->buf_len, 8); + } + else + { + fprintf(out_hnd,"\t%s:\t%s:\n", val_name, type); + out_data(out_hnd, (char*)value->buffer, value->buf_len, 16); + } + break; + } + + case 0x04: /* uint32 */ + { + fprintf(out_hnd,"\t%s:\t%s: 0x%08x\n", val_name, type, buffer2_to_uint32(value)); + break; + } + + case 0x07: /* multiunistr */ + { + fprintf(out_hnd,"\t%s:\t%s:\t%s\n", val_name, type, buffer2_to_multistr(value)); + break; + } + } +} + +/**************************************************************************** + display structure + ****************************************************************************/ +void display_reg_value_info(FILE *out_hnd, enum action_type action, + char *val_name, uint32 val_type, BUFFER2 *value) +{ + switch (action) + { + case ACTION_HEADER: + { + break; + } + case ACTION_ENUMERATE: + { + print_reg_value(out_hnd, val_name, val_type, value); + break; + } + case ACTION_FOOTER: + { + break; + } + } +} + +/**************************************************************************** + display structure + ****************************************************************************/ +void display_reg_key_info(FILE *out_hnd, enum action_type action, + char *key_name, time_t key_mod_time) +{ + switch (action) + { + case ACTION_HEADER: + { + break; + } + case ACTION_ENUMERATE: + { + fprintf(out_hnd, "\t%s\t(%s)\n", + key_name, http_timestring(key_mod_time)); + break; + } + case ACTION_FOOTER: + { + break; + } + } +} + +#if COPY_THIS_TEMPLATE +/**************************************************************************** + display structure + ****************************************************************************/ + void display_(FILE *out_hnd, enum action_type action, *) +{ + switch (action) + { + case ACTION_HEADER: + { + fprintf(out_hnd, "\t\n"); + fprintf(out_hnd, "\t-------------------\n"); + + break; + } + case ACTION_ENUMERATE: + { + break; + } + case ACTION_FOOTER: + { + fprintf(out_hnd, "\n"); + break; + } + } +} + +#endif diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index ba7f7d0180..017183fa1d 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -29,13 +29,13 @@ #define REGISTER 0 #endif +extern pstring debugf; extern pstring scope; extern pstring global_myname; extern pstring user_socket_options; -extern pstring debugf; extern int DEBUGLEVEL; @@ -105,6 +105,12 @@ struct char *description; } commands[] = { + {"regenum", cmd_reg_enum, " Registry Enumeration (keys, values)"}, + {"regcreatekey",cmd_reg_create_key, " [keyclass] Registry Key Create"}, + {"regquerykey",cmd_reg_query_key, " Registry Key Query"}, + {"regcreateval",cmd_reg_create_val, " Registry Key Create"}, + {"regtest2", cmd_reg_test2, "Registry Testing No 2"}, + {"reggetsec", cmd_reg_get_key_sec, " | Registry Key Security"}, {"ntlogin", cmd_netlogon_login_test, "[username] [password] NT Domain login test"}, {"wksinfo", cmd_wks_query_info, "Workstation Query Info"}, {"srvinfo", cmd_srv_query_info, "Server Query Info"}, @@ -386,7 +392,8 @@ enum client_action ****************************************************************************/ int main(int argc,char *argv[]) { - char *pname = argv[0]; + BOOL interactive = True; + int opt; extern FILE *dbf; extern char *optarg; @@ -404,6 +411,7 @@ enum client_action pstring password; /* local copy only, if one is entered */ out_hnd = stdout; + fstrcpy(debugf, argv[0]); rpcclient_init(); @@ -446,18 +454,15 @@ enum client_action pstrcpy(cli_info.share, ""); pstrcpy(cli_info.service, ""); - pstrcpy(cli_info.dom.level3_sid, ""); - pstrcpy(cli_info.dom.level3_dom, ""); - pstrcpy(cli_info.dom.level5_sid, ""); - pstrcpy(cli_info.dom.level5_dom, ""); + ZERO_STRUCT(cli_info.dom.level3_sid); + ZERO_STRUCT(cli_info.dom.level5_sid); + fstrcpy(cli_info.dom.level3_dom, ""); + fstrcpy(cli_info.dom.level5_dom, ""); smb_cli->nt_pipe_fnum = 0xffff; - setup_logging(pname, True); - TimeInit(); charset_initialise(); -/* crc32_build_table(); */ myumask = umask(0); umask(myumask); @@ -501,7 +506,7 @@ enum client_action if (argc < 2) { - usage(pname); + usage(argv[0]); exit(1); } @@ -514,11 +519,11 @@ enum client_action argc--; argv++; - DEBUG(1,("service: %s\n", cli_info.service)); + fprintf(out_hnd, "service: %s\n", cli_info.service); if (count_chars(cli_info.service,'\\') < 3) { - usage(pname); + usage(argv[0]); printf("\n%s: Not enough '\\' characters in service\n", cli_info.service); exit(1); } @@ -644,7 +649,8 @@ enum client_action case 'l': { slprintf(debugf, sizeof(debugf)-1, - "%s.client",optarg); + "%s.client", optarg); + interactive = False; break; } @@ -657,7 +663,7 @@ enum client_action case 'h': { - usage(pname); + usage(argv[0]); exit(0); break; } @@ -676,16 +682,18 @@ enum client_action default: { - usage(pname); + usage(argv[0]); exit(1); break; } } } + setup_logging(debugf, interactive); + if (cli_action == CLIENT_NONE) { - usage(pname); + usage(argv[0]); exit(1); } -- cgit