rpcclient registry commands.
authorLuke Leighton <lkcl@samba.org>
Tue, 10 Nov 1998 19:05:00 +0000 (19:05 +0000)
committerLuke Leighton <lkcl@samba.org>
Tue, 10 Nov 1998 19:05:00 +0000 (19:05 +0000)
(This used to be commit 36fcb4a6e643a05d06a2a273d74318fee7f2c647)

24 files changed:
source3/Makefile.in
source3/include/includes.h
source3/include/ntdomain.h
source3/include/proto.h
source3/include/rpc_dce.h
source3/include/rpc_lsa.h
source3/include/rpc_misc.h
source3/include/rpc_reg.h
source3/include/rpcclient.h
source3/include/smb.h
source3/lib/time.c
source3/lib/util_str.c
source3/lib/util_unistr.c
source3/lsarpcd/srv_lsa.c
source3/rpc_client/cli_reg.c
source3/rpc_parse/parse_lsa.c
source3/rpc_parse/parse_misc.c
source3/rpc_parse/parse_prs.c
source3/rpc_parse/parse_reg.c
source3/rpc_parse/parse_samr.c
source3/rpc_server/srv_lsa.c
source3/rpcclient/cmd_reg.c
source3/rpcclient/display.c
source3/rpcclient/rpcclient.c

index beb577839e851b27b51da428a65052a545e7db75..fee28ac8f4c481a192d3e4c3fddf7600e7473be5 100644 (file)
@@ -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) \
index 56ab47cecc41e1417c4517920b8a253372ce58b4..6c7a67afef223a1f5cf6e7d5f943f15613680076 100644 (file)
 #include <memory.h>
 #endif
 
+#ifdef MEM_MAN
+#include "../mem_man/mem_man.h"
+#else
 #ifdef HAVE_MALLOC_H
 #include <malloc.h>
 #endif
+#endif
 
 #ifdef HAVE_FCNTL_H
 #include <fcntl.h>
index 97122c8169ab8b295e38db0527c86d6f0c76742a..5b53834efe52dcb7bf9465cfeea24e92a8ce1d60 100644 (file)
@@ -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"
index ccbf919ebb844a6de3313a09343ea34a5d10adfa..143f397e0ad1ca51f0f3decc4e2f3f603c2effce 100644 (file)
@@ -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  */
 
index c6499853d6a53a8b7753fbd28407441d40853fc6..70eb1b4e204e6d7ed443a8d0817ca4b18951dde8 100644 (file)
@@ -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! */
index 44758936aeacd47e1172bc570138ebbfde61013e..b8aaa562f08e7fbcad3b425b9a0595c4439ef791 100644 (file)
 
 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;
index 50daf27dfc718c8868e14ce9638bf48a10f87d97..e984a4842b59fa4073ab86b8cac0d56b5846acbe 100644 (file)
@@ -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
index 28d11710cdfabc1b4b41fe8480b4f4723a90d731..93348108662d5dc3c99df759472a9a99f119765e 100644 (file)
 
 /* 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;
index 1065b7c159920ca33f92f3d5f31772314c14d438..eab4d2070330034221ab86e157d08cc95e441bea 100644 (file)
@@ -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  ********************/
 
index a6566fb3643b07a7c8739d3b6512591770cb0321..a8b0c745b2d32c6945d35ef9764d01313a619e23 100644 (file)
@@ -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"
index ea966541087800d6d941b6e50f387b6136b165fa..3cea1a3e14a08367f09f1ea314850a30e945a44c 100644 (file)
@@ -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
 ****************************************************************************/
index 7eb14943821b33ace594f67ce77852b400332697..15eefb00013745677eb84a0aa8fbbe0978b6f0ed 100644 (file)
@@ -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
 ****************************************************************************/
index 2365090f24e95630d34ff482ae2bbcf88edeb410..49fb729267047b3c03cb88927872d1e22766a2f8 100644 (file)
@@ -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.
index 8f22f8f5749ff1c6fa18ba038b6ccc3e098dd60b..5e6e101883c35a59700dd651bf0d5c872cc50842 100644 (file)
@@ -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;
index 2f04facffd8f3cfd9da759abe10519229b50d974..da92ab90bb867f8b5d8c52aa5c51b80d72eb9970 100644 (file)
@@ -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
 ****************************************************************************/
index cc60ace9fc97d7d9c04ff9e5b3998f7ffbaa49b8..a5c523fdb66e59cbc88bb1e32a5b7ac3697ed1e2 100644 (file)
@@ -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);
index 0f242c47384a08cc6a60a0cae2991fe50160a077..3a74d11e52c0958b93595950710f261cfe973990 100644 (file)
@@ -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);
 }
 
 
index d031a828f12140a4cce4a9199a310b15d0ca28c7..873a6897924339383cc3bf93006f16cacf291b86 100644 (file)
@@ -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;
+}
+
index 6b464645e51ba4f7b7db871a706f69b49fe9cc35..329da974fb45f2da4d72c7a3f3d00ccd50ff90e7 100644 (file)
 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));
 }
 
 
index ba6a8d355685eaa36a2cba9821d122ecb340b66a..ec4411b783b157bb312c0f2c6e539151029c19ad 100644 (file)
@@ -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;
index 8f22f8f5749ff1c6fa18ba038b6ccc3e098dd60b..5e6e101883c35a59700dd651bf0d5c872cc50842 100644 (file)
@@ -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;
index 399fb30603470c00a801ae126c63705de76f7951..48b6d385bb2c476456decea76f4b1fb9cde00c8e 100644 (file)
@@ -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 <parent val name> <val_name> <val_type> <val>\n");
+               return;
+       }
+
+       if (!next_token(NULL, val_name   , NULL, sizeof(val_name   )))
+       {
+               fprintf(out_hnd, "regcreate <parent val name> <val_name> <val_type> <val>\n");
+               return;
+       }
+
+       if (!next_token(NULL, tmp, NULL, sizeof(tmp)))
+       {
+               fprintf(out_hnd, "regcreate <parent val name> <val_name> <val_type (1|4)> <val>\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 <parent val name> <val_name> <val_type (1|4)> <val>\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 <parent key name> <key_name> [key_class]\n");
+               return;
+       }
+
+       if (!next_token(NULL, key_name   , NULL, sizeof(key_name   )))
+       {
+               fprintf(out_hnd, "regcreate <parent key name> <key_name> [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
 ****************************************************************************/
index f399b7fc031aebce7ebda8491467413ac39a2174..e173ced009b8bc84efca903ff172a9e82c7465da 100644 (file)
@@ -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
index ba7f7d01807ee3a7e6ca29013df32fc84eff29b8..017183fa1d7dba3a7f76d46da7141f6f95381bb9 100644 (file)
 #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,         "<keyname> Registry Enumeration (keys, values)"},
+  {"regcreatekey",cmd_reg_create_key,  "<parentname> <keyname> [keyclass] Registry Key Create"},
+  {"regquerykey",cmd_reg_query_key,    "<keyname> Registry Key Query"},
+  {"regcreateval",cmd_reg_create_val,  "<parentname> <valname> <valtype> <value> Registry Key Create"},
+  {"regtest2",   cmd_reg_test2,        "Registry Testing No 2"},
+  {"reggetsec",  cmd_reg_get_key_sec,  "<keyname> | <valname> 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);
        }