he is happy with me reverting the RPC change.
The reason I need this code in the 2.0 branch (even though it doesn't
work correctly) is I am using it as a stable area that no-one cares
about (as it doesn't work) to write the fully error checked version
of the RPC transport and parsing code.
Having it removed caused me a few problems :-).
Jeremy.
SPROGS = bin/smbd bin/nmbd bin/swat
PROGS1 = bin/smbclient bin/testparm bin/testprns bin/smbstatus @RUNPROG@
-PROGS2 = bin/smbpasswd bin/make_smbcodepage @WRAP@ @WRAP32@
+PROGS2 = bin/rpcclient bin/smbpasswd bin/make_smbcodepage @WRAP@ @WRAP32@
MPROGS = @MPROGS@
PROGS = $(PROGS1) $(PROGS2) $(MPROGS) bin/nmblookup bin/make_printerdef
RPC_SERVER_OBJ = rpc_server/srv_lsa.o \
rpc_server/srv_lsa_hnd.o rpc_server/srv_netlog.o \
- rpc_server/srv_pipe_hnd.o \
- rpc_server/srv_srvsvc.o \
- rpc_server/srv_wkssvc.o \
- rpc_server/srv_util.o \
+ rpc_server/srv_pipe_hnd.o rpc_server/srv_reg.o \
+ rpc_server/srv_samr.o rpc_server/srv_srvsvc.o \
+ rpc_server/srv_util.o rpc_server/srv_wkssvc.o \
rpc_server/srv_pipe.o
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_rpc.o \
- rpc_parse/parse_srv.o rpc_parse/parse_wks.o \
- rpc_parse/parse_sec.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_sec.o
RPC_CLIENT_OBJ = \
rpc_client/cli_login.o \
rpc_client/cli_netlogon.o \
rpc_client/cli_pipe.o \
- rpc_client/cli_lsarpc.o
+ 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
LOCKING_OBJ = locking/locking.o locking/locking_shm.o locking/locking_slow.o \
SMBPASSWD_OBJ = utils/smbpasswd.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(PASSDB_OBJ) \
$(UBIQX_OBJ) $(RPC_CLIENT_OBJ) $(RPC_PARSE_OBJ) $(LIB_OBJ)
+RPCCLIENT_OBJ = rpcclient/rpcclient.o \
+ rpcclient/display.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) \
+ $(RPC_CLIENT_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_OBJ)
+
SMBWRAPPER_OBJ = smbwrapper/smbw.o smbwrapper/wrapped.o \
smbwrapper/smbw_dir.o smbwrapper/smbw_stat.o \
smbwrapper/realcalls.o smbwrapper/shared.o \
SMBTORTURE_OBJ = utils/torture.o $(LIBSMB_OBJ) $(PARAM_OBJ) \
$(UBIQX_OBJ) $(LIB_OBJ)
+RPCTORTURE_OBJ = utils/rpctorture.o \
+ rpcclient/display.o \
+ rpcclient/cmd_lsarpc.o \
+ rpcclient/cmd_wkssvc.o \
+ rpcclient/cmd_samr.o \
+ rpcclient/cmd_srvsvc.o \
+ rpcclient/cmd_netlogon.o \
+ $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \
+ $(RPC_CLIENT_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_OBJ)
+
DEBUG2HTML_OBJ = utils/debug2html.o ubiqx/debugparse.o
PROTO_OBJ = $(SMBD_OBJ) $(NMBD_OBJ) $(SWAT_OBJ) $(CLIENT_OBJ) \
@echo Linking $@
@$(CC) $(FLAGS) -o $@ $(SMBRUN_OBJ) $(LDFLAGS) $(LIBS)
+bin/rpcclient: $(RPCCLIENT_OBJ) bin/.dummy
+ @echo Linking $@
+ @$(CC) $(FLAGS) -o $@ $(RPCCLIENT_OBJ) $(LDFLAGS) $(LIBS)
+
bin/smbclient: $(CLIENT_OBJ) bin/.dummy
@echo Linking $@
@$(CC) $(FLAGS) -o $@ $(CLIENT_OBJ) $(LDFLAGS) $(LIBS)
@echo Linking $@
@$(CC) $(FLAGS) -o $@ $(SMBTORTURE_OBJ) $(LDFLAGS) $(LIBS)
+bin/rpctorture: $(RPCTORTURE_OBJ) bin/.dummy
+ @echo Linking $@
+ @$(CC) $(FLAGS) -o $@ $(RPCTORTURE_OBJ) $(LDFLAGS) $(LIBS)
+
bin/debug2html: $(DEBUG2HTML_OBJ) bin/.dummy
@echo Linking $@
@$(CC) $(FLAGS) -o $@ $(DEBUG2HTML_OBJ) $(LDFLAGS) $(LIBS)
int str_checksum(const char *s);
void zero_free(void *p, size_t size);
int set_maxfiles(int requested_max);
+void reg_get_subkey(char *full_keyname, char *key_name, char *subkey_name);
+BOOL reg_split_key(char *full_keyname, uint32 *reg_type, char *key_name);
/*The following definitions come from lib/util_file.c */
BOOL do_lsa_open_policy(struct cli_state *cli,
char *server_name, POLICY_HND *hnd,
BOOL sec_qos);
+BOOL do_lsa_lookup_sids(struct cli_state *cli,
+ POLICY_HND *hnd,
+ int num_sids,
+ DOM_SID **sids,
+ char ***names,
+ int *num_names);
BOOL do_lsa_query_info_pol(struct cli_state *cli,
POLICY_HND *hnd, uint16 info_class,
fstring domain_name, DOM_SID *domain_sid);
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_connect(struct cli_state *cli, char *full_keyname, char *key_name,
+ POLICY_HND *reg_hnd);
+BOOL do_reg_open_hklm(struct cli_state *cli, uint16 unknown_0, uint32 level,
+ POLICY_HND *hnd);
+BOOL do_reg_open_hku(struct cli_state *cli, uint16 unknown_0, uint32 level,
+ POLICY_HND *hnd);
+BOOL do_reg_flush_key(struct cli_state *cli, 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_set_key_sec(struct cli_state *cli, POLICY_HND *hnd, SEC_DESC_BUF *sec_desc_buf);
+BOOL do_reg_get_key_sec(struct cli_state *cli, POLICY_HND *hnd, uint32 *sec_buf_size, SEC_DESC_BUF **ppsec_desc_buf);
+BOOL do_reg_delete_val(struct cli_state *cli, POLICY_HND *hnd, char *val_name);
+BOOL do_reg_delete_key(struct cli_state *cli, POLICY_HND *hnd, char *key_name);
+BOOL do_reg_create_key(struct cli_state *cli, POLICY_HND *hnd,
+ char *key_name, char *key_class,
+ SEC_ACCESS *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,
+ POLICY_HND *pol_open_domain, uint32 user_rid,
+ uint32 *num_groups, DOM_GID *gid);
+BOOL get_samr_query_userinfo(struct cli_state *cli,
+ POLICY_HND *pol_open_domain,
+ uint32 info_level,
+ uint32 user_rid, SAM_USER_INFO_21 *usr);
+BOOL do_samr_chgpasswd_user(struct cli_state *cli,
+ char *srv_name, char *user_name,
+ char nt_newpass[516], uchar nt_oldhash[16],
+ char lm_newpass[516], uchar lm_oldhash[16]);
+BOOL do_samr_unknown_38(struct cli_state *cli, char *srv_name);
+BOOL do_samr_query_dom_info(struct cli_state *cli,
+ POLICY_HND *domain_pol, uint16 switch_value);
+BOOL do_samr_enum_dom_users(struct cli_state *cli,
+ POLICY_HND *pol, uint16 num_entries, uint16 unk_0,
+ uint16 acb_mask, uint16 unk_1, uint32 size,
+ struct acct_info **sam,
+ int *num_sam_users);
+BOOL do_samr_connect(struct cli_state *cli,
+ char *srv_name, uint32 unknown_0,
+ POLICY_HND *connect_pol);
+BOOL do_samr_open_user(struct cli_state *cli,
+ POLICY_HND *pol, uint32 unk_0, uint32 rid,
+ POLICY_HND *user_pol);
+BOOL do_samr_open_domain(struct cli_state *cli,
+ POLICY_HND *connect_pol, uint32 rid, DOM_SID *sid,
+ POLICY_HND *domain_pol);
+BOOL do_samr_query_unknown_12(struct cli_state *cli,
+ POLICY_HND *pol, uint32 rid, uint32 num_gids, uint32 *gids,
+ uint32 *num_aliases,
+ fstring als_names [MAX_LOOKUP_SIDS],
+ uint32 num_als_users[MAX_LOOKUP_SIDS]);
+BOOL do_samr_query_usergroups(struct cli_state *cli,
+ POLICY_HND *pol, uint32 *num_groups, DOM_GID *gid);
+BOOL do_samr_query_userinfo(struct cli_state *cli,
+ POLICY_HND *pol, uint16 switch_value, void* usr);
+BOOL do_samr_close(struct cli_state *cli, POLICY_HND *hnd);
+
+/*The following definitions come from rpc_client/cli_srvsvc.c */
+
+BOOL do_srv_net_srv_conn_enum(struct cli_state *cli,
+ char *server_name, char *qual_name,
+ uint32 switch_value, SRV_CONN_INFO_CTR *ctr,
+ uint32 preferred_len,
+ ENUM_HND *hnd);
+BOOL do_srv_net_srv_sess_enum(struct cli_state *cli,
+ char *server_name, char *qual_name,
+ uint32 switch_value, SRV_SESS_INFO_CTR *ctr,
+ uint32 preferred_len,
+ ENUM_HND *hnd);
+BOOL do_srv_net_srv_share_enum(struct cli_state *cli,
+ char *server_name,
+ uint32 switch_value, SRV_SHARE_INFO_CTR *ctr,
+ uint32 preferred_len,
+ ENUM_HND *hnd);
+BOOL do_srv_net_srv_file_enum(struct cli_state *cli,
+ char *server_name, char *qual_name,
+ uint32 switch_value, SRV_FILE_INFO_CTR *ctr,
+ uint32 preferred_len,
+ ENUM_HND *hnd);
+BOOL do_srv_net_srv_get_info(struct cli_state *cli,
+ char *server_name, uint32 switch_value, SRV_INFO_CTR *ctr);
+
+/*The following definitions come from rpc_client/cli_wkssvc.c */
+
+BOOL do_wks_query_info(struct cli_state *cli,
+ char *server_name, uint32 switch_value,
+ WKS_INFO_100 *wks100);
+
/*The following definitions come from rpc_parse/parse_lsa.c */
+void make_lsa_trans_name(LSA_TRANS_NAME *trn, UNISTR2 *uni_name,
+ uint32 sid_name_use, char *name, uint32 idx);
void make_lsa_sec_qos(LSA_SEC_QOS *qos, uint16 imp_lev, uint8 ctxt, uint8 eff,
uint32 unknown);
void make_lsa_obj_attr(LSA_OBJ_ATTR *attr, uint32 attributes, LSA_SEC_QOS *qos);
uint32 status);
void lsa_io_r_enum_trust_dom(char *desc, LSA_R_ENUM_TRUST_DOM *r_e, prs_struct *ps, int depth);
void lsa_io_r_query(char *desc, LSA_R_QUERY_INFO *r_q, prs_struct *ps, int depth);
+void make_lsa_sid_enum(LSA_SID_ENUM *sen, int num_entries, DOM_SID **sids);
+void make_q_lookup_sids(LSA_Q_LOOKUP_SIDS *q_l, POLICY_HND *hnd,
+ int num_sids, DOM_SID **sids,
+ uint16 level);
+void lsa_io_q_lookup_sids(char *desc, LSA_Q_LOOKUP_SIDS *q_s, prs_struct *ps, int depth);
+void lsa_io_r_lookup_sids(char *desc, LSA_R_LOOKUP_SIDS *r_s, prs_struct *ps, int depth);
+void lsa_io_q_lookup_rids(char *desc, LSA_Q_LOOKUP_RIDS *q_r, prs_struct *ps, int depth);
+void lsa_io_r_lookup_rids(char *desc, LSA_R_LOOKUP_RIDS *r_r, prs_struct *ps, int depth);
void make_lsa_q_close(LSA_Q_CLOSE *q_c, POLICY_HND *hnd);
void lsa_io_q_close(char *desc, LSA_Q_CLOSE *q_c, prs_struct *ps, int depth);
void lsa_io_r_close(char *desc, LSA_R_CLOSE *r_c, prs_struct *ps, int depth);
BOOL prs_uint32_post(char *name, prs_struct *ps, int depth, uint32 *data32,
uint32 ptr_uint32, uint32 data_size);
+/*The following definitions come from rpc_parse/parse_reg.c */
+
+void make_reg_q_open_hklm(REG_Q_OPEN_HKLM *q_o,
+ uint16 unknown_0, uint32 level);
+void reg_io_q_open_hklm(char *desc, REG_Q_OPEN_HKLM *r_q, prs_struct *ps, int depth);
+void reg_io_r_open_hklm(char *desc, REG_R_OPEN_HKLM *r_r, prs_struct *ps, int depth);
+void make_reg_q_flush_key(REG_Q_FLUSH_KEY *q_u, POLICY_HND *pol);
+void reg_io_q_flush_key(char *desc, REG_Q_FLUSH_KEY *r_q, prs_struct *ps, int depth);
+void reg_io_r_flush_key(char *desc, REG_R_FLUSH_KEY *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_ACCESS *sam_access,
+ SEC_DESC_BUF *sec_buf);
+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_delete_val(REG_Q_DELETE_VALUE *q_c, POLICY_HND *hnd,
+ char *name);
+void reg_io_q_delete_val(char *desc, REG_Q_DELETE_VALUE *r_q, prs_struct *ps, int depth);
+void reg_io_r_delete_val(char *desc, REG_R_DELETE_VALUE *r_r, prs_struct *ps, int depth);
+void make_reg_q_delete_key(REG_Q_DELETE_KEY *q_c, POLICY_HND *hnd,
+ char *name);
+void reg_io_q_delete_key(char *desc, REG_Q_DELETE_KEY *r_q, prs_struct *ps, int depth);
+void reg_io_r_delete_key(char *desc, REG_R_DELETE_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_hku(REG_Q_OPEN_HKU *q_o,
+ uint16 unknown_0, uint32 level);
+void reg_io_q_open_hku(char *desc, REG_Q_OPEN_HKU *r_q, prs_struct *ps, int depth);
+void reg_io_r_open_hku(char *desc, REG_R_OPEN_HKU *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_set_key_sec(REG_Q_SET_KEY_SEC *q_i, POLICY_HND *pol, SEC_DESC_BUF *sec_desc_buf);
+void reg_io_q_set_key_sec(char *desc, REG_Q_SET_KEY_SEC *r_q, prs_struct *ps, int depth);
+void reg_io_r_set_key_sec(char *desc, REG_R_SET_KEY_SEC *r_q, prs_struct *ps, int depth);
+void make_reg_q_get_key_sec(REG_Q_GET_KEY_SEC *q_i, POLICY_HND *pol,
+ uint32 sec_buf_size, SEC_DESC_BUF *psdb);
+void reg_io_q_get_key_sec(char *desc, REG_Q_GET_KEY_SEC *r_q, prs_struct *ps, int depth);
+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 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);
+void reg_io_r_open_entry(char *desc, REG_R_OPEN_ENTRY *r_r, prs_struct *ps, int depth);
+
/*The following definitions come from rpc_parse/parse_rpc.c */
void make_rpc_hdr(RPC_HDR *hdr, enum RPC_PKT_TYPE pkt_type, uint8 flags,
uint32 ver, uint32 crc32, uint32 seq_num);
void smb_io_rpc_auth_ntlmssp_chk(char *desc, RPC_AUTH_NTLMSSP_CHK *chk, prs_struct *ps, int depth);
+/*The following definitions come from rpc_parse/parse_samr.c */
+
+void make_samr_q_close_hnd(SAMR_Q_CLOSE_HND *q_c, POLICY_HND *hnd);
+void samr_io_q_close_hnd(char *desc, SAMR_Q_CLOSE_HND *q_u, prs_struct *ps, int depth);
+void samr_io_r_close_hnd(char *desc, SAMR_R_CLOSE_HND *r_u, prs_struct *ps, int depth);
+void make_samr_q_open_domain(SAMR_Q_OPEN_DOMAIN *q_u,
+ POLICY_HND *connect_pol, uint32 rid,
+ DOM_SID *sid);
+void samr_io_q_open_domain(char *desc, SAMR_Q_OPEN_DOMAIN *q_u, prs_struct *ps, int depth);
+void samr_io_r_open_domain(char *desc, SAMR_R_OPEN_DOMAIN *r_u, prs_struct *ps, int depth);
+void make_samr_q_unknown_2c(SAMR_Q_UNKNOWN_2C *q_u, POLICY_HND *user_pol);
+void samr_io_q_unknown_2c(char *desc, SAMR_Q_UNKNOWN_2C *q_u, prs_struct *ps, int depth);
+void make_samr_r_unknown_2c(SAMR_R_UNKNOWN_2C *q_u, uint32 status);
+void samr_io_r_unknown_2c(char *desc, SAMR_R_UNKNOWN_2C *r_u, prs_struct *ps, int depth);
+void make_samr_q_unknown_3(SAMR_Q_UNKNOWN_3 *q_u,
+ POLICY_HND *user_pol, uint16 switch_value);
+void samr_io_q_unknown_3(char *desc, SAMR_Q_UNKNOWN_3 *q_u, prs_struct *ps, int depth);
+void make_samr_q_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u,
+ POLICY_HND *domain_pol, uint16 switch_value);
+void samr_io_q_query_dom_info(char *desc, SAMR_Q_QUERY_DOMAIN_INFO *q_u, prs_struct *ps, int depth);
+void make_unk_info2(SAM_UNK_INFO_2 *u_2, char *domain, char *server);
+void sam_io_unk_info2(char *desc, SAM_UNK_INFO_2 *u_2, prs_struct *ps, int depth);
+void make_samr_r_query_dom_info(SAMR_R_QUERY_DOMAIN_INFO *r_u,
+ uint16 switch_value, SAM_UNK_CTR *ctr,
+ uint32 status);
+void samr_io_r_query_dom_info(char *desc, SAMR_R_QUERY_DOMAIN_INFO *r_u, prs_struct *ps, int depth);
+void make_dom_sid3(DOM_SID3 *sid3, uint16 unk_0, uint16 unk_1, DOM_SID *sid);
+void make_samr_r_unknown_3(SAMR_R_UNKNOWN_3 *r_u,
+ uint16 unknown_2, uint16 unknown_3,
+ uint32 unknown_4, uint16 unknown_6, uint16 unknown_7,
+ int num_sid3s, DOM_SID3 sid3[MAX_SAM_SIDS],
+ uint32 status);
+void samr_io_r_unknown_3(char *desc, SAMR_R_UNKNOWN_3 *r_u, prs_struct *ps, int depth);
+void make_samr_q_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_e, POLICY_HND *pol,
+ uint16 req_num_entries, uint16 unk_0,
+ uint16 acb_mask, uint16 unk_1, uint32 size);
+void samr_io_q_enum_dom_users(char *desc, SAMR_Q_ENUM_DOM_USERS *q_e, prs_struct *ps, int depth);
+void make_samr_r_enum_dom_users(SAMR_R_ENUM_DOM_USERS *r_u,
+ uint16 total_num_entries, uint16 unk_0,
+ uint32 num_sam_entries, SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES], uint32 status);
+void samr_io_r_enum_dom_users(char *desc, SAMR_R_ENUM_DOM_USERS *r_u, prs_struct *ps, int depth);
+void make_samr_q_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES *q_e, POLICY_HND *pol, uint32 size);
+void samr_io_q_enum_dom_aliases(char *desc, SAMR_Q_ENUM_DOM_ALIASES *q_e, prs_struct *ps, int depth);
+void make_samr_r_enum_dom_aliases(SAMR_R_ENUM_DOM_ALIASES *r_u,
+ uint32 num_sam_entries, SAM_USER_INFO_21 grps[MAX_SAM_ENTRIES],
+ uint32 status);
+void samr_io_r_enum_dom_aliases(char *desc, SAMR_R_ENUM_DOM_ALIASES *r_u, prs_struct *ps, int depth);
+void make_samr_q_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_e, POLICY_HND *pol,
+ uint16 switch_level, uint32 start_idx, uint32 size);
+void samr_io_q_query_dispinfo(char *desc, SAMR_Q_QUERY_DISPINFO *q_e, prs_struct *ps, int depth);
+void make_sam_info_2(SAM_INFO_2 *sam, uint32 acb_mask,
+ uint32 start_idx, uint32 num_sam_entries,
+ SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES]);
+void make_sam_info_1(SAM_INFO_1 *sam, uint32 acb_mask,
+ uint32 start_idx, uint32 num_sam_entries,
+ SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES]);
+void make_samr_r_query_dispinfo(SAMR_R_QUERY_DISPINFO *r_u,
+ uint16 switch_level, SAM_INFO_CTR *ctr, uint32 status);
+void samr_io_r_query_dispinfo(char *desc, SAMR_R_QUERY_DISPINFO *r_u, prs_struct *ps, int depth);
+void make_samr_q_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_e, POLICY_HND *pol,
+ uint16 switch_level, uint32 start_idx, uint32 size);
+void samr_io_q_enum_dom_groups(char *desc, SAMR_Q_ENUM_DOM_GROUPS *q_e, prs_struct *ps, int depth);
+void make_samr_r_enum_dom_groups(SAMR_R_ENUM_DOM_GROUPS *r_u,
+ uint32 start_idx, uint32 num_sam_entries,
+ SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES],
+ uint32 status);
+void samr_io_r_enum_dom_groups(char *desc, SAMR_R_ENUM_DOM_GROUPS *r_u, prs_struct *ps, int depth);
+void make_samr_q_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_e,
+ POLICY_HND *pol,
+ uint16 switch_level);
+void samr_io_q_query_aliasinfo(char *desc, SAMR_Q_QUERY_ALIASINFO *q_e, prs_struct *ps, int depth);
+void make_samr_r_query_aliasinfo(SAMR_R_QUERY_ALIASINFO *r_u,
+ uint16 switch_value, char *acct_desc,
+ uint32 status);
+void samr_io_r_query_aliasinfo(char *desc, SAMR_R_QUERY_ALIASINFO *r_u, prs_struct *ps, int depth);
+void samr_io_q_lookup_ids(char *desc, SAMR_Q_LOOKUP_IDS *q_u, prs_struct *ps, int depth);
+void make_samr_r_lookup_ids(SAMR_R_LOOKUP_IDS *r_u,
+ uint32 num_rids, uint32 *rid, uint32 status);
+void samr_io_r_lookup_ids(char *desc, SAMR_R_LOOKUP_IDS *r_u, prs_struct *ps, int depth);
+void samr_io_q_lookup_names(char *desc, SAMR_Q_LOOKUP_NAMES *q_u, prs_struct *ps, int depth);
+void make_samr_r_lookup_names(SAMR_R_LOOKUP_NAMES *r_u,
+ uint32 num_rids, uint32 *rid, uint32 status);
+void samr_io_r_lookup_names(char *desc, SAMR_R_LOOKUP_NAMES *r_u, prs_struct *ps, int depth);
+void samr_io_q_unknown_12(char *desc, SAMR_Q_UNKNOWN_12 *q_u, prs_struct *ps, int depth);
+void make_samr_r_unknown_12(SAMR_R_UNKNOWN_12 *r_u,
+ uint32 num_aliases, fstring *als_name, uint32 *num_als_usrs,
+ uint32 status);
+void samr_io_r_unknown_12(char *desc, SAMR_R_UNKNOWN_12 *r_u, prs_struct *ps, int depth);
+void make_samr_q_open_user(SAMR_Q_OPEN_USER *q_u,
+ POLICY_HND *pol,
+ uint32 unk_0, uint32 rid);
+void samr_io_q_open_user(char *desc, SAMR_Q_OPEN_USER *q_u, prs_struct *ps, int depth);
+void samr_io_r_open_user(char *desc, SAMR_R_OPEN_USER *r_u, prs_struct *ps, int depth);
+void make_samr_q_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
+ POLICY_HND *hnd);
+void samr_io_q_query_usergroups(char *desc, SAMR_Q_QUERY_USERGROUPS *q_u, prs_struct *ps, int depth);
+void make_samr_r_query_usergroups(SAMR_R_QUERY_USERGROUPS *r_u,
+ uint32 num_gids, DOM_GID *gid, uint32 status);
+void samr_io_r_query_usergroups(char *desc, SAMR_R_QUERY_USERGROUPS *r_u, prs_struct *ps, int depth);
+void make_samr_q_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
+ POLICY_HND *hnd, uint16 switch_value);
+void samr_io_q_query_userinfo(char *desc, SAMR_Q_QUERY_USERINFO *q_u, prs_struct *ps, int depth);
+void make_sam_user_info10(SAM_USER_INFO_10 *usr,
+ uint32 acb_info);
+void sam_io_user_info10(char *desc, SAM_USER_INFO_10 *usr, prs_struct *ps, int depth);
+void make_sam_user_info11(SAM_USER_INFO_11 *usr,
+ NTTIME *expiry,
+ char *mach_acct,
+ uint32 rid_user,
+ uint32 rid_group,
+ uint16 acct_ctrl);
+void sam_io_user_info11(char *desc, SAM_USER_INFO_11 *usr, prs_struct *ps, int depth);
+void make_sam_user_info21(SAM_USER_INFO_21 *usr,
+
+ NTTIME *logon_time,
+ NTTIME *logoff_time,
+ NTTIME *kickoff_time,
+ NTTIME *pass_last_set_time,
+ NTTIME *pass_can_change_time,
+ NTTIME *pass_must_change_time,
+
+ char *user_name,
+ char *full_name,
+ char *home_dir,
+ char *dir_drive,
+ char *logon_script,
+ char *profile_path,
+ char *description,
+ char *workstations,
+ char *unknown_str,
+ char *munged_dial,
+
+ uint32 user_rid,
+ uint32 group_rid,
+ uint16 acb_info,
+
+ uint32 unknown_3,
+ uint16 logon_divs,
+ LOGON_HRS *hrs,
+ uint32 unknown_5,
+ uint32 unknown_6);
+void make_samr_r_query_userinfo(SAMR_R_QUERY_USERINFO *r_u,
+ uint16 switch_value, void *info, uint32 status);
+void samr_io_r_query_userinfo(char *desc, SAMR_R_QUERY_USERINFO *r_u, prs_struct *ps, int depth);
+void samr_io_q_unknown_32(char *desc, SAMR_Q_UNKNOWN_32 *q_u, prs_struct *ps, int depth);
+void samr_io_r_unknown_32(char *desc, SAMR_R_UNKNOWN_32 *r_u, prs_struct *ps, int depth);
+void make_samr_q_connect(SAMR_Q_CONNECT *q_u,
+ char *srv_name, uint32 unknown_0);
+void samr_io_q_connect(char *desc, SAMR_Q_CONNECT *q_u, prs_struct *ps, int depth);
+void samr_io_r_connect(char *desc, SAMR_R_CONNECT *r_u, prs_struct *ps, int depth);
+void make_samr_q_connect_anon(SAMR_Q_CONNECT_ANON *q_u);
+void samr_io_q_connect_anon(char *desc, SAMR_Q_CONNECT_ANON *q_u, prs_struct *ps, int depth);
+void samr_io_r_connect_anon(char *desc, SAMR_R_CONNECT_ANON *r_u, prs_struct *ps, int depth);
+void make_samr_q_open_alias(SAMR_Q_OPEN_ALIAS *q_u,
+ uint32 unknown_0, uint32 rid);
+void samr_io_q_open_alias(char *desc, SAMR_Q_OPEN_ALIAS *q_u, prs_struct *ps, int depth);
+void samr_io_r_open_alias(char *desc, SAMR_R_OPEN_ALIAS *r_u, prs_struct *ps, int depth);
+void make_samr_q_unknown_12(SAMR_Q_UNKNOWN_12 *q_u,
+ POLICY_HND *pol, uint32 rid,
+ uint32 num_gids, uint32 *gid);
+void make_samr_q_unknown_21(SAMR_Q_UNKNOWN_21 *q_c,
+ POLICY_HND *hnd, uint16 unk_1, uint16 unk_2);
+void make_samr_q_unknown_13(SAMR_Q_UNKNOWN_13 *q_c,
+ POLICY_HND *hnd, uint16 unk_1, uint16 unk_2);
+void make_samr_q_unknown_38(SAMR_Q_UNKNOWN_38 *q_u, char *srv_name);
+void samr_io_q_unknown_38(char *desc, SAMR_Q_UNKNOWN_38 *q_u, prs_struct *ps, int depth);
+void make_samr_r_unknown_38(SAMR_R_UNKNOWN_38 *r_u);
+void samr_io_r_unknown_38(char *desc, SAMR_R_UNKNOWN_38 *r_u, prs_struct *ps, int depth);
+void make_enc_passwd(SAMR_ENC_PASSWD *pwd, char pass[512]);
+void samr_io_enc_passwd(char *desc, SAMR_ENC_PASSWD *pwd, prs_struct *ps, int depth);
+void make_enc_hash(SAMR_ENC_HASH *hsh, uchar hash[16]);
+void samr_io_enc_hash(char *desc, SAMR_ENC_HASH *hsh, prs_struct *ps, int depth);
+void make_samr_q_chgpasswd_user(SAMR_Q_CHGPASSWD_USER *q_u,
+ char *dest_host, char *user_name,
+ char nt_newpass[516], uchar nt_oldhash[16],
+ char lm_newpass[516], uchar lm_oldhash[16]);
+void samr_io_q_chgpasswd_user(char *desc, SAMR_Q_CHGPASSWD_USER *q_u, prs_struct *ps, int depth);
+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 init_sec_access(SEC_ACCESS *t, uint32 mask);
ENUM_HND *hnd);
void srv_io_q_net_share_enum(char *desc, SRV_Q_NET_SHARE_ENUM *q_n, prs_struct *ps, int depth);
void srv_io_r_net_share_enum(char *desc, SRV_R_NET_SHARE_ENUM *r_n, prs_struct *ps, int depth);
+void make_srv_sess_info0_str(SESS_INFO_0_STR *ss0, char *name);
+void make_srv_sess_info0(SESS_INFO_0 *ss0, char *name);
+void make_srv_sess_info1_str(SESS_INFO_1_STR *ss1, char *name, char *user);
+void make_srv_sess_info1(SESS_INFO_1 *ss1,
+ char *name, char *user,
+ uint32 num_opens, uint32 open_time, uint32 idle_time,
+ uint32 user_flags);
+void make_srv_q_net_sess_enum(SRV_Q_NET_SESS_ENUM *q_n,
+ char *srv_name, char *qual_name,
+ uint32 sess_level, SRV_SESS_INFO_CTR *ctr,
+ uint32 preferred_len,
+ ENUM_HND *hnd);
+void srv_io_q_net_sess_enum(char *desc, SRV_Q_NET_SESS_ENUM *q_n, prs_struct *ps, int depth);
+void srv_io_r_net_sess_enum(char *desc, SRV_R_NET_SESS_ENUM *r_n, prs_struct *ps, int depth);
+void make_srv_conn_info0(CONN_INFO_0 *ss0, uint32 id);
+void make_srv_conn_info1_str(CONN_INFO_1_STR *ss1, char *usr_name, char *net_name);
+void make_srv_conn_info1(CONN_INFO_1 *ss1,
+ uint32 id, uint32 type,
+ uint32 num_opens, uint32 num_users, uint32 open_time,
+ char *usr_name, char *net_name);
+void make_srv_q_net_conn_enum(SRV_Q_NET_CONN_ENUM *q_n,
+ char *srv_name, char *qual_name,
+ uint32 conn_level, SRV_CONN_INFO_CTR *ctr,
+ uint32 preferred_len,
+ ENUM_HND *hnd);
+void srv_io_q_net_conn_enum(char *desc, SRV_Q_NET_CONN_ENUM *q_n, prs_struct *ps, int depth);
+void srv_io_r_net_conn_enum(char *desc, SRV_R_NET_CONN_ENUM *r_n, prs_struct *ps, int depth);
+void make_srv_file_info3_str(FILE_INFO_3_STR *fi3, char *user_name, char *path_name);
+void make_srv_file_info3(FILE_INFO_3 *fl3,
+ uint32 id, uint32 perms, uint32 num_locks,
+ char *path_name, char *user_name);
+void make_srv_q_net_file_enum(SRV_Q_NET_FILE_ENUM *q_n,
+ char *srv_name, char *qual_name,
+ uint32 file_level, SRV_FILE_INFO_CTR *ctr,
+ uint32 preferred_len,
+ ENUM_HND *hnd);
+void srv_io_q_net_file_enum(char *desc, SRV_Q_NET_FILE_ENUM *q_n, prs_struct *ps, int depth);
+void srv_io_r_net_file_enum(char *desc, SRV_R_NET_FILE_ENUM *r_n, prs_struct *ps, int depth);
void make_srv_info_101(SRV_INFO_101 *sv101, uint32 platform_id, char *name,
uint32 ver_major, uint32 ver_minor,
uint32 srv_type, char *comment);
pipes_struct *get_rpc_pipe_p(char *buf, int where);
pipes_struct *get_rpc_pipe(int pnum);
+/*The following definitions come from rpc_server/srv_reg.c */
+
+BOOL api_reg_rpc(pipes_struct *p, prs_struct *data);
+
+/*The following definitions come from rpc_server/srv_samr.c */
+
+BOOL api_samr_rpc(pipes_struct *p, prs_struct *data);
+
/*The following definitions come from rpc_server/srv_srvsvc.c */
BOOL api_srvsvc_rpc(pipes_struct *p, prs_struct *data);
BOOL api_wkssvc_rpc(pipes_struct *p, prs_struct *data);
+/*The following definitions come from rpcclient/cmd_lsarpc.c */
+
+void cmd_lsa_query_info(struct client_info *info);
+void cmd_lsa_lookup_sids(struct client_info *info);
+
+/*The following definitions come from rpcclient/cmd_netlogon.c */
+
+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_create_val(struct client_info *info);
+void cmd_reg_delete_val(struct client_info *info);
+void cmd_reg_delete_key(struct client_info *info);
+void cmd_reg_create_key(struct client_info *info);
+void cmd_reg_test_key_sec(struct client_info *info);
+void cmd_reg_get_key_sec(struct client_info *info);
+
+/*The following definitions come from rpcclient/cmd_samr.c */
+
+void cmd_sam_ntchange_pwd(struct client_info *info);
+void cmd_sam_test(struct client_info *info);
+void cmd_sam_enum_users(struct client_info *info);
+void cmd_sam_query_user(struct client_info *info);
+void cmd_sam_query_groups(struct client_info *info);
+void cmd_sam_enum_aliases(struct client_info *info);
+
+/*The following definitions come from rpcclient/cmd_srvsvc.c */
+
+void cmd_srv_query_info(struct client_info *info);
+void cmd_srv_enum_conn(struct client_info *info);
+void cmd_srv_enum_shares(struct client_info *info);
+void cmd_srv_enum_sess(struct client_info *info);
+void cmd_srv_enum_files(struct client_info *info);
+
+/*The following definitions come from rpcclient/cmd_wkssvc.c */
+
+void cmd_wks_query_info(struct client_info *info);
+
+/*The following definitions come from rpcclient/display.c */
+
+char *get_file_mode_str(uint32 share_mode);
+char *get_file_oplock_str(uint32 op_type);
+char *get_share_type_str(uint32 type);
+char *get_server_type_str(uint32 type);
+void display_srv_info_101(FILE *out_hnd, enum action_type action,
+ SRV_INFO_101 *sv101);
+void display_srv_info_102(FILE *out_hnd, enum action_type action,SRV_INFO_102 *sv102);
+void display_srv_info_ctr(FILE *out_hnd, enum action_type action,SRV_INFO_CTR *ctr);
+void display_conn_info_0(FILE *out_hnd, enum action_type action,
+ CONN_INFO_0 *info0);
+void display_conn_info_1(FILE *out_hnd, enum action_type action,
+ CONN_INFO_1 *info1, CONN_INFO_1_STR *str1);
+void display_srv_conn_info_0_ctr(FILE *out_hnd, enum action_type action,
+ SRV_CONN_INFO_0 *ctr);
+void display_srv_conn_info_1_ctr(FILE *out_hnd, enum action_type action,
+ SRV_CONN_INFO_1 *ctr);
+void display_srv_conn_info_ctr(FILE *out_hnd, enum action_type action,
+ SRV_CONN_INFO_CTR *ctr);
+void display_share_info_1(FILE *out_hnd, enum action_type action,
+ SH_INFO_1 *info1, SH_INFO_1_STR *str1);
+void display_share_info_2(FILE *out_hnd, enum action_type action,
+ SH_INFO_2 *info2, SH_INFO_2_STR *str2);
+void display_srv_share_info_1_ctr(FILE *out_hnd, enum action_type action,
+ SRV_SHARE_INFO_1 *ctr);
+void display_srv_share_info_2_ctr(FILE *out_hnd, enum action_type action,
+ SRV_SHARE_INFO_2 *ctr);
+void display_srv_share_info_ctr(FILE *out_hnd, enum action_type action,
+ SRV_SHARE_INFO_CTR *ctr);
+void display_file_info_3(FILE *out_hnd, enum action_type action,
+ FILE_INFO_3 *info3, FILE_INFO_3_STR *str3);
+void display_srv_file_info_3_ctr(FILE *out_hnd, enum action_type action,
+ SRV_FILE_INFO_3 *ctr);
+void display_srv_file_info_ctr(FILE *out_hnd, enum action_type action,
+ SRV_FILE_INFO_CTR *ctr);
+void display_server(FILE *out_hnd, enum action_type action,
+ char *sname, uint32 type, char *comment);
+void display_share(FILE *out_hnd, enum action_type action,
+ char *sname, uint32 type, char *comment);
+void display_share2(FILE *out_hnd, enum action_type action,
+ char *sname, uint32 type, char *comment,
+ uint32 perms, uint32 max_uses, uint32 num_uses,
+ char *path, char *passwd);
+void display_name(FILE *out_hnd, enum action_type action,
+ char *sname);
+void display_group_rid_info(FILE *out_hnd, enum action_type action,
+ uint32 num_gids, DOM_GID *gid);
+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_mask_str(uint32 type);
+void display_sec_access(FILE *out_hnd, enum action_type action, SEC_ACCESS *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 *sec_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 */
+
+void rpcclient_init(void);
+
/*The following definitions come from smbd/blocking.c */
BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int lock_num);
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* removed in SAMBA_2_0 branch. */
+#ifndef _RPC_REG_H /* _RPC_REG_H */
+#define _RPC_REG_H
+
+
+/* winreg pipe defines */
+#define REG_OPEN_HKLM 0x02
+#define REG_OPEN_HKU 0x04
+#define REG_FLUSH_KEY 0x0B
+#define REG_UNK_1A 0x1a
+#define REG_QUERY_KEY 0x10
+#define REG_ENUM_KEY 0x09
+#define REG_CREATE_KEY 0x06
+#define REG_DELETE_KEY 0x07
+#define REG_DELETE_VALUE 0x08
+#define REG_CREATE_VALUE 0x16
+#define REG_GET_KEY_SEC 0x0c
+#define REG_SET_KEY_SEC 0x15
+#define REG_ENUM_VALUE 0x0a
+#define REG_OPEN_ENTRY 0x0f
+#define REG_INFO 0x11
+#define REG_CLOSE 0x05
+
+#define HKEY_LOCAL_MACHINE 0x80000000
+#define HKEY_USERS 0x80000003
+
+/* REG_Q_OPEN_HKLM */
+typedef struct q_reg_open_policy_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_HKLM ;
+
+/* REG_R_OPEN_HKLM */
+typedef struct r_reg_open_policy_info
+{
+ POLICY_HND pol; /* policy handle */
+ uint32 status; /* return status */
+
+} REG_R_OPEN_HKLM;
+
+
+/* REG_Q_OPEN_HKU */
+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_HKU;
+
+/* REG_R_OPEN_HKU */
+typedef struct r_reg_open_unk4_info
+{
+ POLICY_HND pol; /* policy handle */
+ uint32 status; /* return status */
+
+} REG_R_OPEN_HKU;
+
+
+/* REG_Q_FLUSH_KEY */
+typedef struct q_reg_open_flush_key_info
+{
+ POLICY_HND pol; /* policy handle */
+
+} REG_Q_FLUSH_KEY;
+
+/* REG_R_FLUSH_KEY */
+typedef struct r_reg_open_flush_key_info
+{
+ uint32 status; /* return status */
+
+} REG_R_FLUSH_KEY;
+
+
+/* REG_Q_SET_KEY_SEC */
+typedef struct q_reg_set_key_sec_info
+{
+ POLICY_HND pol; /* policy handle */
+
+ uint32 sec_info; /* xxxx_SECURITY_INFORMATION */
+
+ uint32 ptr; /* pointer */
+ BUFHDR hdr_sec; /* header for security data */
+ SEC_DESC_BUF *data; /* security data */
+
+} REG_Q_SET_KEY_SEC;
+
+/* REG_R_SET_KEY_SEC */
+typedef struct r_reg_set_key_sec_info
+{
+ uint32 status;
+
+} REG_R_SET_KEY_SEC;
+
+
+/* REG_Q_GET_KEY_SEC */
+typedef struct q_reg_get_key_sec_info
+{
+ POLICY_HND pol; /* policy handle */
+
+ uint32 sec_info; /* xxxx_SECURITY_INFORMATION */
+
+ 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 sec_info; /* xxxx_SECURITY_INFORMATION */
+
+ 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_ACCESS sam_access; /* access rights flags, see rpc_secdes.h */
+
+ uint32 ptr1;
+ uint32 sec_info; /* xxxx_SECURITY_INFORMATION */
+
+ uint32 ptr2; /* pointer */
+ BUFHDR hdr_sec; /* header for security data */
+ uint32 ptr3; /* pointer */
+ SEC_DESC_BUF *data;
+
+ 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_DELETE_KEY */
+typedef struct q_reg_delete_key_info
+{
+ POLICY_HND pnt_pol; /* parent key policy handle */
+
+ UNIHDR hdr_name;
+ UNISTR2 uni_name;
+} REG_Q_DELETE_KEY;
+
+/* REG_R_DELETE_KEY */
+typedef struct r_reg_delete_key_info
+{
+ POLICY_HND key_pol; /* policy handle */
+
+ uint32 status; /* return status */
+
+} REG_R_DELETE_KEY;
+
+/* REG_Q_DELETE_VALUE */
+typedef struct q_reg_delete_val_info
+{
+ POLICY_HND pnt_pol; /* parent key policy handle */
+
+ UNIHDR hdr_name;
+ UNISTR2 uni_name;
+
+} REG_Q_DELETE_VALUE;
+
+/* REG_R_DELETE_VALUE */
+typedef struct r_reg_delete_val_info
+{
+ POLICY_HND key_pol; /* policy handle */
+
+ uint32 status; /* return status */
+
+} REG_R_DELETE_VALUE;
+
+/* 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
+{
+ POLICY_HND pol; /* policy handle */
+
+} REG_Q_CLOSE;
+
+/* REG_R_CLOSE */
+typedef struct reg_r_close_info
+{
+ POLICY_HND pol; /* policy handle. should be all zeros. */
+
+ uint32 status; /* return code */
+
+} 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 */
+
+ UNIHDR hdr_type; /* unicode product type header */
+ UNISTR2 uni_type; /* unicode product type - "ProductType" */
+
+ uint32 ptr1; /* pointer */
+ NTTIME time; /* current time? */
+ uint8 major_version1; /* 0x4 - os major version? */
+ uint8 minor_version1; /* 0x1 - os minor version? */
+ uint8 pad1[10]; /* padding - zeros */
+
+ uint32 ptr2; /* pointer */
+ uint8 major_version2; /* 0x4 - os major version? */
+ uint8 minor_version2; /* 0x1 - os minor version? */
+ uint8 pad2[2]; /* padding - zeros */
+
+ uint32 ptr3; /* pointer */
+ uint32 unknown; /* 0x0000 0000 */
+
+} REG_Q_INFO;
+
+/* REG_R_INFO */
+typedef struct r_reg_info_info
+{
+ uint32 ptr1; /* buffer pointer */
+ uint32 level; /* 0x1 - info level? */
+
+ 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 */
+
+ uint32 ptr3; /* pointer to unknown_1 */
+ uint32 unknown_1; /* 0x12 */
+
+ uint32 status; /* return status */
+
+} REG_R_INFO;
+
+
+/* REG_Q_OPEN_ENTRY */
+typedef struct q_reg_open_entry_info
+{
+ 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 */
+ uint32 unknown_1; /* 32 bit unknown - 0x0200 0000 */
+
+} REG_Q_OPEN_ENTRY;
+
+
+
+/* REG_R_OPEN_ENTRY */
+typedef struct r_reg_open_entry_info
+{
+ POLICY_HND pol; /* policy handle */
+ uint32 status; /* return status */
+
+} REG_R_OPEN_ENTRY;
+
+
+
+#endif /* _RPC_REG_H */
+
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* removed in SAMBA_2_0 branch. */
+#ifndef _RPC_SAMR_H /* _RPC_SAMR_H */
+#define _RPC_SAMR_H
+
+
+#include "rpc_misc.h"
+
+
+/*******************************************************************
+ the following information comes from a QuickView on samsrv.dll,
+ and gives an idea of exactly what is needed:
+
+SamrAddMemberToAlias
+SamrAddMemberToGroup
+SamrAddMultipleMembersToAlias
+SamrChangePasswordUser
+x SamrCloseHandle
+x SamrConnect
+SamrCreateAliasInDomain
+SamrCreateGroupInDomain
+SamrCreateUserInDomain
+SamrDeleteAlias
+SamrDeleteGroup
+SamrDeleteUser
+x SamrEnumerateAliasesInDomain
+SamrEnumerateDomainsInSamServer
+x SamrEnumerateGroupsInDomain
+x SamrEnumerateUsersInDomain
+SamrGetUserDomainPasswordInformation
+SamrLookupDomainInSamServer
+? SamrLookupIdsInDomain
+x SamrLookupNamesInDomain
+x SamrOpenAlias
+x SamrOpenDomain
+SamrOpenGroup
+x SamrOpenUser
+x SamrQueryDisplayInformation
+x SamrQueryInformationAlias
+SamrQueryInformationDomain
+? SamrQueryInformationUser
+SamrQuerySecurityObject
+SamrRemoveMemberFromAlias
+SamrRemoveMemberFromForiegnDomain
+SamrRemoveMemberFromGroup
+SamrRemoveMultipleMembersFromAlias
+SamrSetInformationAlias
+SamrSetInformationDomain
+SamrSetInformationGroup
+SamrSetInformationUser
+SamrSetMemberAttributesOfGroup
+SamrSetSecurityObject
+SamrShutdownSamServer
+SamrTestPrivateFunctionsDomain
+SamrTestPrivateFunctionsUser
+
+********************************************************************/
+
+#define SAMR_CLOSE_HND 0x01
+#define SAMR_OPEN_DOMAIN 0x07
+#define SAMR_QUERY_DOMAIN_INFO 0x08
+#define SAMR_LOOKUP_IDS 0x10
+#define SAMR_LOOKUP_NAMES 0x11
+#define SAMR_UNKNOWN_3 0x03
+#define SAMR_QUERY_DISPINFO 0x28
+#define SAMR_OPEN_USER 0x22
+#define SAMR_QUERY_USERINFO 0x24
+#define SAMR_QUERY_USERGROUPS 0x27
+#define SAMR_UNKNOWN_12 0x12
+#define SAMR_UNKNOWN_21 0x21
+#define SAMR_UNKNOWN_2C 0x2c
+#define SAMR_UNKNOWN_32 0x32
+#define SAMR_UNKNOWN_34 0x34
+#define SAMR_CHGPASSWD_USER 0x37
+#define SAMR_UNKNOWN_38 0x38
+#define SAMR_CONNECT 0x39
+#define SAMR_CONNECT_ANON 0x00
+#define SAMR_OPEN_ALIAS 0x1b
+#define SAMR_QUERY_ALIASINFO 0x1c
+#define SAMR_ENUM_DOM_USERS 0x0d
+#define SAMR_ENUM_DOM_ALIASES 0x0f
+#define SAMR_ENUM_DOM_GROUPS 0x30
+
+
+typedef struct logon_hours_info
+{
+ uint32 len; /* normally 21 bytes */
+ uint8 hours[32];
+
+} LOGON_HRS;
+
+/* SAM_USER_INFO_21 */
+typedef struct sam_user_info_21
+{
+ NTTIME logon_time; /* logon time */
+ NTTIME logoff_time; /* logoff time */
+ NTTIME kickoff_time; /* kickoff time */
+ NTTIME pass_last_set_time; /* password last set time */
+ NTTIME pass_can_change_time; /* password can change time */
+ NTTIME pass_must_change_time; /* password must change time */
+
+ UNIHDR hdr_user_name; /* username unicode string header */
+ UNIHDR hdr_full_name; /* user's full name unicode string header */
+ UNIHDR hdr_home_dir; /* home directory unicode string header */
+ UNIHDR hdr_dir_drive; /* home drive unicode string header */
+ UNIHDR hdr_logon_script; /* logon script unicode string header */
+ UNIHDR hdr_profile_path; /* profile path unicode string header */
+ UNIHDR hdr_acct_desc ; /* user description */
+ UNIHDR hdr_workstations; /* comma-separated workstations user can log in from */
+ UNIHDR hdr_unknown_str ; /* don't know what this is, yet. */
+ UNIHDR hdr_munged_dial ; /* munged path name and dial-back tel number */
+
+ uint8 lm_pwd[16]; /* lm user passwords */
+ uint8 nt_pwd[16]; /* nt user passwords */
+
+ uint32 user_rid; /* Primary User ID */
+ uint32 group_rid; /* Primary Group ID */
+
+ uint16 acb_info; /* account info (ACB_xxxx bit-mask) */
+ /* uint8 pad[2] */
+
+ uint32 unknown_3; /* 0x00ff ffff */
+
+ uint16 logon_divs; /* 0x0000 00a8 which is 168 which is num hrs in a week */
+ /* uint8 pad[2] */
+ uint32 ptr_logon_hrs; /* unknown pointer */
+
+ uint32 unknown_5; /* 0x0002 0000 */
+
+ uint8 padding1[8];
+
+ UNISTR2 uni_user_name; /* username unicode string */
+ UNISTR2 uni_full_name; /* user's full name unicode string */
+ UNISTR2 uni_home_dir; /* home directory unicode string */
+ UNISTR2 uni_dir_drive; /* home directory drive unicode string */
+ UNISTR2 uni_logon_script; /* logon script unicode string */
+ UNISTR2 uni_profile_path; /* profile path unicode string */
+ UNISTR2 uni_acct_desc ; /* user description unicode string */
+ UNISTR2 uni_workstations; /* login from workstations unicode string */
+ UNISTR2 uni_unknown_str ; /* don't know what this is, yet. */
+ UNISTR2 uni_munged_dial ; /* munged path name and dial-back tel number */
+
+ uint32 unknown_6; /* 0x0000 04ec */
+ uint32 padding4;
+
+ LOGON_HRS logon_hrs;
+
+} SAM_USER_INFO_21;
+
+
+/* SAM_USER_INFO_11 */
+typedef struct sam_user_info_11
+{
+ uint8 padding_0[16]; /* 0 - padding 16 bytes */
+ NTTIME expiry; /* expiry time or something? */
+ uint8 padding_1[24]; /* 0 - padding 24 bytes */
+
+ UNIHDR hdr_mach_acct; /* unicode header for machine account */
+ uint32 padding_2; /* 0 - padding 4 bytes */
+
+ uint32 ptr_1; /* pointer */
+ uint8 padding_3[32]; /* 0 - padding 32 bytes */
+ uint32 padding_4; /* 0 - padding 4 bytes */
+
+ uint32 ptr_2; /* pointer */
+ uint32 padding_5; /* 0 - padding 4 bytes */
+
+ uint32 ptr_3; /* pointer */
+ uint8 padding_6[32]; /* 0 - padding 32 bytes */
+
+ uint32 rid_user; /* user RID */
+ uint32 rid_group; /* group RID */
+
+ uint16 acct_ctrl; /* 0080 - ACB_XXXX */
+ uint16 unknown_3; /* 16 bit padding */
+
+ uint16 unknown_4; /* 0x003f - 16 bit unknown */
+ uint16 unknown_5; /* 0x003c - 16 bit unknown */
+
+ uint8 padding_7[16]; /* 0 - padding 16 bytes */
+ uint32 padding_8; /* 0 - padding 4 bytes */
+
+ UNISTR2 uni_mach_acct; /* unicode string for machine account */
+
+ uint8 padding_9[48]; /* 0 - padding 48 bytes */
+
+} SAM_USER_INFO_11;
+
+
+/* SAM_USER_INFO_10 */
+typedef struct sam_user_info_10
+{
+ uint32 acb_info;
+
+} SAM_USER_INFO_10;
+
+
+
+/* SAMR_Q_CLOSE_HND - probably a policy handle close */
+typedef struct q_samr_close_hnd_info
+{
+ POLICY_HND pol; /* policy handle */
+
+} SAMR_Q_CLOSE_HND;
+
+
+/* SAMR_R_CLOSE_HND - probably a policy handle close */
+typedef struct r_samr_close_hnd_info
+{
+ POLICY_HND pol; /* policy handle */
+ uint32 status; /* return status */
+
+} SAMR_R_CLOSE_HND;
+
+
+/****************************************************************************
+SAMR_Q_UNKNOWN_2C - a "set user info" occurs just after this
+*****************************************************************************/
+
+/* SAMR_Q_UNKNOWN_2C */
+typedef struct q_samr_unknown_2c_info
+{
+ POLICY_HND user_pol; /* policy handle */
+
+} SAMR_Q_UNKNOWN_2C;
+
+
+/****************************************************************************
+SAMR_R_UNKNOWN_2C - a "set user info" occurs just after this
+*****************************************************************************/
+
+/* SAMR_R_UNKNOWN_2C */
+typedef struct r_samr_unknown_2c_info
+{
+ uint32 unknown_0; /* 0x0016 0000 */
+ uint32 unknown_1; /* 0x0000 0000 */
+ uint32 status;
+
+} SAMR_R_UNKNOWN_2C;
+
+
+/****************************************************************************
+SAMR_Q_UNKNOWN_3 - info level 4. returns SIDs.
+*****************************************************************************/
+
+/* SAMR_Q_UNKNOWN_3 - probably get domain info... */
+typedef struct q_samr_unknown_3_info
+{
+ POLICY_HND user_pol; /* policy handle */
+ uint16 switch_value; /* 0x0000 0004 */
+ /* uint8 pad[2] */
+
+} SAMR_Q_UNKNOWN_3;
+
+/* DOM_SID3 example:
+ 0x14 0x035b 0x0002 S-1-1
+ 0x18 0x07ff 0x000f S-1-5-20-DOMAIN_ALIAS_RID_ADMINS
+ 0x18 0x07ff 0x000f S-1-5-20-DOMAIN_ALIAS_RID_ACCOUNT_OPS
+ 0x24 0x0044 0x0002 S-1-5-21-nnn-nnn-nnn-0x03f1
+ */
+
+/* DOM_SID3 example:
+ 0x24 0x0044 0x0002 S-1-5-21-nnn-nnn-nnn-0x03ee
+ 0x18 0x07ff 0x000f S-1-5-20-DOMAIN_ALIAS_RID_ADMINS
+ 0x14 0x035b 0x0002 S-1-1
+ */
+
+/* DOM_SID3 - security id */
+typedef struct sid_info_3
+{
+ uint16 len; /* length, bytes, including length of len :-) */
+ /* uint8 pad[2]; */
+
+ DOM_SID sid;
+
+} DOM_SID3;
+
+
+#define MAX_SAM_SIDS 15
+
+/* SAM_SID_STUFF */
+typedef struct sid_stuff_info
+{
+ uint16 unknown_2; /* 0x0001 */
+ uint16 unknown_3; /* 0x8004 */
+
+ uint8 padding1[8];
+
+ uint32 unknown_4; /* 0x0000 0014 */
+ uint32 unknown_5; /* 0x0000 0014 */
+
+ uint16 unknown_6; /* 0x0002 */
+ uint16 unknown_7; /* 0x5800 */
+
+ uint32 num_sids;
+
+ uint16 padding2;
+
+ DOM_SID3 sid[MAX_SAM_SIDS];
+
+} SAM_SID_STUFF;
+
+/* SAMR_R_UNKNOWN_3 - probably an open */
+typedef struct r_samr_unknown_3_info
+{
+ uint32 ptr_0;
+ uint32 sid_stuff_len0;
+
+ uint32 ptr_1;
+ uint32 sid_stuff_len1;
+
+ SAM_SID_STUFF sid_stuff;
+
+ uint32 status; /* return status */
+
+} SAMR_R_UNKNOWN_3;
+
+
+/****************************************************************************
+SAMR_Q_QUERY_DOMAIN_INFO - probably a query on domain group info.
+*****************************************************************************/
+
+/* SAMR_Q_QUERY_DOMAIN_INFO - */
+typedef struct q_samr_query_domain_info
+{
+ POLICY_HND domain_pol; /* policy handle */
+ uint16 switch_value; /* 0x0002 */
+
+} SAMR_Q_QUERY_DOMAIN_INFO;
+
+typedef struct sam_unkown_info_2_info
+{
+ uint32 unknown_0; /* 0x0000 0000 */
+ uint32 unknown_1; /* 0x8000 0000 */
+ uint32 unknown_2; /* 0x0000 0000 */
+
+ uint32 ptr_0; /* pointer to unknown structure */
+ UNIHDR hdr_domain; /* domain name unicode header */
+ UNIHDR hdr_server; /* server name unicode header */
+
+ /* put all the data in here, at the moment, including what the above
+ pointer is referring to
+ */
+
+ uint32 seq_num; /* some sort of incrementing sequence number? */
+ uint32 unknown_3; /* 0x0000 0000 */
+
+ uint32 unknown_4; /* 0x0000 0001 */
+ uint32 unknown_5; /* 0x0000 0003 */
+ uint32 unknown_6; /* 0x0000 0001 */
+ uint32 num_domain_usrs; /* number of users in domain */
+ uint32 num_domain_grps; /* number of domain groups in domain */
+ uint32 num_local_grps; /* number of local groups in domain */
+
+ uint8 padding[12]; /* 12 bytes zeros */
+
+ UNISTR2 uni_domain; /* domain name unicode string */
+ UNISTR2 uni_server; /* server name unicode string */
+
+} SAM_UNK_INFO_2;
+
+
+typedef struct sam_unknown_ctr_info
+{
+ union
+ {
+ SAM_UNK_INFO_2 inf2;
+
+ } info;
+
+} SAM_UNK_CTR;
+
+
+/* SAMR_R_QUERY_DOMAIN_INFO - */
+typedef struct r_samr_query_domain_info
+{
+ uint32 ptr_0;
+ uint16 switch_value; /* same as in query */
+
+ SAM_UNK_CTR *ctr;
+
+ uint32 status; /* return status */
+
+} SAMR_R_QUERY_DOMAIN_INFO;
+
+
+/****************************************************************************
+SAMR_Q_OPEN_DOMAIN - unknown_0 values seen associated with SIDs:
+
+0x0000 03f1 and a specific domain sid - S-1-5-21-44c01ca6-797e5c3d-33f83fd0
+0x0000 0200 and a specific domain sid - S-1-5-21-44c01ca6-797e5c3d-33f83fd0
+*****************************************************************************/
+
+/* SAMR_Q_OPEN_DOMAIN */
+typedef struct q_samr_open_domain_info
+{
+ POLICY_HND connect_pol; /* policy handle */
+ uint32 rid; /* 0x2000 0000; 0x0000 0211; 0x0000 0280; 0x0000 0200 - a RID? */
+ DOM_SID2 dom_sid; /* domain SID */
+
+} SAMR_Q_OPEN_DOMAIN;
+
+
+/* SAMR_R_OPEN_DOMAIN - probably an open */
+typedef struct r_samr_open_domain_info
+{
+ POLICY_HND domain_pol; /* policy handle associated with the SID */
+ uint32 status; /* return status */
+
+} SAMR_R_OPEN_DOMAIN;
+
+
+#define MAX_SAM_ENTRIES 250
+
+typedef struct samr_entry_info
+{
+ uint32 rid;
+ UNIHDR hdr_name;
+
+} SAM_ENTRY;
+
+/* SAMR_Q_ENUM_DOM_USERS - SAM rids and names */
+typedef struct q_samr_enum_dom_users_info
+{
+ POLICY_HND pol; /* policy handle */
+
+ uint16 req_num_entries; /* number of values (0 indicates unlimited?) */
+ uint16 unknown_0; /* enumeration context? */
+ uint16 acb_mask; /* 0x0000 indicates all */
+ uint16 unknown_1; /* 0x0000 */
+
+ uint32 max_size; /* 0x0000 ffff */
+
+} SAMR_Q_ENUM_DOM_USERS;
+
+
+/* SAMR_R_ENUM_DOM_USERS - SAM rids and names */
+typedef struct r_samr_enum_dom_users_info
+{
+ uint16 total_num_entries; /* number of entries that match without the acb mask */
+ uint16 unknown_0; /* same as unknown_0 (enum context?) in request */
+ uint32 ptr_entries1; /* actual number of entries to follow, having masked some out */
+
+ uint32 num_entries2;
+ uint32 ptr_entries2;
+
+ uint32 num_entries3;
+
+ SAM_ENTRY sam[MAX_SAM_ENTRIES];
+ UNISTR2 uni_acct_name[MAX_SAM_ENTRIES];
+
+ uint32 num_entries4;
+
+ uint32 status;
+
+} SAMR_R_ENUM_DOM_USERS;
+
+
+typedef struct samr_entry_info3
+{
+ uint32 grp_idx;
+
+ uint32 rid_grp;
+ uint32 attr;
+
+ UNIHDR hdr_grp_name;
+ UNIHDR hdr_grp_desc;
+
+} SAM_ENTRY3;
+
+typedef struct samr_str_entry_info3
+{
+ UNISTR2 uni_grp_name;
+ UNISTR2 uni_grp_desc;
+
+} SAM_STR3;
+
+/* SAMR_Q_ENUM_DOM_GROUPS - SAM rids and names */
+typedef struct q_samr_enum_dom_groups_info
+{
+ POLICY_HND pol; /* policy handle */
+
+ /* these are possibly an enumeration context handle... */
+ uint16 switch_level; /* 0x0003 */
+ uint16 unknown_0; /* 0x0000 */
+ uint32 start_idx; /* presumably the start enumeration index */
+ uint32 unknown_1; /* 0x0000 07d0 */
+
+ uint32 max_size; /* 0x0000 7fff */
+
+} SAMR_Q_ENUM_DOM_GROUPS;
+
+
+/* SAMR_R_ENUM_DOM_GROUPS - SAM rids and names */
+typedef struct r_samr_enum_dom_groups_info
+{
+ uint32 unknown_0; /* 0x0000 0492 or 0x0000 00be */
+ uint32 unknown_1; /* 0x0000 049a or 0x0000 00be */
+ uint32 switch_level; /* 0x0000 0003 */
+
+ uint32 num_entries;
+ uint32 ptr_entries;
+
+ uint32 num_entries2;
+
+ SAM_ENTRY3 sam[MAX_SAM_ENTRIES];
+ SAM_STR3 str[MAX_SAM_ENTRIES];
+
+ uint32 status;
+
+} SAMR_R_ENUM_DOM_GROUPS;
+
+
+
+/* SAMR_Q_ENUM_DOM_ALIASES - SAM rids and names */
+typedef struct q_samr_enum_dom_aliases_info
+{
+ POLICY_HND pol; /* policy handle */
+
+ /* this is possibly an enumeration context handle... */
+ uint32 unknown_0; /* 0x0000 0000 */
+
+ uint32 max_size; /* 0x0000 ffff */
+
+} SAMR_Q_ENUM_DOM_ALIASES;
+
+/* SAMR_R_ENUM_DOM_ALIASES - SAM rids and names */
+typedef struct r_samr_enum_dom_aliases_info
+{
+ uint32 num_entries;
+ uint32 ptr_entries;
+
+ uint32 num_entries2;
+ uint32 ptr_entries2;
+
+ uint32 num_entries3;
+
+ SAM_ENTRY sam[MAX_SAM_ENTRIES];
+ UNISTR2 uni_grp_name[MAX_SAM_ENTRIES];
+
+ uint32 num_entries4;
+
+ uint32 status;
+
+} SAMR_R_ENUM_DOM_ALIASES;
+
+
+
+/* SAMR_Q_QUERY_DISPINFO - SAM rids, names and descriptions */
+typedef struct q_samr_query_disp_info
+{
+ POLICY_HND pol; /* policy handle */
+
+ uint16 switch_level; /* 0x0001 and 0x0002 seen */
+ uint16 unknown_0; /* 0x0000 and 0x2000 seen */
+ uint32 start_idx; /* presumably the start enumeration index */
+ uint32 unknown_1; /* 0x0000 07d0, 0x0000 0400 and 0x0000 0200 seen */
+
+ uint32 max_size; /* 0x0000 7fff, 0x0000 7ffe and 0x0000 3fff seen*/
+
+} SAMR_Q_QUERY_DISPINFO;
+
+typedef struct samr_entry_info1
+{
+ uint32 user_idx;
+
+ uint32 rid_user;
+ uint16 acb_info;
+ uint16 pad;
+
+ UNIHDR hdr_acct_name;
+ UNIHDR hdr_user_name;
+ UNIHDR hdr_user_desc;
+
+} SAM_ENTRY1;
+
+typedef struct samr_str_entry_info1
+{
+ UNISTR2 uni_acct_name;
+ UNISTR2 uni_full_name;
+ UNISTR2 uni_acct_desc;
+
+} SAM_STR1;
+
+typedef struct sam_entry_info_1
+{
+ uint32 num_entries;
+ uint32 ptr_entries;
+ uint32 num_entries2;
+
+ SAM_ENTRY1 sam[MAX_SAM_ENTRIES];
+ SAM_STR1 str[MAX_SAM_ENTRIES];
+
+
+} SAM_INFO_1;
+
+typedef struct samr_entry_info2
+{
+ uint32 user_idx;
+
+ uint32 rid_user;
+ uint16 acb_info;
+ uint16 pad;
+
+ UNIHDR hdr_srv_name;
+ UNIHDR hdr_srv_desc;
+
+} SAM_ENTRY2;
+
+typedef struct samr_str_entry_info2
+{
+ UNISTR2 uni_srv_name;
+ UNISTR2 uni_srv_desc;
+
+} SAM_STR2;
+
+typedef struct sam_entry_info_2
+{
+ uint32 num_entries;
+ uint32 ptr_entries;
+ uint32 num_entries2;
+
+ SAM_ENTRY2 sam[MAX_SAM_ENTRIES];
+ SAM_STR2 str[MAX_SAM_ENTRIES];
+
+} SAM_INFO_2;
+
+typedef struct sam_info_ctr_info
+{
+ union
+ {
+ SAM_INFO_1 *info1; /* server info */
+ SAM_INFO_2 *info2; /* user info */
+ void *info; /* allows assignment without typecasting, */
+
+ } sam;
+
+} SAM_INFO_CTR;
+
+/* SAMR_R_QUERY_DISPINFO - SAM rids, names and descriptions */
+typedef struct r_samr_query_dispinfo_info
+{
+ uint32 unknown_0; /* container length? 0x0000 0492 or 0x0000 00be */
+ uint32 unknown_1; /* container length? 0x0000 049a or 0x0000 00be */
+ uint16 switch_level; /* 0x0001 or 0x0002 */
+ /*uint8 pad[2] */
+
+ SAM_INFO_CTR *ctr;
+
+ uint32 status;
+
+} SAMR_R_QUERY_DISPINFO;
+
+
+
+/* SAMR_Q_QUERY_ALIASINFO - SAM Alias Info */
+typedef struct q_samr_enum_alias_info
+{
+ POLICY_HND pol; /* policy handle */
+
+ uint16 switch_level; /* 0x0003 seen */
+
+} SAMR_Q_QUERY_ALIASINFO;
+
+typedef struct samr_alias_info3
+{
+ UNIHDR hdr_acct_desc;
+ UNISTR2 uni_acct_desc;
+
+} ALIAS_INFO3;
+
+/* SAMR_R_QUERY_ALIASINFO - SAM rids, names and descriptions */
+typedef struct r_samr_query_aliasinfo_info
+{
+ uint32 ptr;
+ uint16 switch_value; /* 0x0003 */
+ /* uint8[2] padding */
+
+ union
+ {
+ ALIAS_INFO3 info3;
+
+ } alias;
+
+ uint32 status;
+
+} SAMR_R_QUERY_ALIASINFO;
+
+
+/* SAMR_Q_QUERY_USERGROUPS - */
+typedef struct q_samr_query_usergroup_info
+{
+ POLICY_HND pol; /* policy handle associated with unknown id */
+
+} SAMR_Q_QUERY_USERGROUPS;
+
+/* SAMR_R_QUERY_USERGROUPS - probably a get sam info */
+typedef struct r_samr_query_usergroup_info
+{
+ uint32 ptr_0; /* pointer */
+ uint32 num_entries; /* number of RID groups */
+ uint32 ptr_1; /* pointer */
+ uint32 num_entries2; /* number of RID groups */
+
+ DOM_GID *gid; /* group info */
+
+ uint32 status; /* return status */
+
+} SAMR_R_QUERY_USERGROUPS;
+
+
+/* SAMR_Q_QUERY_USERINFO - probably a get sam info */
+typedef struct q_samr_query_user_info
+{
+ POLICY_HND pol; /* policy handle associated with unknown id */
+ uint16 switch_value; /* 0x0015, 0x0011 or 0x0010 - 16 bit unknown */
+
+} SAMR_Q_QUERY_USERINFO;
+
+/* SAMR_R_QUERY_USERINFO - probably a get sam info */
+typedef struct r_samr_query_user_info
+{
+ uint32 ptr; /* pointer */
+ uint16 switch_value; /* 0x0015, 0x0011 or 0x0010 - same as in query */
+ /* uint8[2] padding. */
+
+ union
+ {
+ SAM_USER_INFO_10 *id10; /* auth-level 0x10 */
+ SAM_USER_INFO_11 *id11; /* auth-level 0x11 */
+ SAM_USER_INFO_21 *id21; /* auth-level 21 */
+ void* id; /* to make typecasting easy */
+
+ } info;
+
+ uint32 status; /* return status */
+
+} SAMR_R_QUERY_USERINFO;
+
+
+/****************************************************************************
+SAMR_Q_LOOKUP_IDS - do a conversion from name to RID.
+
+the policy handle allocated by an "samr open secret" call is associated
+with a SID. this policy handle is what is queried here, *not* the SID
+itself. the response to the lookup rids is relative to this SID.
+*****************************************************************************/
+/* SAMR_Q_LOOKUP_IDS */
+typedef struct q_samr_lookup_ids_info
+{
+ POLICY_HND pol; /* policy handle */
+
+ uint32 num_sids1; /* number of rids being looked up */
+ uint32 ptr; /* buffer pointer */
+ uint32 num_sids2; /* number of rids being looked up */
+
+ uint32 ptr_sid[MAX_LOOKUP_SIDS]; /* pointers to sids to be looked up */
+ DOM_SID2 sid [MAX_LOOKUP_SIDS]; /* sids to be looked up. */
+
+} SAMR_Q_LOOKUP_IDS;
+
+
+/* SAMR_R_LOOKUP_IDS */
+typedef struct r_samr_lookup_ids_info
+{
+ uint32 num_entries;
+ uint32 ptr; /* undocumented buffer pointer */
+
+ uint32 num_entries2;
+ uint32 rid[MAX_LOOKUP_SIDS]; /* domain RIDs being looked up */
+
+ uint32 status; /* return code */
+
+} SAMR_R_LOOKUP_IDS;
+
+
+/****************************************************************************
+SAMR_Q_LOOKUP_NAMES - do a conversion from SID to RID.
+
+the policy handle allocated by an "samr open secret" call is associated
+with a SID. this policy handle is what is queried here, *not* the SID
+itself. the response to the lookup rids is relative to this SID.
+*****************************************************************************/
+/* SAMR_Q_LOOKUP_NAMES */
+typedef struct q_samr_lookup_names_info
+{
+ POLICY_HND pol; /* policy handle */
+
+ uint32 num_rids1; /* number of rids being looked up */
+ uint32 rid; /* 0x0000 03e8 - RID of the server doing the query? */
+ uint32 ptr; /* 0x0000 0000 - 32 bit unknown */
+ uint32 num_rids2; /* number of rids being looked up */
+
+ UNIHDR hdr_user_name[MAX_LOOKUP_SIDS]; /* unicode account name header */
+ UNISTR2 uni_user_name[MAX_LOOKUP_SIDS]; /* unicode account name string */
+
+} SAMR_Q_LOOKUP_NAMES;
+
+
+/* SAMR_R_LOOKUP_NAMES */
+typedef struct r_samr_lookup_names_info
+{
+ uint32 num_entries;
+ uint32 undoc_buffer; /* undocumented buffer pointer */
+
+ uint32 num_entries2;
+ DOM_RID3 dom_rid[MAX_LOOKUP_SIDS]; /* domain RIDs being looked up */
+
+ uint32 num_entries3;
+
+ uint32 status; /* return code */
+
+} SAMR_R_LOOKUP_NAMES;
+
+
+/****************************************************************************
+SAMR_Q_UNKNOWN_12 - do a conversion from RID groups to something.
+
+called to resolve domain RID groups.
+*****************************************************************************/
+/* SAMR_Q_UNKNOWN_12 */
+typedef struct q_samr_unknown_12_info
+{
+ POLICY_HND pol; /* policy handle */
+
+ uint32 num_gids1; /* number of rids being looked up */
+ uint32 rid; /* 0x0000 03e8 - RID of the server doing the query? */
+ uint32 ptr; /* 0x0000 0000 - 32 bit unknown */
+ uint32 num_gids2; /* number of rids being looked up */
+
+ uint32 gid[MAX_LOOKUP_SIDS]; /* domain RIDs being looked up */
+
+} SAMR_Q_UNKNOWN_12;
+
+
+/****************************************************************************
+SAMR_R_UNKNOWN_12 - do a conversion from group RID to names
+
+*****************************************************************************/
+/* SAMR_R_UNKNOWN_12 */
+typedef struct r_samr_unknown_12_info
+{
+ POLICY_HND pol; /* policy handle */
+
+ uint32 num_aliases1; /* number of aliases being looked up */
+ uint32 ptr_aliases; /* pointer to aliases */
+ uint32 num_aliases2; /* number of aliases being looked up */
+
+ UNIHDR hdr_als_name[MAX_LOOKUP_SIDS]; /* unicode account name header */
+ UNISTR2 uni_als_name[MAX_LOOKUP_SIDS]; /* unicode account name string */
+
+ uint32 num_als_usrs1; /* number of users in aliases being looked up */
+ uint32 ptr_als_usrs; /* pointer to users in aliases */
+ uint32 num_als_usrs2; /* number of users in aliases being looked up */
+
+ uint32 num_als_usrs[MAX_LOOKUP_SIDS]; /* number of users per group */
+
+ uint32 status;
+
+} SAMR_R_UNKNOWN_12;
+
+
+/* SAMR_Q_OPEN_USER - probably an open */
+typedef struct q_samr_open_user_info
+{
+ POLICY_HND domain_pol; /* policy handle */
+ uint32 unknown_0; /* 32 bit unknown - 0x02011b */
+ uint32 user_rid; /* user RID */
+
+} SAMR_Q_OPEN_USER;
+
+
+/* SAMR_R_OPEN_USER - probably an open */
+typedef struct r_samr_open_user_info
+{
+ POLICY_HND user_pol; /* policy handle associated with unknown id */
+ uint32 status; /* return status */
+
+} SAMR_R_OPEN_USER;
+
+
+/* SAMR_Q_UNKNOWN_13 - probably an open alias in domain */
+typedef struct q_samr_unknown_13_info
+{
+ POLICY_HND alias_pol; /* policy handle */
+
+ uint16 unknown_1; /* 16 bit unknown - 0x0200 */
+ uint16 unknown_2; /* 16 bit unknown - 0x0000 */
+
+} SAMR_Q_UNKNOWN_13;
+
+
+/* SAMR_Q_UNKNOWN_21 - probably an open group in domain */
+typedef struct q_samr_unknown_21_info
+{
+ POLICY_HND group_pol; /* policy handle */
+
+ uint16 unknown_1; /* 16 bit unknown - 0x0477 */
+ uint16 unknown_2; /* 16 bit unknown - 0x0000 */
+
+} SAMR_Q_UNKNOWN_21;
+
+
+/* SAMR_Q_UNKNOWN_32 - probably a "create SAM entry" */
+typedef struct q_samr_unknown_32_info
+{
+ POLICY_HND pol; /* policy handle */
+
+ UNIHDR hdr_mach_acct; /* unicode machine account name header */
+ UNISTR2 uni_mach_acct; /* unicode machine account name */
+
+ uint32 acct_ctrl; /* 32 bit ACB_XXXX */
+ uint16 unknown_1; /* 16 bit unknown - 0x00B0 */
+ uint16 unknown_2; /* 16 bit unknown - 0xe005 */
+
+} SAMR_Q_UNKNOWN_32;
+
+
+/* SAMR_R_UNKNOWN_32 - probably a "create SAM entry" */
+typedef struct r_samr_unknown_32_info
+{
+ POLICY_HND pol; /* policy handle */
+
+ /* rid4.unknown - fail: 0030 success: 0x03ff */
+ DOM_RID4 rid4; /* rid and attributes */
+
+ uint32 status; /* return status - fail: 0xC000 0099: user exists */
+
+} SAMR_R_UNKNOWN_32;
+
+
+/* SAMR_Q_OPEN_ALIAS - probably an open */
+typedef struct q_samr_open_alias_info
+{
+ uint32 unknown_0; /* 0x0000 0008 */
+ uint32 rid_alias; /* rid */
+
+} SAMR_Q_OPEN_ALIAS;
+
+
+/* SAMR_R_OPEN_ALIAS - probably an open */
+typedef struct r_samr_open_alias_info
+{
+ POLICY_HND pol; /* policy handle */
+ uint32 status; /* return status */
+
+} SAMR_R_OPEN_ALIAS;
+
+
+/* SAMR_Q_CONNECT_ANON - probably an open */
+typedef struct q_samr_connect_anon_info
+{
+ uint32 ptr; /* ptr? */
+ uint16 unknown_0; /* 0x005c */
+ uint16 unknown_1; /* 0x0001 */
+ uint32 unknown_2; /* 0x0000 0020 */
+
+} SAMR_Q_CONNECT_ANON;
+
+/* SAMR_R_CONNECT_ANON - probably an open */
+typedef struct r_samr_connect_anon_info
+{
+ POLICY_HND connect_pol; /* policy handle */
+ uint32 status; /* return status */
+
+} SAMR_R_CONNECT_ANON;
+
+/* SAMR_Q_CONNECT - probably an open */
+typedef struct q_samr_connect_info
+{
+ uint32 ptr_srv_name; /* pointer (to server name?) */
+ UNISTR2 uni_srv_name; /* unicode server name starting with '\\' */
+
+ uint32 unknown_0; /* 32 bit unknown */
+
+} SAMR_Q_CONNECT;
+
+
+/* SAMR_R_CONNECT - probably an open */
+typedef struct r_samr_connect_info
+{
+ POLICY_HND connect_pol; /* policy handle */
+ uint32 status; /* return status */
+
+} SAMR_R_CONNECT;
+
+/* SAMR_Q_UNKNOWN_38 */
+typedef struct q_samr_unknown_38
+{
+ uint32 ptr;
+ UNIHDR hdr_srv_name;
+ UNISTR2 uni_srv_name;
+
+} SAMR_Q_UNKNOWN_38;
+
+/* SAMR_R_UNKNOWN_38 */
+typedef struct r_samr_unknown_38
+{
+ uint16 unk_0;
+ uint16 unk_1;
+ uint16 unk_2;
+ uint16 unk_3;
+
+} SAMR_R_UNKNOWN_38;
+
+/* SAMR_ENC_PASSWD */
+typedef struct enc_passwd_info
+{
+ uint32 ptr;
+ uint8 pass[516];
+
+} SAMR_ENC_PASSWD;
+
+/* SAMR_ENC_HASH */
+typedef struct enc_hash_info
+{
+ uint32 ptr;
+ uint8 hash[16];
+
+} SAMR_ENC_HASH;
+
+/* SAMR_Q_CHGPASSWD_USER */
+typedef struct q_samr_chgpasswd_user_info
+{
+ uint32 ptr_0;
+
+ UNIHDR hdr_dest_host; /* server name unicode header */
+ UNISTR2 uni_dest_host; /* server name unicode string */
+
+ UNIHDR hdr_user_name; /* username unicode string header */
+ UNISTR2 uni_user_name; /* username unicode string */
+
+ SAMR_ENC_PASSWD nt_newpass;
+ SAMR_ENC_HASH nt_oldhash;
+
+ uint32 unknown; /* 0x0000 0001 */
+
+ SAMR_ENC_PASSWD lm_newpass;
+ SAMR_ENC_HASH lm_oldhash;
+
+} SAMR_Q_CHGPASSWD_USER;
+
+/* SAMR_R_CHGPASSWD_USER */
+typedef struct r_samr_chgpasswd_user_info
+{
+ uint32 status; /* 0 == OK, C000006A (NT_STATUS_WRONG_PASSWORD) */
+
+} SAMR_R_CHGPASSWD_USER;
+
+#endif /* _RPC_SAMR_H */
+
return requested_max;
#endif
}
+
+
+/*****************************************************************
+ splits out the last subkey of a key
+ *****************************************************************/
+void reg_get_subkey(char *full_keyname, char *key_name, char *subkey_name)
+{
+ split_at_last_component(full_keyname, key_name, '\\', subkey_name);
+}
+
+/*****************************************************************
+ splits out the start of the key (HKLM or HKU) and the rest of the key
+ *****************************************************************/
+BOOL reg_split_key(char *full_keyname, uint32 *reg_type, char *key_name)
+{
+ pstring tmp;
+
+ if (!next_token(&full_keyname, tmp, "\\", sizeof(tmp)))
+ {
+ return False;
+ }
+
+ (*reg_type) = 0;
+
+ DEBUG(10, ("reg_split_key: hive %s\n", tmp));
+
+ if (strequal(tmp, "HKLM") || strequal(tmp, "HKEY_LOCAL_MACHINE"))
+ {
+ (*reg_type) = HKEY_LOCAL_MACHINE;
+ }
+ else if (strequal(tmp, "HKU") || strequal(tmp, "HKEY_USERS"))
+ {
+ (*reg_type) = HKEY_USERS;
+ }
+ else
+ {
+ DEBUG(10,("reg_split_key: unrecognised hive key %s\n", tmp));
+ return False;
+ }
+
+ if (next_token(NULL, tmp, "\n\r", sizeof(tmp)))
+ {
+ fstrcpy(key_name, tmp);
+ }
+ else
+ {
+ key_name[0] = 0;
+ }
+
+ DEBUG(10, ("reg_split_key: name %s\n", key_name));
+
+ return True;
+}
lsa_io_r_open_pol("", &r_o, rdata, 0);
}
+/***************************************************************************
+make_dom_query
+ ***************************************************************************/
+static void make_dom_query(DOM_QUERY *d_q, char *dom_name, DOM_SID *dom_sid)
+{
+ int domlen = strlen(dom_name);
+
+ d_q->uni_dom_max_len = domlen * 2;
+ d_q->uni_dom_str_len = domlen * 2;
+
+ d_q->buffer_dom_name = 4; /* domain buffer pointer */
+ d_q->buffer_dom_sid = 2; /* domain sid pointer */
+
+ /* this string is supposed to be character short */
+ make_unistr2(&(d_q->uni_domain_name), dom_name, domlen);
+
+ make_dom_sid2(&(d_q->dom_sid), dom_sid);
+}
+
/***************************************************************************
lsa_reply_query_info
***************************************************************************/
lsa_io_r_enum_trust_dom("", &r_e, rdata, 0);
}
-/***************************************************************************
-make_dom_query
- ***************************************************************************/
-static void make_dom_query(DOM_QUERY *d_q, char *dom_name, DOM_SID *dom_sid)
-{
- int domlen = strlen(dom_name);
-
- d_q->uni_dom_max_len = domlen * 2;
- d_q->uni_dom_str_len = domlen * 2;
-
- d_q->buffer_dom_name = 4; /* domain buffer pointer */
- d_q->buffer_dom_sid = 2; /* domain sid pointer */
-
- /* this string is supposed to be character short */
- make_unistr2(&(d_q->uni_domain_name), dom_name, domlen);
-
- make_dom_sid2(&(d_q->dom_sid), dom_sid);
-}
/***************************************************************************
lsa_reply_query_info
***************************************************************************/
}
+/***************************************************************************
+make_dom_ref
+ ***************************************************************************/
+static void make_dom_ref(DOM_R_REF *ref, int num_domains,
+ char **dom_names, DOM_SID **dom_sids)
+
+{
+ int i;
+
+ if (num_domains > MAX_REF_DOMAINS)
+ {
+ num_domains = MAX_REF_DOMAINS;
+ }
+
+ ref->undoc_buffer = 1;
+ ref->num_ref_doms_1 = num_domains;
+ ref->undoc_buffer2 = 1;
+ ref->max_entries = MAX_REF_DOMAINS;
+ ref->num_ref_doms_2 = num_domains;
+
+ for (i = 0; i < num_domains; i++)
+ {
+ int len = dom_names[i] != NULL ? strlen(dom_names[i]) : 0;
+
+ make_uni_hdr(&(ref->hdr_ref_dom[i].hdr_dom_name), len, len, len != 0 ? 1 : 0);
+ ref->hdr_ref_dom[i].ptr_dom_sid = dom_sids[i] != NULL ? 1 : 0;
+
+ make_unistr2 (&(ref->ref_dom[i].uni_dom_name), dom_names[i], len);
+ make_dom_sid2(&(ref->ref_dom[i].ref_dom ), dom_sids [i]);
+ }
+
+}
+
+/***************************************************************************
+make_reply_lookup_rids
+ ***************************************************************************/
+static void make_reply_lookup_rids(LSA_R_LOOKUP_RIDS *r_l,
+ int num_entries, uint32 dom_rids[MAX_LOOKUP_SIDS],
+ int num_ref_doms,
+ char **dom_names, DOM_SID **dom_sids)
+{
+ int i;
+
+ make_dom_ref(&(r_l->dom_ref), num_ref_doms, dom_names, dom_sids);
+
+ r_l->num_entries = num_entries;
+ r_l->undoc_buffer = 1;
+ r_l->num_entries2 = num_entries;
+
+ SMB_ASSERT_ARRAY(r_l->dom_rid, num_entries);
+
+ for (i = 0; i < num_entries; i++)
+ {
+ make_dom_rid2(&(r_l->dom_rid[i]), dom_rids[i], 0x01);
+ }
+
+ r_l->num_entries3 = num_entries;
+}
+
+/***************************************************************************
+make_lsa_trans_names
+ ***************************************************************************/
+static void make_lsa_trans_names(LSA_TRANS_NAME_ENUM *trn,
+ int num_entries, DOM_SID2 sid[MAX_LOOKUP_SIDS],
+ uint32 *total)
+{
+ uint32 status = 0x0;
+ int i;
+ (*total) = 0;
+
+ SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
+
+ for (i = 0; i < num_entries; i++)
+ {
+ uint32 rid = 0xffffffff;
+ uint8 num_auths = sid[i].sid.num_auths;
+ fstring name;
+ uint32 type;
+
+ SMB_ASSERT_ARRAY(sid[i].sid.sub_auths, num_auths);
+
+ /* find the rid to look up */
+ if (num_auths != 0)
+ {
+ rid = sid[i].sid.sub_auths[num_auths-1];
+
+ status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
+
+ status = (status != 0x0) ? lookup_user_name (rid, name, &type) : status;
+ status = (status != 0x0) ? lookup_group_name(rid, name, &type) : status;
+ status = (status != 0x0) ? lookup_alias_name(rid, name, &type) : status;
+ }
+
+ if (status == 0x0)
+ {
+ make_lsa_trans_name(&(trn->name [(*total)]),
+ &(trn->uni_name[(*total)]),
+ type, name, (*total));
+ (*total)++;
+ }
+ }
+
+ trn->num_entries = (*total);
+ trn->ptr_trans_names = 1;
+ trn->num_entries2 = (*total);
+}
+
+/***************************************************************************
+make_reply_lookup_sids
+ ***************************************************************************/
+static void make_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l,
+ DOM_R_REF *ref, LSA_TRANS_NAME_ENUM *names,
+ uint32 mapped_count, uint32 status)
+{
+ r_l->dom_ref = ref;
+ r_l->names = names;
+ r_l->mapped_count = mapped_count;
+ r_l->status = status;
+}
+
+/***************************************************************************
+lsa_reply_lookup_sids
+ ***************************************************************************/
+static void lsa_reply_lookup_sids(prs_struct *rdata,
+ int num_entries, DOM_SID2 sid[MAX_LOOKUP_SIDS],
+ int num_ref_doms,
+ char **dom_names, DOM_SID **dom_sids)
+{
+ LSA_R_LOOKUP_SIDS r_l;
+ DOM_R_REF ref;
+ LSA_TRANS_NAME_ENUM names;
+ uint32 mapped_count = 0;
+
+ ZERO_STRUCT(r_l);
+ ZERO_STRUCT(ref);
+ ZERO_STRUCT(names);
+
+ /* set up the LSA Lookup SIDs response */
+ make_dom_ref(&ref, num_ref_doms, dom_names, dom_sids);
+ make_lsa_trans_names(&names, num_entries, sid, &mapped_count);
+ make_reply_lookup_sids(&r_l, &ref, &names, mapped_count, 0x0);
+
+ /* store the response in the SMB stream */
+ lsa_io_r_lookup_sids("", &r_l, rdata, 0);
+}
+
+/***************************************************************************
+lsa_reply_lookup_rids
+ ***************************************************************************/
+static void lsa_reply_lookup_rids(prs_struct *rdata,
+ int num_entries, uint32 dom_rids[MAX_LOOKUP_SIDS],
+ int num_ref_doms,
+ char **dom_names, DOM_SID **dom_sids)
+{
+ LSA_R_LOOKUP_RIDS r_l;
+
+ ZERO_STRUCT(r_l);
+
+ /* set up the LSA Lookup RIDs response */
+ make_reply_lookup_rids(&r_l, num_entries, dom_rids,
+ num_ref_doms, dom_names, dom_sids);
+ r_l.status = 0x0;
+
+ /* store the response in the SMB stream */
+ lsa_io_r_lookup_rids("", &r_l, rdata, 0);
+}
+
/***************************************************************************
api_lsa_open_policy
***************************************************************************/
lsa_reply_query_info(&q_i, rdata, dom_name, &global_sam_sid);
}
+/***************************************************************************
+api_lsa_lookup_sids
+ ***************************************************************************/
+static void api_lsa_lookup_sids( uint16 vuid, prs_struct *data,
+ prs_struct *rdata )
+{
+ LSA_Q_LOOKUP_SIDS q_l;
+ pstring dom_name;
+ DOM_SID sid_S_1_1;
+ DOM_SID sid_S_1_3;
+ DOM_SID sid_S_1_5;
+
+ DOM_SID *sid_array[4];
+ char *dom_names[4];
+
+ ZERO_STRUCT(q_l);
+ ZERO_STRUCT(sid_S_1_1);
+ ZERO_STRUCT(sid_S_1_3);
+ ZERO_STRUCT(sid_S_1_5);
+
+ /* grab the info class and policy handle */
+ lsa_io_q_lookup_sids("", &q_l, data, 0);
+
+ pstrcpy(dom_name, lp_workgroup());
+
+ string_to_sid(&sid_S_1_1, "S-1-1");
+ string_to_sid(&sid_S_1_3, "S-1-3");
+ string_to_sid(&sid_S_1_5, "S-1-5");
+
+ dom_names[0] = dom_name;
+ sid_array[0] = &global_sam_sid;
+
+ dom_names[1] = "Everyone";
+ sid_array[1] = &sid_S_1_1;
+
+ dom_names[2] = "don't know";
+ sid_array[2] = &sid_S_1_3;
+
+ dom_names[3] = "NT AUTHORITY";
+ sid_array[3] = &sid_S_1_5;
+
+ /* construct reply. return status is always 0x0 */
+ lsa_reply_lookup_sids(rdata,
+ q_l.sids.num_entries, q_l.sids.sid, /* SIDs */
+ 4, dom_names, sid_array);
+}
+
+/***************************************************************************
+api_lsa_lookup_names
+ ***************************************************************************/
+static void api_lsa_lookup_names( uint16 vuid, prs_struct *data,
+ prs_struct *rdata )
+{
+ int i;
+ LSA_Q_LOOKUP_RIDS q_l;
+ pstring dom_name;
+ uint32 dom_rids[MAX_LOOKUP_SIDS];
+ uint32 dummy_g_rid;
+
+ DOM_SID sid_S_1_1;
+ DOM_SID sid_S_1_3;
+ DOM_SID sid_S_1_5;
+
+ DOM_SID *sid_array[4];
+ char *dom_names[4];
+
+ ZERO_STRUCT(q_l);
+ ZERO_STRUCT(sid_S_1_1);
+ ZERO_STRUCT(sid_S_1_3);
+ ZERO_STRUCT(sid_S_1_5);
+ ZERO_ARRAY(dom_rids);
+
+ /* grab the info class and policy handle */
+ lsa_io_q_lookup_rids("", &q_l, data, 0);
+
+ pstrcpy(dom_name, lp_workgroup());
+
+ string_to_sid(&sid_S_1_1, "S-1-1");
+ string_to_sid(&sid_S_1_3, "S-1-3");
+ string_to_sid(&sid_S_1_5, "S-1-5");
+
+ dom_names[0] = dom_name;
+ sid_array[0] = &global_sam_sid;
+
+ dom_names[1] = "Everyone";
+ sid_array[1] = &sid_S_1_1;
+
+ dom_names[2] = "don't know";
+ sid_array[2] = &sid_S_1_3;
+
+ dom_names[3] = "NT AUTHORITY";
+ sid_array[3] = &sid_S_1_5;
+
+ SMB_ASSERT_ARRAY(q_l.lookup_name, q_l.num_entries);
+
+ /* convert received RIDs to strings, so we can do them. */
+ for (i = 0; i < q_l.num_entries; i++)
+ {
+ fstring user_name;
+ fstrcpy(user_name, unistr2(q_l.lookup_name[i].str.buffer));
+
+ /*
+ * Map to the UNIX username.
+ */
+ map_username(user_name);
+
+ /*
+ * Do any case conversions.
+ */
+ (void)Get_Pwnam(user_name, True);
+
+ if (!pdb_name_to_rid(user_name, &dom_rids[i], &dummy_g_rid))
+ {
+ /* WHOOPS! we should really do something about this... */
+ dom_rids[i] = 0;
+ }
+ }
+
+ /* construct reply. return status is always 0x0 */
+ lsa_reply_lookup_rids(rdata,
+ q_l.num_entries, dom_rids, /* text-converted SIDs */
+ 4, dom_names, sid_array);
+}
+
/***************************************************************************
api_lsa_close
***************************************************************************/
{ "LSA_ENUMTRUSTDOM" , LSA_ENUMTRUSTDOM , api_lsa_enum_trust_dom },
{ "LSA_CLOSE" , LSA_CLOSE , api_lsa_close },
{ "LSA_OPENSECRET" , LSA_OPENSECRET , api_lsa_open_secret },
+ { "LSA_LOOKUPSIDS" , LSA_LOOKUPSIDS , api_lsa_lookup_sids },
+ { "LSA_LOOKUPNAMES" , LSA_LOOKUPNAMES , api_lsa_lookup_names },
{ NULL , 0 , NULL }
};
static void dump_globals(FILE *f)
{
int i;
- fprintf(f, "[global]\n");
+ fprintf(f, "# Global parameters\n");
for (i=0;parm_table[i].label;i++)
if (parm_table[i].class == P_GLOBAL &&
return valid_pol;
}
+/****************************************************************************
+do a LSA Lookup SIDs
+****************************************************************************/
+BOOL do_lsa_lookup_sids(struct cli_state *cli,
+ POLICY_HND *hnd,
+ int num_sids,
+ DOM_SID **sids,
+ char ***names,
+ int *num_names)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ LSA_Q_LOOKUP_SIDS q_l;
+ BOOL valid_response = False;
+
+ if (hnd == NULL || num_sids == 0 || sids == 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 LSA_LOOKUP_SIDS */
+
+ DEBUG(4,("LSA Lookup SIDs\n"));
+
+ /* store the parameters */
+ make_q_lookup_sids(&q_l, hnd, num_sids, sids, 1);
+
+ /* turn parameters into data stream */
+ lsa_io_q_lookup_sids("", &q_l, &buf, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, LSA_LOOKUPSIDS, &buf, &rbuf))
+ {
+ LSA_R_LOOKUP_SIDS r_l;
+ DOM_R_REF ref;
+ LSA_TRANS_NAME_ENUM t_names;
+ BOOL p;
+
+ r_l.dom_ref = &ref;
+ r_l.names = &t_names;
+
+ lsa_io_r_lookup_sids("", &r_l, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_l.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("LSA_LOOKUP_SIDS: %s\n", get_nt_error_msg(r_l.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ if (t_names.ptr_trans_names != 0 && ref.undoc_buffer != 0)
+ {
+ valid_response = True;
+ }
+ }
+
+ if (num_names != NULL && valid_response)
+ {
+ (*num_names) = t_names.num_entries;
+ }
+ if (valid_response)
+ {
+ int i;
+ for (i = 0; i < t_names.num_entries; i++)
+ {
+ if (t_names.name[i].domain_idx >= ref.num_ref_doms_1)
+ {
+ DEBUG(0,("LSA_LOOKUP_SIDS: domain index out of bounds\n"));
+ valid_response = False;
+ break;
+ }
+ }
+ }
+
+ if (names != NULL && valid_response && t_names.num_entries != 0)
+ {
+ (*names) = (char**)malloc((*num_names) * sizeof(char*));
+ }
+
+ if (names != NULL && (*names) != NULL)
+ {
+ int i;
+ /* take each name, construct a \DOMAIN\name string */
+ for (i = 0; i < (*num_names); i++)
+ {
+ fstring name;
+ fstring dom_name;
+ fstring full_name;
+ uint32 dom_idx = t_names.name[i].domain_idx;
+ fstrcpy(dom_name, unistr2(ref.ref_dom[dom_idx].uni_dom_name.buffer));
+ fstrcpy(name , unistr2(t_names.uni_name[i].buffer));
+
+ slprintf(full_name, sizeof(full_name)-1, "\\%s\\%s",
+ dom_name, name);
+
+ (*names)[i] = strdup(full_name);
+ }
+ }
+ }
+
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
+
+ return valid_response;
+}
+
/****************************************************************************
do a LSA Query Info Policy
****************************************************************************/
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* removed in SAMBA_2_0 branch. */
+
+#ifdef SYSLOG
+#undef SYSLOG
+#endif
+
+#include "includes.h"
+
+extern int DEBUGLEVEL;
+
+/****************************************************************************
+do a REG Open Policy
+****************************************************************************/
+BOOL do_reg_connect(struct cli_state *cli, char *full_keyname, char *key_name,
+ POLICY_HND *reg_hnd)
+{
+ BOOL res = True;
+ uint32 reg_type = 0;
+
+ if (full_keyname == NULL)
+ {
+ return False;
+ }
+
+ ZERO_STRUCTP(reg_hnd);
+
+ /*
+ * open registry receive a policy handle
+ */
+
+ if (!reg_split_key(full_keyname, ®_type, key_name))
+ {
+ DEBUG(0,("do_reg_connect: unrecognised key name %s\n", full_keyname));
+ return False;
+ }
+
+ switch (reg_type)
+ {
+ case HKEY_LOCAL_MACHINE:
+ {
+ res = res ? do_reg_open_hklm(cli,
+ 0x84E0, 0x02000000,
+ reg_hnd) : False;
+ break;
+ }
+
+ case HKEY_USERS:
+ {
+ res = res ? do_reg_open_hku(cli,
+ 0x84E0, 0x02000000,
+ reg_hnd) : False;
+ break;
+ }
+ default:
+ {
+ DEBUG(0,("do_reg_connect: unrecognised hive key\n"));
+ return False;
+ }
+ }
+
+ return res;
+}
+
+/****************************************************************************
+do a REG Open Policy
+****************************************************************************/
+BOOL do_reg_open_hklm(struct cli_state *cli, uint16 unknown_0, uint32 level,
+ POLICY_HND *hnd)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ REG_Q_OPEN_HKLM q_o;
+ BOOL valid_pol = False;
+
+ if (hnd == NULL) return False;
+
+ prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
+ prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True );
+
+ /* create and send a MSRPC command with api REG_OPEN_HKLM */
+
+ DEBUG(4,("REG Open HKLM\n"));
+
+ make_reg_q_open_hklm(&q_o, unknown_0, level);
+
+ /* turn parameters into data stream */
+ reg_io_q_open_hklm("", &q_o, &buf, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, REG_OPEN_HKLM, &buf, &rbuf))
+ {
+ REG_R_OPEN_HKLM r_o;
+ BOOL p;
+
+ ZERO_STRUCT(r_o);
+
+ reg_io_r_open_hklm("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("REG_OPEN_HKLM: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ /* ok, at last: we're happy. return the policy handle */
+ memcpy(hnd, r_o.pol.data, sizeof(hnd->data));
+ valid_pol = True;
+ }
+ }
+
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
+
+ return valid_pol;
+}
+
+/****************************************************************************
+do a REG Open HKU
+****************************************************************************/
+BOOL do_reg_open_hku(struct cli_state *cli, uint16 unknown_0, uint32 level,
+ POLICY_HND *hnd)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ REG_Q_OPEN_HKU q_o;
+ BOOL valid_pol = False;
+
+ if (hnd == NULL) return False;
+
+ prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
+ prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True );
+
+ /* create and send a MSRPC command with api REG_OPEN_HKU */
+
+ DEBUG(4,("REG Open HKU\n"));
+
+ make_reg_q_open_hku(&q_o, unknown_0, level);
+
+ /* turn parameters into data stream */
+ reg_io_q_open_hku("", &q_o, &buf, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, REG_OPEN_HKU, &buf, &rbuf))
+ {
+ REG_R_OPEN_HKU r_o;
+ BOOL p;
+
+ ZERO_STRUCT(r_o);
+
+ reg_io_r_open_hku("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("REG_OPEN_HKU: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ /* ok, at last: we're happy. return the policy handle */
+ memcpy(hnd, r_o.pol.data, sizeof(hnd->data));
+ valid_pol = True;
+ }
+ }
+
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
+
+ return valid_pol;
+}
+
+/****************************************************************************
+do a REG Unknown 0xB command. sent after a create key or create value.
+this might be some sort of "sync" or "refresh" command, sent after
+modification of the registry...
+****************************************************************************/
+BOOL do_reg_flush_key(struct cli_state *cli, POLICY_HND *hnd)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ REG_Q_FLUSH_KEY q_o;
+ BOOL valid_query = 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_FLUSH_KEY */
+
+ DEBUG(4,("REG Unknown 0xB\n"));
+
+ make_reg_q_flush_key(&q_o, hnd);
+
+ /* turn parameters into data stream */
+ reg_io_q_flush_key("", &q_o, &buf, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, REG_FLUSH_KEY, &buf, &rbuf))
+ {
+ REG_R_FLUSH_KEY r_o;
+ BOOL p;
+
+ ZERO_STRUCT(r_o);
+
+ reg_io_r_flush_key("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("REG_FLUSH_KEY: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ valid_query = True;
+ }
+ }
+
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
+
+ return valid_query;
+}
+
+/****************************************************************************
+do a REG Query Key
+****************************************************************************/
+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)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ REG_Q_QUERY_KEY q_o;
+ BOOL valid_query = 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_QUERY_KEY */
+
+ DEBUG(4,("REG Query Key\n"));
+
+ make_reg_q_query_key(&q_o, hnd, *class_len);
+
+ /* turn parameters into data stream */
+ reg_io_q_query_key("", &q_o, &buf, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, REG_QUERY_KEY, &buf, &rbuf))
+ {
+ REG_R_QUERY_KEY r_o;
+ BOOL p;
+
+ ZERO_STRUCT(r_o);
+
+ 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_KEY: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ valid_query = True;
+
+ *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 ;
+ *max_subkeysize = r_o.max_subkeysize;
+ *num_values = r_o.num_values ;
+ *max_valnamelen = r_o.max_valnamelen;
+ *max_valbufsize = r_o.max_valbufsize;
+ *sec_desc = r_o.sec_desc ;
+ *mod_time = r_o.mod_time ;
+ }
+ }
+
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
+
+ return valid_query;
+}
+
+/****************************************************************************
+do a REG Unknown 1A
+****************************************************************************/
+BOOL do_reg_unknown_1a(struct cli_state *cli, POLICY_HND *hnd, uint32 *unk)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ REG_Q_UNK_1A q_o;
+ BOOL valid_query = 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_UNKNOWN_1A */
+
+ DEBUG(4,("REG Unknown 1a\n"));
+
+ make_reg_q_unk_1a(&q_o, hnd);
+
+ /* turn parameters into data stream */
+ reg_io_q_unk_1a("", &q_o, &buf, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, REG_UNK_1A, &buf, &rbuf))
+ {
+ REG_R_UNK_1A r_o;
+ BOOL p;
+
+ ZERO_STRUCT(r_o);
+
+ reg_io_r_unk_1a("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("REG_UNK_1A: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ valid_query = True;
+ (*unk) = r_o.unknown;
+ }
+ }
+
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
+
+ return valid_query;
+}
+
+/****************************************************************************
+do a REG Query Info
+****************************************************************************/
+BOOL do_reg_query_info(struct cli_state *cli, POLICY_HND *hnd,
+ char *type, uint32 *unk_0, uint32 *unk_1)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ REG_Q_INFO q_o;
+ BOOL valid_query = 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_INFO */
+
+ DEBUG(4,("REG Query Info\n"));
+
+ make_reg_q_info(&q_o, hnd, "ProductType", time(NULL), 4, 1);
+
+ /* turn parameters into data stream */
+ reg_io_q_info("", &q_o, &buf, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, REG_INFO, &buf, &rbuf))
+ {
+ REG_R_INFO r_o;
+ BOOL p;
+
+ ZERO_STRUCT(r_o);
+
+ reg_io_r_info("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("REG_INFO: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ valid_query = True;
+ fstrcpy(type, buffer2_to_str(&r_o.uni_type));
+ (*unk_0) = r_o.unknown_0;
+ (*unk_1) = r_o.unknown_1;
+ }
+ }
+
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
+
+ return valid_query;
+}
+
+/****************************************************************************
+do a REG Set Key Security
+****************************************************************************/
+BOOL do_reg_set_key_sec(struct cli_state *cli, POLICY_HND *hnd, SEC_DESC_BUF *sec_desc_buf)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ REG_Q_SET_KEY_SEC q_o;
+ BOOL valid_query = 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_SET_KEY_SEC */
+
+ DEBUG(4,("REG Set Key security.\n"));
+
+ make_reg_q_set_key_sec(&q_o, hnd, sec_desc_buf);
+
+ /* turn parameters into data stream */
+ reg_io_q_set_key_sec("", &q_o, &buf, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, REG_SET_KEY_SEC, &buf, &rbuf))
+ {
+ REG_R_SET_KEY_SEC r_o;
+ BOOL p;
+
+ ZERO_STRUCT(r_o);
+
+ reg_io_r_set_key_sec("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ valid_query = True;
+ }
+ }
+
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
+
+ return valid_query;
+}
+
+/****************************************************************************
+do a REG Query Key Security
+****************************************************************************/
+
+BOOL do_reg_get_key_sec(struct cli_state *cli, POLICY_HND *hnd, uint32 *sec_buf_size, SEC_DESC_BUF **ppsec_desc_buf)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ REG_Q_GET_KEY_SEC q_o;
+ BOOL valid_query = 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_GET_KEY_SEC */
+
+ DEBUG(4,("REG query key security. buf_size: %d\n", *sec_buf_size));
+
+ make_reg_q_get_key_sec(&q_o, hnd, *sec_buf_size, NULL);
+
+ /* turn parameters into data stream */
+ reg_io_q_get_key_sec("", &q_o, &buf, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, REG_GET_KEY_SEC, &buf, &rbuf))
+ {
+ REG_R_GET_KEY_SEC r_o;
+ BOOL p;
+
+ ZERO_STRUCT(r_o);
+
+ reg_io_r_get_key_sec("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.status == 0x0000007a)
+ {
+ /*
+ * get the maximum buffer size: it was too small
+ */
+ (*sec_buf_size) = r_o.hdr_sec.buf_max_len;
+ DEBUG(5,("sec_buf_size too small. use %d\n", *sec_buf_size));
+ valid_query = True;
+ }
+ else if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("REG_GET_KEY_SEC: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+ else
+ {
+ valid_query = True;
+ (*sec_buf_size) = r_o.data->len;
+ *ppsec_desc_buf = r_o.data;
+ }
+ }
+
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
+
+ return valid_query;
+}
+
+/****************************************************************************
+do a REG Delete Value
+****************************************************************************/
+BOOL do_reg_delete_val(struct cli_state *cli, POLICY_HND *hnd, char *val_name)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ REG_Q_DELETE_VALUE q_o;
+ BOOL valid_delete = 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_DELETE_VALUE */
+
+ DEBUG(4,("REG Delete Value: %s\n", val_name));
+
+ make_reg_q_delete_val(&q_o, hnd, val_name);
+
+ /* turn parameters into data stream */
+ reg_io_q_delete_val("", &q_o, &buf, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, REG_DELETE_VALUE, &buf, &rbuf))
+ {
+ REG_R_DELETE_VALUE r_o;
+ BOOL p;
+
+ ZERO_STRUCT(r_o);
+
+ reg_io_r_delete_val("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("REG_DELETE_VALUE: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ valid_delete = True;
+ }
+ }
+
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
+
+ return valid_delete;
+}
+
+/****************************************************************************
+do a REG Delete Key
+****************************************************************************/
+BOOL do_reg_delete_key(struct cli_state *cli, POLICY_HND *hnd, char *key_name)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ REG_Q_DELETE_KEY q_o;
+ BOOL valid_delete = 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_DELETE_KEY */
+
+ DEBUG(4,("REG Delete Key: %s\n", key_name));
+
+ make_reg_q_delete_key(&q_o, hnd, key_name);
+
+ /* turn parameters into data stream */
+ reg_io_q_delete_key("", &q_o, &buf, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, REG_DELETE_KEY, &buf, &rbuf))
+ {
+ REG_R_DELETE_KEY r_o;
+ BOOL p;
+
+ ZERO_STRUCT(r_o);
+
+ reg_io_r_delete_key("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("REG_DELETE_KEY: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ valid_delete = True;
+ }
+ }
+
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
+
+ return valid_delete;
+}
+
+/****************************************************************************
+do a REG Create Key
+****************************************************************************/
+BOOL do_reg_create_key(struct cli_state *cli, POLICY_HND *hnd,
+ char *key_name, char *key_class,
+ SEC_ACCESS *sam_access,
+ POLICY_HND *key)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ REG_Q_CREATE_KEY q_o;
+ BOOL valid_create = False;
+ SEC_DESC *sec;
+ SEC_DESC_BUF *sec_buf;
+ size_t sec_len;
+
+ ZERO_STRUCT(sec);
+ ZERO_STRUCT(sec_buf);
+ ZERO_STRUCT(q_o);
+
+ 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->mask : 0));
+
+ if((sec = make_sec_desc( 1, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, NULL, &sec_len)) == NULL)
+ {
+ DEBUG(0,("make_sec_desc : malloc fail.\n"));
+ return False;
+ }
+
+ DEBUG(10,("make_sec_desc: len = %d\n", sec_len));
+
+ if((sec_buf = make_sec_desc_buf( (int)sec_len, sec)) == NULL)
+ {
+ DEBUG(0,("make_sec_desc : malloc fail (1)\n"));
+ free_sec_desc(&sec);
+ return False;
+ }
+ free_sec_desc(&sec);
+
+ make_reg_q_create_key(&q_o, hnd, key_name, key_class, sam_access, sec_buf);
+
+ /* 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));
+ }
+ }
+
+ free_sec_desc_buf(&sec_buf);
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
+
+ return valid_create;
+}
+
+/****************************************************************************
+do a REG Enum 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)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ REG_Q_ENUM_KEY q_o;
+ BOOL valid_query = 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_ENUM_KEY */
+
+ DEBUG(4,("REG Enum Key\n"));
+
+ make_reg_q_enum_key(&q_o, hnd, key_index);
+
+ /* turn parameters into data stream */
+ reg_io_q_enum_key("", &q_o, &buf, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, REG_ENUM_KEY, &buf, &rbuf))
+ {
+ REG_R_ENUM_KEY r_o;
+ BOOL p;
+
+ ZERO_STRUCT(r_o);
+
+ reg_io_r_enum_key("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("REG_ENUM_KEY: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ valid_query = True;
+ (*unk_1) = r_o.unknown_1;
+ (*unk_2) = r_o.unknown_2;
+ fstrcpy(key_name, unistr2(r_o.key_name.str.buffer));
+ (*mod_time) = nt_time_to_unix(&r_o.time);
+ }
+ }
+
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
+
+ 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
+****************************************************************************/
+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)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ REG_Q_ENUM_VALUE q_o;
+ BOOL valid_query = 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_ENUM_VALUE */
+
+ DEBUG(4,("REG Enum Value\n"));
+
+ make_reg_q_enum_val(&q_o, hnd, val_index, max_valnamelen, max_valbufsize);
+
+ /* turn parameters into data stream */
+ reg_io_q_enum_val("", &q_o, &buf, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, REG_ENUM_VALUE, &buf, &rbuf))
+ {
+ REG_R_ENUM_VALUE r_o;
+ BOOL p;
+
+ ZERO_STRUCT(r_o);
+ r_o.buf_value = value;
+
+ reg_io_r_enum_val("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("REG_ENUM_VALUE: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ valid_query = True;
+ (*val_type) = r_o.type;
+ fstrcpy(val_name, unistr2_to_str(&r_o.uni_name));
+ }
+ }
+
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
+
+ return valid_query;
+}
+
+/****************************************************************************
+do a REG Open Key
+****************************************************************************/
+BOOL do_reg_open_entry(struct cli_state *cli, POLICY_HND *hnd,
+ char *key_name, uint32 unk_0,
+ POLICY_HND *key_hnd)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ REG_Q_OPEN_ENTRY q_o;
+ BOOL valid_pol = False;
+
+ if (hnd == NULL) return False;
+
+ prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
+ prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True );
+
+ /* create and send a MSRPC command with api REG_OPEN_ENTRY */
+
+ DEBUG(4,("REG Open Entry\n"));
+
+ make_reg_q_open_entry(&q_o, hnd, key_name, unk_0);
+
+ /* turn parameters into data stream */
+ reg_io_q_open_entry("", &q_o, &buf, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, REG_OPEN_ENTRY, &buf, &rbuf))
+ {
+ REG_R_OPEN_ENTRY r_o;
+ BOOL p;
+
+ ZERO_STRUCT(r_o);
+
+ reg_io_r_open_entry("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("REG_OPEN_ENTRY: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ valid_pol = True;
+ memcpy(key_hnd, r_o.pol.data, sizeof(key_hnd->data));
+ }
+ }
+
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
+
+ return valid_pol;
+}
+
+/****************************************************************************
+do a REG Close
+****************************************************************************/
+BOOL do_reg_close(struct cli_state *cli, POLICY_HND *hnd)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ REG_Q_CLOSE q_c;
+ BOOL valid_close = False;
+
+ if (hnd == NULL) return False;
+
+ /* create and send a MSRPC command with api REG_CLOSE */
+
+ prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
+ prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True );
+
+ DEBUG(4,("REG Close\n"));
+
+ /* store the parameters */
+ make_reg_q_close(&q_c, hnd);
+
+ /* turn parameters into data stream */
+ reg_io_q_close("", &q_c, &buf, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, REG_CLOSE, &buf, &rbuf))
+ {
+ REG_R_CLOSE r_c;
+ BOOL p;
+
+ ZERO_STRUCT(r_c);
+
+ reg_io_r_close("", &r_c, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_c.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("REG_CLOSE: %s\n", get_nt_error_msg(r_c.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ /* check that the returned policy handle is all zeros */
+ int i;
+ valid_close = True;
+
+ for (i = 0; i < sizeof(r_c.pol.data); i++)
+ {
+ if (r_c.pol.data[i] != 0)
+ {
+ valid_close = False;
+ break;
+ }
+ }
+ if (!valid_close)
+ {
+ DEBUG(0,("REG_CLOSE: non-zero handle returned\n"));
+ }
+ }
+ }
+
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
+
+ return valid_close;
+}
+
+
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* removed in SAMBA_2_0 branch. */
+
+
+#ifdef SYSLOG
+#undef SYSLOG
+#endif
+
+#include "includes.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+
+
+
+/****************************************************************************
+do a SAMR query user groups
+****************************************************************************/
+BOOL get_samr_query_usergroups(struct cli_state *cli,
+ POLICY_HND *pol_open_domain, uint32 user_rid,
+ uint32 *num_groups, DOM_GID *gid)
+{
+ POLICY_HND pol_open_user;
+ if (pol_open_domain == NULL || num_groups == NULL || gid == NULL) return False;
+
+ /* send open domain (on user sid) */
+ if (!do_samr_open_user(cli,
+ pol_open_domain,
+ 0x02011b, user_rid,
+ &pol_open_user))
+ {
+ return False;
+ }
+
+ /* send user groups query */
+ if (!do_samr_query_usergroups(cli,
+ &pol_open_user,
+ num_groups, gid))
+ {
+ DEBUG(5,("do_samr_query_usergroups: error in query user groups\n"));
+ }
+
+ return do_samr_close(cli, &pol_open_user);
+}
+
+/****************************************************************************
+do a SAMR query user info
+****************************************************************************/
+BOOL get_samr_query_userinfo(struct cli_state *cli,
+ POLICY_HND *pol_open_domain,
+ uint32 info_level,
+ uint32 user_rid, SAM_USER_INFO_21 *usr)
+{
+ POLICY_HND pol_open_user;
+ if (pol_open_domain == NULL || usr == NULL) return False;
+
+ memset((char *)usr, '\0', sizeof(*usr));
+
+ /* send open domain (on user sid) */
+ if (!do_samr_open_user(cli,
+ pol_open_domain,
+ 0x02011b, user_rid,
+ &pol_open_user))
+ {
+ return False;
+ }
+
+ /* send user info query */
+ if (!do_samr_query_userinfo(cli,
+ &pol_open_user,
+ info_level, (void*)usr))
+ {
+ DEBUG(5,("do_samr_query_userinfo: error in query user info, level 0x%x\n",
+ info_level));
+ }
+
+ return do_samr_close(cli, &pol_open_user);
+}
+
+/****************************************************************************
+do a SAMR change user password command
+****************************************************************************/
+BOOL do_samr_chgpasswd_user(struct cli_state *cli,
+ char *srv_name, char *user_name,
+ char nt_newpass[516], uchar nt_oldhash[16],
+ char lm_newpass[516], uchar lm_oldhash[16])
+{
+ prs_struct data;
+ prs_struct rdata;
+
+ SAMR_Q_CHGPASSWD_USER q_e;
+ BOOL valid_pwc = False;
+
+ /* create and send a MSRPC command with api SAMR_CHGPASSWD_USER */
+
+ prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
+ prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True );
+
+ DEBUG(4,("SAMR Change User Password. server:%s username:%s\n",
+ srv_name, user_name));
+
+ make_samr_q_chgpasswd_user(&q_e, srv_name, user_name,
+ nt_newpass, nt_oldhash,
+ lm_newpass, lm_oldhash);
+
+ /* turn parameters into data stream */
+ samr_io_q_chgpasswd_user("", &q_e, &data, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, SAMR_CHGPASSWD_USER, &data, &rdata))
+ {
+ SAMR_R_CHGPASSWD_USER r_e;
+ BOOL p;
+
+ samr_io_r_chgpasswd_user("", &r_e, &rdata, 0);
+
+ p = rdata.offset != 0;
+ if (p && r_e.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("SAMR_R_CHGPASSWD_USER: %s\n", get_nt_error_msg(r_e.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ valid_pwc = True;
+ }
+ }
+
+ prs_mem_free(&data );
+ prs_mem_free(&rdata );
+
+ return valid_pwc;
+}
+
+/****************************************************************************
+do a SAMR unknown 0x38 command
+****************************************************************************/
+BOOL do_samr_unknown_38(struct cli_state *cli, char *srv_name)
+{
+ prs_struct data;
+ prs_struct rdata;
+
+ SAMR_Q_UNKNOWN_38 q_e;
+ BOOL valid_un8 = False;
+
+ /* create and send a MSRPC command with api SAMR_ENUM_DOM_USERS */
+
+ prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
+ prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True );
+
+ DEBUG(4,("SAMR Unknown 38 server:%s\n", srv_name));
+
+ make_samr_q_unknown_38(&q_e, srv_name);
+
+ /* turn parameters into data stream */
+ samr_io_q_unknown_38("", &q_e, &data, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, SAMR_UNKNOWN_38, &data, &rdata))
+ {
+ SAMR_R_UNKNOWN_38 r_e;
+ BOOL p;
+
+ samr_io_r_unknown_38("", &r_e, &rdata, 0);
+
+ p = rdata.offset != 0;
+#if 0
+ if (p && r_e.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("SAMR_R_UNKNOWN_38: %s\n", get_nt_error_msg(r_e.status)));
+ p = False;
+ }
+#endif
+ if (p)
+ {
+ valid_un8 = True;
+ }
+ }
+
+ prs_mem_free(&data );
+ prs_mem_free(&rdata );
+
+ return valid_un8;
+}
+
+/****************************************************************************
+do a SAMR unknown 0x8 command
+****************************************************************************/
+BOOL do_samr_query_dom_info(struct cli_state *cli,
+ POLICY_HND *domain_pol, uint16 switch_value)
+{
+ prs_struct data;
+ prs_struct rdata;
+
+ SAMR_Q_QUERY_DOMAIN_INFO q_e;
+ BOOL valid_un8 = False;
+
+ /* create and send a MSRPC command with api SAMR_ENUM_DOM_USERS */
+
+ prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
+ prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True );
+
+ DEBUG(4,("SAMR Unknown 8 switch:%d\n", switch_value));
+
+ if (domain_pol == NULL) return False;
+
+ /* store the parameters */
+ make_samr_q_query_dom_info(&q_e, domain_pol, switch_value);
+
+ /* turn parameters into data stream */
+ samr_io_q_query_dom_info("", &q_e, &data, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, SAMR_QUERY_DOMAIN_INFO, &data, &rdata))
+ {
+#if 0
+ SAMR_R_QUERY_DOMAIN_INFO r_e;
+ BOOL p;
+
+ samr_io_r_query_dom_info("", &r_e, &rdata, 0);
+
+ p = rdata.offset != 0;
+ if (p && r_e.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("SAMR_R_QUERY_DOMAIN_INFO: %s\n", get_nt_error_msg(r_e.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ valid_un8 = True;
+ }
+#endif
+ }
+
+ prs_mem_free(&data );
+ prs_mem_free(&rdata );
+
+ return valid_un8;
+}
+
+/****************************************************************************
+do a SAMR enumerate users
+****************************************************************************/
+BOOL do_samr_enum_dom_users(struct cli_state *cli,
+ POLICY_HND *pol, uint16 num_entries, uint16 unk_0,
+ uint16 acb_mask, uint16 unk_1, uint32 size,
+ struct acct_info **sam,
+ int *num_sam_users)
+{
+ prs_struct data;
+ prs_struct rdata;
+
+ SAMR_Q_ENUM_DOM_USERS q_e;
+ BOOL valid_pol = False;
+
+ /* create and send a MSRPC command with api SAMR_ENUM_DOM_USERS */
+
+ prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
+ prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True );
+
+ DEBUG(4,("SAMR Enum SAM DB max size:%x\n", size));
+
+ if (pol == NULL || num_sam_users == NULL) return False;
+
+ /* store the parameters */
+ make_samr_q_enum_dom_users(&q_e, pol,
+ num_entries, unk_0,
+ acb_mask, unk_1, size);
+
+ /* turn parameters into data stream */
+ samr_io_q_enum_dom_users("", &q_e, &data, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, SAMR_ENUM_DOM_USERS, &data, &rdata))
+ {
+ SAMR_R_ENUM_DOM_USERS r_e;
+ BOOL p;
+
+ samr_io_r_enum_dom_users("", &r_e, &rdata, 0);
+
+ p = rdata.offset != 0;
+ if (p && r_e.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("SAMR_R_ENUM_DOM_USERS: %s\n", get_nt_error_msg(r_e.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ int i;
+ int name_idx = 0;
+
+ *num_sam_users = r_e.num_entries2;
+ if (*num_sam_users > MAX_SAM_ENTRIES)
+ {
+ *num_sam_users = MAX_SAM_ENTRIES;
+ DEBUG(2,("do_samr_enum_dom_users: sam user entries limited to %d\n",
+ *num_sam_users));
+ }
+
+ *sam = (struct acct_info*) malloc(sizeof(struct acct_info) * (*num_sam_users));
+
+ if ((*sam) == NULL)
+ {
+ *num_sam_users = 0;
+ }
+
+ for (i = 0; i < *num_sam_users; i++)
+ {
+
+ (*sam)[i].smb_userid = r_e.sam[i].rid;
+ if (r_e.sam[i].hdr_name.buffer)
+ {
+ char *acct_name = unistrn2(r_e.uni_acct_name[name_idx].buffer,
+ r_e.uni_acct_name[name_idx].uni_str_len);
+ fstrcpy((*sam)[i].acct_name, acct_name);
+ name_idx++;
+ }
+ else
+ {
+ memset((char *)(*sam)[i].acct_name, '\0', sizeof((*sam)[i].acct_name));
+ }
+ DEBUG(5,("do_samr_enum_dom_users: idx: %4d rid: %8x acct: %s\n",
+ i, (*sam)[i].smb_userid, (*sam)[i].acct_name));
+ }
+ valid_pol = True;
+ }
+ }
+
+ prs_mem_free(&data );
+ prs_mem_free(&rdata );
+
+ return valid_pol;
+}
+
+/****************************************************************************
+do a SAMR Connect
+****************************************************************************/
+BOOL do_samr_connect(struct cli_state *cli,
+ char *srv_name, uint32 unknown_0,
+ POLICY_HND *connect_pol)
+{
+ prs_struct data;
+ prs_struct rdata;
+
+ SAMR_Q_CONNECT q_o;
+ BOOL valid_pol = False;
+
+ /* create and send a MSRPC command with api SAMR_CONNECT */
+
+ prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
+ prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True );
+
+ DEBUG(4,("SAMR Open Policy server:%s undoc value:%x\n",
+ srv_name, unknown_0));
+
+ if (srv_name == NULL || connect_pol == NULL) return False;
+
+ /* store the parameters */
+ make_samr_q_connect(&q_o, srv_name, unknown_0);
+
+ /* turn parameters into data stream */
+ samr_io_q_connect("", &q_o, &data, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, SAMR_CONNECT, &data, &rdata))
+ {
+ SAMR_R_CONNECT r_o;
+ BOOL p;
+
+ samr_io_r_connect("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("SAMR_R_CONNECT: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ memcpy(connect_pol, &r_o.connect_pol, sizeof(r_o.connect_pol));
+ valid_pol = True;
+ }
+ }
+
+ prs_mem_free(&data );
+ prs_mem_free(&rdata );
+
+ return valid_pol;
+}
+
+/****************************************************************************
+do a SAMR Open User
+****************************************************************************/
+BOOL do_samr_open_user(struct cli_state *cli,
+ POLICY_HND *pol, uint32 unk_0, uint32 rid,
+ POLICY_HND *user_pol)
+{
+ prs_struct data;
+ prs_struct rdata;
+
+ SAMR_Q_OPEN_USER q_o;
+ BOOL valid_pol = False;
+
+ /* create and send a MSRPC command with api SAMR_OPEN_USER */
+
+ prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
+ prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True );
+
+ DEBUG(4,("SAMR Open User. unk_0: %08x RID:%x\n",
+ unk_0, rid));
+
+ if (pol == NULL || user_pol == NULL) return False;
+
+ /* store the parameters */
+ make_samr_q_open_user(&q_o, pol, unk_0, rid);
+
+ /* turn parameters into data stream */
+ samr_io_q_open_user("", &q_o, &data, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, SAMR_OPEN_USER, &data, &rdata))
+ {
+ SAMR_R_OPEN_USER r_o;
+ BOOL p;
+
+ samr_io_r_open_user("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("SAMR_R_OPEN_USER: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ memcpy(user_pol, &r_o.user_pol, sizeof(r_o.user_pol));
+ valid_pol = True;
+ }
+ }
+
+ prs_mem_free(&data );
+ prs_mem_free(&rdata );
+
+ return valid_pol;
+}
+
+/****************************************************************************
+do a SAMR Open Domain
+****************************************************************************/
+BOOL do_samr_open_domain(struct cli_state *cli,
+ POLICY_HND *connect_pol, uint32 rid, DOM_SID *sid,
+ POLICY_HND *domain_pol)
+{
+ pstring sid_str;
+ prs_struct data;
+ prs_struct rdata;
+
+ SAMR_Q_OPEN_DOMAIN q_o;
+ BOOL valid_pol = False;
+
+ /* create and send a MSRPC command with api SAMR_OPEN_DOMAIN */
+
+ prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
+ prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True );
+
+ sid_to_string(sid_str, sid);
+ DEBUG(4,("SAMR Open Domain. SID:%s RID:%x\n", sid_str, rid));
+
+ if (connect_pol == NULL || sid == NULL || domain_pol == NULL) return False;
+
+ /* store the parameters */
+ make_samr_q_open_domain(&q_o, connect_pol, rid, sid);
+
+ /* turn parameters into data stream */
+ samr_io_q_open_domain("", &q_o, &data, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, SAMR_OPEN_DOMAIN, &data, &rdata))
+ {
+ SAMR_R_OPEN_DOMAIN r_o;
+ BOOL p;
+
+ samr_io_r_open_domain("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("SAMR_R_OPEN_DOMAIN: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ memcpy(domain_pol, &r_o.domain_pol, sizeof(r_o.domain_pol));
+ valid_pol = True;
+ }
+ }
+
+ prs_mem_free(&data );
+ prs_mem_free(&rdata );
+
+ return valid_pol;
+}
+
+/****************************************************************************
+do a SAMR Query Unknown 12
+****************************************************************************/
+BOOL do_samr_query_unknown_12(struct cli_state *cli,
+ POLICY_HND *pol, uint32 rid, uint32 num_gids, uint32 *gids,
+ uint32 *num_aliases,
+ fstring als_names [MAX_LOOKUP_SIDS],
+ uint32 num_als_users[MAX_LOOKUP_SIDS])
+{
+ prs_struct data;
+ prs_struct rdata;
+
+ SAMR_Q_UNKNOWN_12 q_o;
+ BOOL valid_query = False;
+
+ /* create and send a MSRPC command with api SAMR_UNKNOWN_12 */
+
+ prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
+ prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True );
+
+ DEBUG(4,("SAMR Query Unknown 12.\n"));
+
+ if (pol == NULL || rid == 0 || num_gids == 0 || gids == NULL ||
+ num_aliases == NULL || als_names == NULL || num_als_users == NULL ) return False;
+
+ /* store the parameters */
+ make_samr_q_unknown_12(&q_o, pol, rid, num_gids, gids);
+
+ /* turn parameters into data stream */
+ samr_io_q_unknown_12("", &q_o, &data, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, SAMR_UNKNOWN_12, &data, &rdata))
+ {
+ SAMR_R_UNKNOWN_12 r_o;
+ BOOL p;
+
+ samr_io_r_unknown_12("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("SAMR_R_UNKNOWN_12: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ if (r_o.ptr_aliases != 0 && r_o.ptr_als_usrs != 0 &&
+ r_o.num_als_usrs1 == r_o.num_aliases1)
+ {
+ int i;
+
+ valid_query = True;
+ *num_aliases = r_o.num_aliases1;
+
+ for (i = 0; i < r_o.num_aliases1; i++)
+ {
+ fstrcpy(als_names[i], unistrn2(r_o.uni_als_name[i].buffer, r_o.uni_als_name[i].uni_str_len));
+ }
+ for (i = 0; i < r_o.num_als_usrs1; i++)
+ {
+ num_als_users[i] = r_o.num_als_usrs[i];
+ }
+ }
+ else if (r_o.ptr_aliases == 0 && r_o.ptr_als_usrs == 0)
+ {
+ valid_query = True;
+ *num_aliases = 0;
+ }
+ else
+ {
+ p = False;
+ }
+ }
+ }
+
+ prs_mem_free(&data );
+ prs_mem_free(&rdata );
+
+ return valid_query;
+}
+
+/****************************************************************************
+do a SAMR Query User Groups
+****************************************************************************/
+BOOL do_samr_query_usergroups(struct cli_state *cli,
+ POLICY_HND *pol, uint32 *num_groups, DOM_GID *gid)
+{
+ prs_struct data;
+ prs_struct rdata;
+
+ SAMR_Q_QUERY_USERGROUPS q_o;
+ BOOL valid_query = False;
+
+ /* create and send a MSRPC command with api SAMR_QUERY_USERGROUPS */
+
+ prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
+ prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True );
+
+ DEBUG(4,("SAMR Query User Groups.\n"));
+
+ if (pol == NULL || gid == NULL || num_groups == 0) return False;
+
+ /* store the parameters */
+ make_samr_q_query_usergroups(&q_o, pol);
+
+ /* turn parameters into data stream */
+ samr_io_q_query_usergroups("", &q_o, &data, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, SAMR_QUERY_USERGROUPS, &data, &rdata))
+ {
+ SAMR_R_QUERY_USERGROUPS r_o;
+ BOOL p;
+
+ /* get user info */
+ r_o.gid = gid;
+
+ samr_io_r_query_usergroups("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("SAMR_R_QUERY_USERGROUPS: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p && r_o.ptr_0 != 0)
+ {
+ valid_query = True;
+ *num_groups = r_o.num_entries;
+ }
+
+ }
+
+ prs_mem_free(&data );
+ prs_mem_free(&rdata );
+
+ return valid_query;
+}
+
+/****************************************************************************
+do a SAMR Query User Info
+****************************************************************************/
+BOOL do_samr_query_userinfo(struct cli_state *cli,
+ POLICY_HND *pol, uint16 switch_value, void* usr)
+{
+ prs_struct data;
+ prs_struct rdata;
+
+ SAMR_Q_QUERY_USERINFO q_o;
+ BOOL valid_query = False;
+
+ /* create and send a MSRPC command with api SAMR_QUERY_USERINFO */
+
+ prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
+ prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True );
+
+ DEBUG(4,("SAMR Query User Info. level: %d\n", switch_value));
+
+ if (pol == NULL || usr == NULL || switch_value == 0) return False;
+
+ /* store the parameters */
+ make_samr_q_query_userinfo(&q_o, pol, switch_value);
+
+ /* turn parameters into data stream */
+ samr_io_q_query_userinfo("", &q_o, &data, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, SAMR_QUERY_USERINFO, &data, &rdata))
+ {
+ SAMR_R_QUERY_USERINFO r_o;
+ BOOL p;
+
+ /* get user info */
+ r_o.info.id = usr;
+
+ samr_io_r_query_userinfo("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("SAMR_R_QUERY_USERINFO: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p && r_o.switch_value != switch_value)
+ {
+ DEBUG(0,("SAMR_R_QUERY_USERINFO: received incorrect level %d\n",
+ r_o.switch_value));
+ }
+
+ if (p && r_o.ptr != 0)
+ {
+ valid_query = True;
+ }
+ }
+
+ prs_mem_free(&data );
+ prs_mem_free(&rdata );
+
+ return valid_query;
+}
+
+/****************************************************************************
+do a SAMR Close
+****************************************************************************/
+BOOL do_samr_close(struct cli_state *cli, POLICY_HND *hnd)
+{
+ prs_struct data;
+ prs_struct rdata;
+
+ SAMR_Q_CLOSE_HND q_c;
+ BOOL valid_close = False;
+
+ prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
+ prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True );
+
+ if (hnd == NULL) return False;
+
+ /* create and send a MSRPC command with api SAMR_CLOSE_HND */
+
+ DEBUG(4,("SAMR Close\n"));
+
+ /* store the parameters */
+ make_samr_q_close_hnd(&q_c, hnd);
+
+ /* turn parameters into data stream */
+ samr_io_q_close_hnd("", &q_c, &data, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, SAMR_CLOSE_HND, &data, &rdata))
+ {
+ SAMR_R_CLOSE_HND r_c;
+ BOOL p;
+
+ samr_io_r_close_hnd("", &r_c, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_c.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("SAMR_CLOSE_HND: %s\n", get_nt_error_msg(r_c.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ /* check that the returned policy handle is all zeros */
+ int i;
+ valid_close = True;
+
+ for (i = 0; i < sizeof(r_c.pol.data); i++)
+ {
+ if (r_c.pol.data[i] != 0)
+ {
+ valid_close = False;
+ break;
+ }
+ }
+ if (!valid_close)
+ {
+ DEBUG(0,("SAMR_CLOSE_HND: non-zero handle returned\n"));
+ }
+ }
+ }
+
+ prs_mem_free(&data );
+ prs_mem_free(&rdata );
+
+ return valid_close;
+}
+
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* removed in SAMBA_2_0 branch. */
+
+#ifdef SYSLOG
+#undef SYSLOG
+#endif
+
+#include "includes.h"
+
+extern int DEBUGLEVEL;
+
+/****************************************************************************
+do a server net conn enum
+****************************************************************************/
+BOOL do_srv_net_srv_conn_enum(struct cli_state *cli,
+ char *server_name, char *qual_name,
+ uint32 switch_value, SRV_CONN_INFO_CTR *ctr,
+ uint32 preferred_len,
+ ENUM_HND *hnd)
+{
+ prs_struct data;
+ prs_struct rdata;
+ SRV_Q_NET_CONN_ENUM q_o;
+ BOOL valid_enum = False;
+
+ if (server_name == NULL || ctr == NULL || preferred_len == 0) return False;
+
+ prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
+ prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True );
+
+ /* create and send a MSRPC command with api SRV_NETCONNENUM */
+
+ DEBUG(4,("SRV Net Server Connection Enum(%s, %s), level %d, enum:%8x\n",
+ server_name, qual_name, switch_value, get_enum_hnd(hnd)));
+
+ ctr->switch_value = switch_value;
+ ctr->ptr_conn_ctr = 1;
+ ctr->conn.info0.num_entries_read = 0;
+ ctr->conn.info0.ptr_conn_info = 1;
+
+ /* store the parameters */
+ make_srv_q_net_conn_enum(&q_o, server_name, qual_name,
+ switch_value, ctr,
+ preferred_len,
+ hnd);
+
+ /* turn parameters into data stream */
+ srv_io_q_net_conn_enum("", &q_o, &data, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, SRV_NETCONNENUM, &data, &rdata))
+ {
+ SRV_R_NET_CONN_ENUM r_o;
+ BOOL p;
+
+ r_o.ctr = ctr;
+
+ srv_io_r_net_conn_enum("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("SRV_R_NET_SRV_GET_INFO: %s\n", get_nt_error_msg(r_o.status)));
+ p = 0;
+ }
+
+ if (p && r_o.ctr->switch_value != switch_value)
+ {
+ /* different switch levels. oops. */
+ DEBUG(0,("SRV_R_NET_SRV_CONN_ENUM: info class %d does not match request %d\n",
+ r_o.ctr->switch_value, switch_value));
+ p = 0;
+ }
+
+ if (p)
+ {
+ /* ok, at last: we're happy. */
+ valid_enum = True;
+ }
+ }
+
+ prs_mem_free(&data );
+ prs_mem_free(&rdata );
+
+ return valid_enum;
+}
+
+/****************************************************************************
+do a server net sess enum
+****************************************************************************/
+BOOL do_srv_net_srv_sess_enum(struct cli_state *cli,
+ char *server_name, char *qual_name,
+ uint32 switch_value, SRV_SESS_INFO_CTR *ctr,
+ uint32 preferred_len,
+ ENUM_HND *hnd)
+{
+ prs_struct data;
+ prs_struct rdata;
+ SRV_Q_NET_SESS_ENUM q_o;
+ BOOL valid_enum = False;
+
+ if (server_name == NULL || ctr == NULL || preferred_len == 0) return False;
+
+ prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
+ prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True );
+
+ /* create and send a MSRPC command with api SRV_NETSESSENUM */
+
+ DEBUG(4,("SRV Net Session Enum (%s), level %d, enum:%8x\n",
+ server_name, switch_value, get_enum_hnd(hnd)));
+
+ ctr->switch_value = switch_value;
+ ctr->ptr_sess_ctr = 1;
+ ctr->sess.info0.num_entries_read = 0;
+ ctr->sess.info0.ptr_sess_info = 1;
+
+ /* store the parameters */
+ make_srv_q_net_sess_enum(&q_o, server_name, qual_name,
+ switch_value, ctr,
+ preferred_len,
+ hnd);
+
+ /* turn parameters into data stream */
+ srv_io_q_net_sess_enum("", &q_o, &data, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, SRV_NETSESSENUM, &data, &rdata))
+ {
+ SRV_R_NET_SESS_ENUM r_o;
+ BOOL p;
+
+ r_o.ctr = ctr;
+
+ srv_io_r_net_sess_enum("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("SRV_R_NET_SRV_GET_INFO: %s\n", get_nt_error_msg(r_o.status)));
+ p = 0;
+ }
+
+ if (p && r_o.ctr->switch_value != switch_value)
+ {
+ /* different switch levels. oops. */
+ DEBUG(0,("SRV_R_NET_SRV_SESS_ENUM: info class %d does not match request %d\n",
+ r_o.ctr->switch_value, switch_value));
+ p = 0;
+ }
+
+ if (p)
+ {
+ /* ok, at last: we're happy. */
+ valid_enum = True;
+ }
+ }
+
+ prs_mem_free(&data );
+ prs_mem_free(&rdata );
+
+ return valid_enum;
+}
+
+/****************************************************************************
+do a server net share enum
+****************************************************************************/
+BOOL do_srv_net_srv_share_enum(struct cli_state *cli,
+ char *server_name,
+ uint32 switch_value, SRV_SHARE_INFO_CTR *ctr,
+ uint32 preferred_len,
+ ENUM_HND *hnd)
+{
+ prs_struct data;
+ prs_struct rdata;
+ SRV_Q_NET_SHARE_ENUM q_o;
+ BOOL valid_enum = False;
+
+ if (server_name == NULL || ctr == NULL || preferred_len == 0) return False;
+
+ prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
+ prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True );
+
+ /* create and send a MSRPC command with api SRV_NETSHAREENUM */
+
+ DEBUG(4,("SRV Get Share Info (%s), level %d, enum:%8x\n",
+ server_name, switch_value, get_enum_hnd(hnd)));
+
+ q_o.share_level = switch_value;
+
+ ctr->switch_value = switch_value;
+ ctr->ptr_share_ctr = 1;
+ ctr->share.info1.num_entries_read = 0;
+ ctr->share.info1.ptr_share_info = 1;
+
+ /* store the parameters */
+ make_srv_q_net_share_enum(&q_o, server_name,
+ switch_value, ctr,
+ preferred_len,
+ hnd);
+
+ /* turn parameters into data stream */
+ srv_io_q_net_share_enum("", &q_o, &data, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, SRV_NETSHAREENUM, &data, &rdata))
+ {
+ SRV_R_NET_SHARE_ENUM r_o;
+ BOOL p;
+
+ r_o.ctr = ctr;
+
+ srv_io_r_net_share_enum("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("SRV_R_NET_SRV_GET_INFO: %s\n", get_nt_error_msg(r_o.status)));
+ p = 0;
+ }
+
+ if (p && r_o.ctr->switch_value != switch_value)
+ {
+ /* different switch levels. oops. */
+ DEBUG(0,("SRV_R_NET_SRV_SHARE_ENUM: info class %d does not match request %d\n",
+ r_o.ctr->switch_value, switch_value));
+ p = 0;
+ }
+
+ if (p)
+ {
+ /* ok, at last: we're happy. */
+ valid_enum = True;
+ }
+ }
+
+ prs_mem_free(&data );
+ prs_mem_free(&rdata );
+
+ return valid_enum;
+}
+
+/****************************************************************************
+do a server net file enum
+****************************************************************************/
+BOOL do_srv_net_srv_file_enum(struct cli_state *cli,
+ char *server_name, char *qual_name,
+ uint32 switch_value, SRV_FILE_INFO_CTR *ctr,
+ uint32 preferred_len,
+ ENUM_HND *hnd)
+{
+ prs_struct data;
+ prs_struct rdata;
+ SRV_Q_NET_FILE_ENUM q_o;
+ BOOL valid_enum = False;
+
+ if (server_name == NULL || ctr == NULL || preferred_len == 0) return False;
+
+ prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
+ prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True );
+
+ /* create and send a MSRPC command with api SRV_NETFILEENUM */
+
+ DEBUG(4,("SRV Get File Info (%s), level %d, enum:%8x\n",
+ server_name, switch_value, get_enum_hnd(hnd)));
+
+ q_o.file_level = switch_value;
+
+ ctr->switch_value = switch_value;
+ ctr->ptr_file_ctr = 1;
+ ctr->file.info3.num_entries_read = 0;
+ ctr->file.info3.ptr_file_info = 1;
+
+ /* store the parameters */
+ make_srv_q_net_file_enum(&q_o, server_name, qual_name,
+ switch_value, ctr,
+ preferred_len,
+ hnd);
+
+ /* turn parameters into data stream */
+ srv_io_q_net_file_enum("", &q_o, &data, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, SRV_NETFILEENUM, &data, &rdata))
+ {
+ SRV_R_NET_FILE_ENUM r_o;
+ BOOL p;
+
+ r_o.ctr = ctr;
+
+ srv_io_r_net_file_enum("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("SRV_R_NET_SRV_GET_INFO: %s\n", get_nt_error_msg(r_o.status)));
+ p = 0;
+ }
+
+ if (p && r_o.ctr->switch_value != switch_value)
+ {
+ /* different switch levels. oops. */
+ DEBUG(0,("SRV_R_NET_SRV_FILE_ENUM: info class %d does not match request %d\n",
+ r_o.ctr->switch_value, switch_value));
+ p = 0;
+ }
+
+ if (p)
+ {
+ /* ok, at last: we're happy. */
+ valid_enum = True;
+ }
+ }
+
+ prs_mem_free(&data );
+ prs_mem_free(&rdata );
+
+ return valid_enum;
+}
+
+/****************************************************************************
+do a server get info
+****************************************************************************/
+BOOL do_srv_net_srv_get_info(struct cli_state *cli,
+ char *server_name, uint32 switch_value, SRV_INFO_CTR *ctr)
+{
+ prs_struct data;
+ prs_struct rdata;
+ SRV_Q_NET_SRV_GET_INFO q_o;
+ BOOL valid_info = False;
+
+ if (server_name == NULL || switch_value == 0 || ctr == NULL) return False;
+
+ prs_init(&data , 1024, 4, SAFETY_MARGIN, False);
+ prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True );
+
+ /* create and send a MSRPC command with api SRV_NET_SRV_GET_INFO */
+
+ DEBUG(4,("SRV Get Server Info (%s), level %d\n", server_name, switch_value));
+
+ /* store the parameters */
+ make_srv_q_net_srv_get_info(&q_o, server_name, switch_value);
+
+ /* turn parameters into data stream */
+ srv_io_q_net_srv_get_info("", &q_o, &data, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, SRV_NET_SRV_GET_INFO, &data, &rdata))
+ {
+ SRV_R_NET_SRV_GET_INFO r_o;
+ BOOL p;
+
+ r_o.ctr = ctr;
+
+ srv_io_r_net_srv_get_info("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("SRV_R_NET_SRV_GET_INFO: %s\n", get_nt_error_msg(r_o.status)));
+ p = 0;
+ }
+
+ if (p && r_o.ctr->switch_value != q_o.switch_value)
+ {
+ /* different switch levels. oops. */
+ DEBUG(0,("SRV_R_NET_SRV_GET_INFO: info class %d does not match request %d\n",
+ r_o.ctr->switch_value, q_o.switch_value));
+ p = 0;
+ }
+
+ if (p)
+ {
+ /* ok, at last: we're happy. */
+ valid_info = True;
+ }
+ }
+
+ prs_mem_free(&data );
+ prs_mem_free(&rdata );
+
+ return valid_info;
+}
+
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* removed in SAMBA_2_0 branch. */
+
+#ifdef SYSLOG
+#undef SYSLOG
+#endif
+
+#include "includes.h"
+
+extern int DEBUGLEVEL;
+
+/****************************************************************************
+do a WKS Open Policy
+****************************************************************************/
+BOOL do_wks_query_info(struct cli_state *cli,
+ char *server_name, uint32 switch_value,
+ WKS_INFO_100 *wks100)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ WKS_Q_QUERY_INFO q_o;
+ BOOL valid_info = False;
+
+ if (server_name == 0 || wks100 == 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 WKS_QUERY_INFO */
+
+ DEBUG(4,("WKS Query Info\n"));
+
+ /* store the parameters */
+ make_wks_q_query_info(&q_o, server_name, switch_value);
+
+ /* turn parameters into data stream */
+ wks_io_q_query_info("", &q_o, &buf, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, WKS_QUERY_INFO, &buf, &rbuf))
+ {
+ WKS_R_QUERY_INFO r_o;
+ BOOL p;
+
+ r_o.wks100 = wks100;
+
+ wks_io_r_query_info("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("WKS_R_QUERY_INFO: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ valid_info = True;
+ }
+ }
+
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
+
+ return valid_info;
+}
+
extern int DEBUGLEVEL;
+static void lsa_io_trans_names(char *desc, LSA_TRANS_NAME_ENUM *trn, prs_struct *ps, int depth);
+
+/*******************************************************************
+creates a LSA_TRANS_NAME structure.
+********************************************************************/
+void make_lsa_trans_name(LSA_TRANS_NAME *trn, UNISTR2 *uni_name,
+ uint32 sid_name_use, char *name, uint32 idx)
+{
+ int len_name = strlen(name);
+
+ trn->sid_name_use = sid_name_use;
+ make_uni_hdr(&(trn->hdr_name), len_name, len_name, len_name != 0);
+ make_unistr2(uni_name, name, len_name);
+ trn->domain_idx = idx;
+}
+
+/*******************************************************************
+reads or writes a LSA_TRANS_NAME structure.
+********************************************************************/
+static void lsa_io_trans_name(char *desc, LSA_TRANS_NAME *trn, prs_struct *ps, int depth)
+{
+ if (trn == NULL) return;
+
+ prs_debug(ps, depth, desc, "lsa_io_trans_name");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("sid_name_use", ps, depth, &(trn->sid_name_use));
+ smb_io_unihdr ("hdr_name", &(trn->hdr_name), ps, depth);
+ prs_uint32("domain_idx ", ps, depth, &(trn->domain_idx ));
+}
+
+/*******************************************************************
+reads or writes a DOM_R_REF structure.
+********************************************************************/
+static void lsa_io_dom_r_ref(char *desc, DOM_R_REF *r_r, prs_struct *ps, int depth)
+{
+ int i, s, n;
+
+ prs_debug(ps, depth, desc, "smb_io_dom_r_ref");
+ depth++;
+
+ if (r_r == NULL) return;
+
+ prs_align(ps);
+
+ prs_uint32("undoc_buffer ", ps, depth, &(r_r->undoc_buffer )); /* undocumented buffer pointer. */
+ prs_uint32("num_ref_doms_1", ps, depth, &(r_r->num_ref_doms_1)); /* num referenced domains? */
+ prs_uint32("undoc_buffer2 ", ps, depth, &(r_r->undoc_buffer2 )); /* undocumented buffer pointer. */
+ prs_uint32("max_entries ", ps, depth, &(r_r->max_entries )); /* 32 - max number of entries */
+ prs_uint32("num_ref_doms_2", ps, depth, &(r_r->num_ref_doms_2)); /* 4 - num referenced domains? */
+
+ SMB_ASSERT_ARRAY(r_r->hdr_ref_dom, r_r->num_ref_doms_1-1);
+ SMB_ASSERT_ARRAY(r_r->ref_dom, r_r->num_ref_doms_2);
+
+ for (i = 0; i < r_r->num_ref_doms_1; i++)
+ {
+ fstring t;
+
+ slprintf(t, sizeof(t) - 1, "dom_ref[%d] ", i);
+ smb_io_unihdr(t, &(r_r->hdr_ref_dom[i].hdr_dom_name), ps, depth);
+
+ slprintf(t, sizeof(t) - 1, "sid_ptr[%d] ", i);
+ prs_uint32(t, ps, depth, &(r_r->hdr_ref_dom[i].ptr_dom_sid));
+ }
+
+ for (i = 0, n = 0, s = 0; i < r_r->num_ref_doms_2; i++)
+ {
+ fstring t;
+
+ if (r_r->hdr_ref_dom[i].hdr_dom_name.buffer != 0)
+ {
+ slprintf(t, sizeof(t) - 1, "dom_ref[%d] ", i);
+ smb_io_unistr2(t, &(r_r->ref_dom[n].uni_dom_name), True, ps, depth); /* domain name unicode string */
+ n++;
+ }
+
+ if (r_r->hdr_ref_dom[i].ptr_dom_sid != 0)
+ {
+ slprintf(t, sizeof(t) - 1, "sid_ptr[%d] ", i);
+ smb_io_dom_sid2("", &(r_r->ref_dom[s].ref_dom), ps, depth); /* referenced domain SIDs */
+ s++;
+ }
+ }
+}
+
+
/*******************************************************************
makes an LSA_SEC_QOS structure.
********************************************************************/
prs_uint32("status", ps, depth, &(r_q->status));
}
+/*******************************************************************
+makes a LSA_SID_ENUM structure.
+********************************************************************/
+void make_lsa_sid_enum(LSA_SID_ENUM *sen, int num_entries, DOM_SID **sids)
+{
+ int i, i2;
+ if (sen == NULL || sids == NULL) return;
+
+ DEBUG(5,("make_lsa_sid_enum\n"));
+
+ sen->num_entries = num_entries;
+ sen->ptr_sid_enum = num_entries != 0 ? 1 : 0;
+ sen->num_entries2 = num_entries;
+
+ SMB_ASSERT_ARRAY(sen->sid, sen->num_entries);
+
+ for (i = 0, i2 = 0; i < num_entries; i++)
+ {
+ if (sids[i] != NULL)
+ {
+ sen->ptr_sid[i] = 1;
+ make_dom_sid2(&(sen->sid[i2]), sids[i]);
+ i2++;
+ }
+ else
+ {
+ sen->ptr_sid[i] = 0;
+ }
+ }
+}
+
+/*******************************************************************
+reads or writes a LSA_SID_ENUM structure.
+********************************************************************/
+static void lsa_io_sid_enum(char *desc, LSA_SID_ENUM *sen,
+ prs_struct *ps, int depth)
+{
+ int i;
+
+ if (sen == NULL) return;
+
+ prs_debug(ps, depth, desc, "lsa_io_sid_enum");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("num_entries ", ps, depth, &(sen->num_entries));
+ prs_uint32("ptr_sid_enum", ps, depth, &(sen->ptr_sid_enum));
+ prs_uint32("num_entries2", ps, depth, &(sen->num_entries2));
+
+ SMB_ASSERT_ARRAY(sen->ptr_sid, sen->num_entries);
+
+ for (i = 0; i < sen->num_entries; i++)
+ {
+ fstring temp;
+ slprintf(temp, sizeof(temp) - 1, "ptr_sid[%d]", i);
+ prs_uint32(temp, ps, depth, &(sen->ptr_sid[i])); /* domain SID pointers to be looked up. */
+ }
+
+ SMB_ASSERT_ARRAY(sen->sid, sen->num_entries);
+
+ for (i = 0; i < sen->num_entries; i++)
+ {
+ fstring temp;
+ slprintf(temp, sizeof(temp) - 1, "sid[%d]", i);
+ smb_io_dom_sid2(temp, &(sen->sid[i]), ps, depth); /* domain SIDs to be looked up. */
+ }
+}
+
+/*******************************************************************
+makes an LSA_R_ENUM_TRUST_DOM structure.
+********************************************************************/
+void make_q_lookup_sids(LSA_Q_LOOKUP_SIDS *q_l, POLICY_HND *hnd,
+ int num_sids, DOM_SID **sids,
+ uint16 level)
+{
+ if (q_l == NULL) return;
+
+ DEBUG(5,("make_r_enum_trust_dom\n"));
+
+ memcpy(&(q_l->pol), hnd, sizeof(q_l->pol));
+ make_lsa_sid_enum(&(q_l->sids), num_sids, sids);
+
+ q_l->names.num_entries = 0;
+ q_l->names.ptr_trans_names = 0;
+ q_l->names.num_entries2 = 0;
+
+ q_l->level.value = level;
+}
+
+/*******************************************************************
+reads or writes a LSA_Q_LOOKUP_SIDS structure.
+********************************************************************/
+void lsa_io_q_lookup_sids(char *desc, LSA_Q_LOOKUP_SIDS *q_s, prs_struct *ps, int depth)
+{
+ if (q_s == NULL) return;
+
+ prs_debug(ps, depth, desc, "lsa_io_q_lookup_sids");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd ("pol_hnd", &(q_s->pol), ps, depth); /* policy handle */
+ lsa_io_sid_enum ("sids ", &(q_s->sids ), ps, depth); /* sids to be looked up */
+ lsa_io_trans_names ("names ", &(q_s->names ), ps, depth); /* translated names */
+ smb_io_lookup_level("switch ", &(q_s->level ), ps, depth); /* lookup level */
+
+ prs_uint32("mapped_count", ps, depth, &(q_s->mapped_count));
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static void lsa_io_trans_names(char *desc, LSA_TRANS_NAME_ENUM *trn,
+ prs_struct *ps, int depth)
+{
+ int i;
+ int i2;
+
+ if (trn == NULL) return;
+
+ prs_debug(ps, depth, desc, "lsa_io_trans_names");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("num_entries ", ps, depth, &(trn->num_entries));
+ prs_uint32("ptr_trans_names", ps, depth, &(trn->ptr_trans_names));
+
+ if (trn->ptr_trans_names != 0)
+ {
+ prs_uint32("num_entries2 ", ps, depth, &(trn->num_entries2));
+
+ SMB_ASSERT_ARRAY(trn->name, trn->num_entries);
+
+ for (i = 0, i2 = 0; i < trn->num_entries2; i++)
+ {
+ fstring t;
+ slprintf(t, sizeof(t) - 1, "name[%d] ", i);
+
+ lsa_io_trans_name(t, &(trn->name[i]), ps, depth); /* translated name */
+
+ if (trn->name[i].hdr_name.buffer != 0)
+ {
+ smb_io_unistr2(t, &(trn->uni_name[i2]), 1, ps, depth);
+ prs_align(ps);
+ i2++;
+ }
+ }
+ }
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void lsa_io_r_lookup_sids(char *desc, LSA_R_LOOKUP_SIDS *r_s, prs_struct *ps, int depth)
+{
+ if (r_s == NULL) return;
+
+ prs_debug(ps, depth, desc, "lsa_io_r_lookup_sids");
+ depth++;
+
+ prs_align(ps);
+
+ lsa_io_dom_r_ref ("dom_ref", r_s->dom_ref, ps, depth); /* domain reference info */
+ lsa_io_trans_names("names ", r_s->names , ps, depth); /* translated names */
+
+ prs_align(ps);
+
+ prs_uint32("mapped_count", ps, depth, &(r_s->mapped_count));
+
+ prs_uint32("status ", ps, depth, &(r_s->status));
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void lsa_io_q_lookup_rids(char *desc, LSA_Q_LOOKUP_RIDS *q_r, prs_struct *ps, int depth)
+{
+ int i;
+
+ if (q_r == NULL) return;
+
+ prs_debug(ps, depth, desc, "lsa_io_q_lookup_rids");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("", &(q_r->pol), ps, depth); /* policy handle */
+
+ prs_uint32("num_entries ", ps, depth, &(q_r->num_entries));
+ prs_uint32("num_entries2 ", ps, depth, &(q_r->num_entries2));
+ prs_uint32("buffer_dom_sid ", ps, depth, &(q_r->buffer_dom_sid)); /* undocumented domain SID buffer pointer */
+ prs_uint32("buffer_dom_name", ps, depth, &(q_r->buffer_dom_name)); /* undocumented domain name buffer pointer */
+
+ SMB_ASSERT_ARRAY(q_r->lookup_name, q_r->num_entries);
+
+ for (i = 0; i < q_r->num_entries; i++)
+ {
+ 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);
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void lsa_io_r_lookup_rids(char *desc, LSA_R_LOOKUP_RIDS *r_r, prs_struct *ps, int depth)
+{
+ int i;
+
+ if (r_r == NULL) return;
+
+ prs_debug(ps, depth, desc, "lsa_io_r_lookup_rids");
+ depth++;
+
+ prs_align(ps);
+
+ lsa_io_dom_r_ref("", &(r_r->dom_ref), ps, depth); /* domain reference info */
+
+ prs_uint32("num_entries ", ps, depth, &(r_r->num_entries));
+ prs_uint32("undoc_buffer", ps, depth, &(r_r->undoc_buffer));
+ prs_uint32("num_entries2", ps, depth, &(r_r->num_entries2));
+
+ SMB_ASSERT_ARRAY(r_r->dom_rid, r_r->num_entries2);
+
+ for (i = 0; i < r_r->num_entries2; i++)
+ {
+ smb_io_dom_rid2("", &(r_r->dom_rid[i]), ps, depth); /* domain RIDs being looked up */
+ }
+
+ prs_uint32("num_entries3", ps, depth, &(r_r->num_entries3));
+
+ prs_uint32("status ", ps, depth, &(r_r->status));
+}
+
+
/*******************************************************************
makes an LSA_Q_CLOSE structure.
********************************************************************/
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* removed in SAMBA_2_0 branch. */
+
+#include "includes.h"
+
+extern int DEBUGLEVEL;
+
+
+/*******************************************************************
+creates a structure.
+********************************************************************/
+void make_reg_q_open_hklm(REG_Q_OPEN_HKLM *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_hklm(char *desc, REG_Q_OPEN_HKLM *r_q, prs_struct *ps, int depth)
+{
+ if (r_q == NULL) return;
+
+ prs_debug(ps, depth, desc, "reg_io_q_open_hklm");
+ 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_hklm(char *desc, REG_R_OPEN_HKLM *r_r, prs_struct *ps, int depth)
+{
+ if (r_r == NULL) return;
+
+ prs_debug(ps, depth, desc, "reg_io_r_open_hklm");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("", &(r_r->pol), ps, depth);
+
+ prs_uint32("status", ps, depth, &(r_r->status));
+}
+
+
+/*******************************************************************
+creates a structure.
+********************************************************************/
+void make_reg_q_flush_key(REG_Q_FLUSH_KEY *q_u, POLICY_HND *pol)
+{
+ memcpy(&(q_u->pol), pol, sizeof(q_u->pol));
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void reg_io_q_flush_key(char *desc, REG_Q_FLUSH_KEY *r_q, prs_struct *ps, int depth)
+{
+ if (r_q == NULL) return;
+
+ prs_debug(ps, depth, desc, "reg_io_q_flush_key");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("", &(r_q->pol), ps, depth);
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void reg_io_r_flush_key(char *desc, REG_R_FLUSH_KEY *r_r, prs_struct *ps, int depth)
+{
+ if (r_r == NULL) return;
+
+ prs_debug(ps, depth, desc, "reg_io_r_flush_key");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("status", ps, depth, &(r_r->status));
+}
+
+/*******************************************************************
+reads or writes SEC_DESC_BUF and SEC_DATA structures.
+********************************************************************/
+static void reg_io_hdrbuf_sec(uint32 ptr, uint32 *ptr3, BUFHDR *hdr_sec, SEC_DESC_BUF *data, prs_struct *ps, int depth)
+{
+ if (ptr != 0)
+ {
+ uint32 hdr_offset;
+ uint32 old_offset;
+ smb_io_hdrbuf_pre("hdr_sec", hdr_sec, ps, depth, &hdr_offset);
+ old_offset = ps->offset;
+ if (ptr3 != NULL)
+ {
+ prs_uint32("ptr3", ps, depth, ptr3);
+ }
+ if (ptr3 == NULL || *ptr3 != 0)
+ {
+ sec_io_desc_buf("data ", &data , ps, depth); /* JRA - this line is probably wrong... */
+ }
+ smb_io_hdrbuf_post("hdr_sec", hdr_sec, ps, depth, hdr_offset,
+ data->max_len, data->len);
+ ps->offset = old_offset + data->len + sizeof(uint32) * ((ptr3 != NULL) ? 5 : 3);
+ prs_align(ps);
+ }
+}
+
+
+
+/*******************************************************************
+creates a structure.
+********************************************************************/
+void make_reg_q_create_key(REG_Q_CREATE_KEY *q_c, POLICY_HND *hnd,
+ char *name, char *class, SEC_ACCESS *sam_access,
+ SEC_DESC_BUF *sec_buf)
+{
+ int len_name = name != NULL ? strlen(name ) + 1: 0;
+ int len_class = class != NULL ? strlen(class) + 1: 0;
+
+ 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->sec_info = DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
+
+ q_c->data = sec_buf;
+ q_c->ptr2 = 1;
+ make_buf_hdr(&(q_c->hdr_sec), sec_buf->len, sec_buf->len);
+ q_c->ptr3 = 1;
+ 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_access("sam_access", &r_q->sam_access, ps, depth);
+
+ prs_uint32("ptr1", ps, depth, &(r_q->ptr1));
+ if (r_q->ptr1 != 0)
+ {
+ prs_uint32("sec_info", ps, depth, &(r_q->sec_info));
+ }
+
+ prs_uint32("ptr2", ps, depth, &(r_q->ptr2));
+ reg_io_hdrbuf_sec(r_q->ptr2, &r_q->ptr3, &r_q->hdr_sec, r_q->data, ps, depth);
+
+ prs_uint32("unknown_2", ps, depth, &(r_q->unknown_2));
+}
+
+
+/*******************************************************************
+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_delete_val(REG_Q_DELETE_VALUE *q_c, POLICY_HND *hnd,
+ char *name)
+{
+ int len_name = name != NULL ? strlen(name ) + 1: 0;
+ 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);
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void reg_io_q_delete_val(char *desc, REG_Q_DELETE_VALUE *r_q, prs_struct *ps, int depth)
+{
+ if (r_q == NULL) return;
+
+ prs_debug(ps, depth, desc, "reg_io_q_delete_val");
+ 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);
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void reg_io_r_delete_val(char *desc, REG_R_DELETE_VALUE *r_r, prs_struct *ps, int depth)
+{
+ if (r_r == NULL) return;
+
+ prs_debug(ps, depth, desc, "reg_io_r_delete_val");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("status", ps, depth, &(r_r->status));
+}
+
+
+/*******************************************************************
+creates a structure.
+********************************************************************/
+void make_reg_q_delete_key(REG_Q_DELETE_KEY *q_c, POLICY_HND *hnd,
+ char *name)
+{
+ int len_name = name != NULL ? strlen(name ) + 1: 0;
+ 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);
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void reg_io_q_delete_key(char *desc, REG_Q_DELETE_KEY *r_q, prs_struct *ps, int depth)
+{
+ if (r_q == NULL) return;
+
+ prs_debug(ps, depth, desc, "reg_io_q_delete_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);
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void reg_io_r_delete_key(char *desc, REG_R_DELETE_KEY *r_r, prs_struct *ps, int depth)
+{
+ if (r_r == NULL) return;
+
+ prs_debug(ps, depth, desc, "reg_io_r_delete_key");
+ depth++;
+
+ prs_align(ps);
+
+ 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_hku(REG_Q_OPEN_HKU *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_hku(char *desc, REG_Q_OPEN_HKU *r_q, prs_struct *ps, int depth)
+{
+ if (r_q == NULL) return;
+
+ prs_debug(ps, depth, desc, "reg_io_q_open_hku");
+ 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_hku(char *desc, REG_R_OPEN_HKU *r_r, prs_struct *ps, int depth)
+{
+ if (r_r == NULL) return;
+
+ prs_debug(ps, depth, desc, "reg_io_r_open_hku");
+ 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.
+********************************************************************/
+void reg_io_q_close(char *desc, REG_Q_CLOSE *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "reg_io_q_unknown_1");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("", &(q_u->pol), ps, depth);
+ prs_align(ps);
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void reg_io_r_close(char *desc, REG_R_CLOSE *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "reg_io_r_unknown_1");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("", &(r_u->pol), ps, depth);
+ prs_align(ps);
+
+ prs_uint32("status", ps, depth, &(r_u->status));
+}
+
+/*******************************************************************
+makes a structure.
+********************************************************************/
+void make_reg_q_set_key_sec(REG_Q_SET_KEY_SEC *q_i, POLICY_HND *pol, SEC_DESC_BUF *sec_desc_buf)
+{
+ if (q_i == NULL) return;
+
+ memcpy(&(q_i->pol), pol, sizeof(q_i->pol));
+
+ q_i->sec_info = DACL_SECURITY_INFORMATION;
+
+ q_i->ptr = 1;
+ make_buf_hdr(&(q_i->hdr_sec), sec_desc_buf->len, sec_desc_buf->len);
+ q_i->data = sec_desc_buf;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void reg_io_q_set_key_sec(char *desc, REG_Q_SET_KEY_SEC *r_q, prs_struct *ps, int depth)
+{
+ if (r_q == NULL) return;
+
+ prs_debug(ps, depth, desc, "reg_io_q_set_key_sec");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("", &(r_q->pol), ps, depth);
+
+ prs_uint32("sec_info", ps, depth, &(r_q->sec_info));
+ prs_uint32("ptr ", ps, depth, &(r_q->ptr ));
+
+ reg_io_hdrbuf_sec(r_q->ptr, NULL, &r_q->hdr_sec, r_q->data, ps, depth);
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void reg_io_r_set_key_sec(char *desc, REG_R_SET_KEY_SEC *r_q, prs_struct *ps, int depth)
+{
+ if (r_q == NULL) return;
+
+ prs_debug(ps, depth, desc, "reg_io_r_set_key_sec");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("status", ps, depth, &(r_q->status));
+}
+
+
+/*******************************************************************
+makes a structure.
+********************************************************************/
+void make_reg_q_get_key_sec(REG_Q_GET_KEY_SEC *q_i, POLICY_HND *pol,
+ uint32 sec_buf_size, SEC_DESC_BUF *psdb)
+{
+ if (q_i == NULL) return;
+
+ memcpy(&(q_i->pol), pol, sizeof(q_i->pol));
+
+ q_i->sec_info = OWNER_SECURITY_INFORMATION |
+ GROUP_SECURITY_INFORMATION |
+ DACL_SECURITY_INFORMATION;
+
+ q_i->ptr = psdb != NULL ? 1 : 0;
+ q_i->data = psdb;
+
+ make_buf_hdr(&(q_i->hdr_sec), sec_buf_size, 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("sec_info", ps, depth, &(r_q->sec_info));
+ prs_uint32("ptr ", ps, depth, &(r_q->ptr ));
+
+ reg_io_hdrbuf_sec(r_q->ptr, NULL, &r_q->hdr_sec, r_q->data, ps, depth);
+}
+
+#if 0
+/*******************************************************************
+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 */
+}
+#endif
+
+/*******************************************************************
+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.
+********************************************************************/
+void reg_io_q_info(char *desc, REG_Q_INFO *r_q, prs_struct *ps, int depth)
+{
+ if (r_q == NULL) return;
+
+ prs_debug(ps, depth, desc, "reg_io_q_info");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("", &(r_q->pol), ps, 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)
+ {
+ smb_io_time("", &(r_q->time), ps, depth);
+ prs_uint8 ("major_version1", ps, depth, &(r_q->major_version1));
+ prs_uint8 ("minor_version1", ps, depth, &(r_q->minor_version1));
+ prs_uint8s(False, "pad1", ps, depth, r_q->pad1, sizeof(r_q->pad1));
+ }
+
+ prs_uint32("ptr2", ps, depth, &(r_q->ptr2));
+
+ if (r_q->ptr2 != 0)
+ {
+ prs_uint8 ("major_version2", ps, depth, &(r_q->major_version2));
+ prs_uint8 ("minor_version2", ps, depth, &(r_q->minor_version2));
+ 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)
+ {
+ prs_uint32("unknown", ps, depth, &(r_q->unknown));
+ }
+}
+
+
+/*******************************************************************
+creates a structure.
+********************************************************************/
+void make_reg_r_info(REG_R_INFO *r_r,
+ uint32 level, char *os_type,
+ uint32 unknown_0, uint32 unknown_1,
+ uint32 status)
+{
+ uint8 buf[512];
+ int len = struni2((char *)buf, os_type);
+
+ r_r->ptr1 = 1;
+ r_r->level = level;
+
+ r_r->ptr_type = 1;
+ make_buffer2(&(r_r->uni_type), buf, len*2);
+
+ r_r->ptr2 = 1;
+ r_r->unknown_0 = unknown_0;
+
+ r_r->ptr3 = 1;
+ r_r->unknown_1 = unknown_1;
+
+ r_r->status = status;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void reg_io_r_info(char *desc, REG_R_INFO *r_r, prs_struct *ps, int depth)
+{
+ if (r_r == NULL) return;
+
+ prs_debug(ps, depth, desc, "reg_io_r_info");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("ptr1", ps, depth, &(r_r->ptr1));
+
+ 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_buffer2("uni_type", &(r_r->uni_type), r_r->ptr_type, ps, depth);
+
+ prs_uint32("ptr2", ps, depth, &(r_r->ptr2));
+
+ if (r_r->ptr2 != 0)
+ {
+ prs_uint32("unknown_0", ps, depth, &(r_r->unknown_0));
+ }
+
+ prs_uint32("ptr3", ps, depth, &(r_r->ptr3));
+
+ if (r_r->ptr3 != 0)
+ {
+ 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.
+********************************************************************/
+void reg_io_q_open_entry(char *desc, REG_Q_OPEN_ENTRY *r_q, prs_struct *ps, int depth)
+{
+ if (r_q == NULL) return;
+
+ prs_debug(ps, depth, desc, "reg_io_q_entry");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("", &(r_q->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);
+
+ prs_uint32("unknown_0", ps, depth, &(r_q->unknown_0));
+ prs_uint32("unknown_1", ps, depth, &(r_q->unknown_1));
+}
+
+
+/*******************************************************************
+creates a structure.
+********************************************************************/
+void make_reg_r_open_entry(REG_R_OPEN_ENTRY *r_r,
+ POLICY_HND *pol, uint32 status)
+{
+ if (r_r == NULL) return;
+
+ memcpy(&(r_r->pol), pol, sizeof(r_r->pol));
+ r_r->status = status;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void reg_io_r_open_entry(char *desc, REG_R_OPEN_ENTRY *r_r, prs_struct *ps, int depth)
+{
+ if (r_r == NULL) return;
+
+ prs_debug(ps, depth, desc, "reg_io_r_open_entry");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("", &(r_r->pol), ps, depth);
+
+ prs_uint32("status", ps, depth, &(r_r->status));
+}
+
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* removed in SAMBA_2_0 branch. */
+
+#include "includes.h"
+
+extern int DEBUGLEVEL;
+
+
+/*******************************************************************
+makes a SAMR_Q_CLOSE_HND structure.
+********************************************************************/
+void make_samr_q_close_hnd(SAMR_Q_CLOSE_HND *q_c, POLICY_HND *hnd)
+{
+ if (q_c == NULL || hnd == NULL) return;
+
+ DEBUG(5,("make_samr_q_close_hnd\n"));
+
+ memcpy(&(q_c->pol), hnd, sizeof(q_c->pol));
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_q_close_hnd(char *desc, SAMR_Q_CLOSE_HND *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_q_close_hnd");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("pol", &(q_u->pol), ps, depth);
+ prs_align(ps);
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_r_close_hnd(char *desc, SAMR_R_CLOSE_HND *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_r_close_hnd");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("pol", &(r_u->pol), ps, depth);
+ prs_align(ps);
+
+ prs_uint32("status", ps, depth, &(r_u->status));
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void make_samr_q_open_domain(SAMR_Q_OPEN_DOMAIN *q_u,
+ POLICY_HND *connect_pol, uint32 rid,
+ DOM_SID *sid)
+{
+ if (q_u == NULL) return;
+
+ DEBUG(5,("samr_make_q_open_domain\n"));
+
+ memcpy(&q_u->connect_pol, connect_pol, sizeof(q_u->connect_pol));
+ q_u->rid = rid;
+ make_dom_sid2(&(q_u->dom_sid), sid);
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_q_open_domain(char *desc, SAMR_Q_OPEN_DOMAIN *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_q_open_domain");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("connect_pol", &(q_u->connect_pol), ps, depth);
+ prs_align(ps);
+
+ prs_uint32("rid", ps, depth, &(q_u->rid));
+
+ smb_io_dom_sid2("sid", &(q_u->dom_sid), ps, depth);
+ prs_align(ps);
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_r_open_domain(char *desc, SAMR_R_OPEN_DOMAIN *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_r_open_domain");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("domain_pol", &(r_u->domain_pol), ps, depth);
+ prs_align(ps);
+
+ prs_uint32("status", ps, depth, &(r_u->status));
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void make_samr_q_unknown_2c(SAMR_Q_UNKNOWN_2C *q_u, POLICY_HND *user_pol)
+{
+ if (q_u == NULL) return;
+
+ DEBUG(5,("samr_make_q_unknown_2c\n"));
+
+ memcpy(&q_u->user_pol, user_pol, sizeof(q_u->user_pol));
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_q_unknown_2c(char *desc, SAMR_Q_UNKNOWN_2C *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_q_unknown_2c");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("user_pol", &(q_u->user_pol), ps, depth);
+ prs_align(ps);
+}
+
+/*******************************************************************
+makes a structure.
+********************************************************************/
+void make_samr_r_unknown_2c(SAMR_R_UNKNOWN_2C *q_u, uint32 status)
+{
+ if (q_u == NULL) return;
+
+ DEBUG(5,("samr_make_r_unknown_2c\n"));
+
+ q_u->unknown_0 = 0x00160000;
+ q_u->unknown_1 = 0x00000000;
+ q_u->status = status;
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_r_unknown_2c(char *desc, SAMR_R_UNKNOWN_2C *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_r_unknown_2c");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("unknown_0", ps, depth, &(r_u->unknown_0));
+ prs_uint32("unknown_1", ps, depth, &(r_u->unknown_1));
+ prs_uint32("status ", ps, depth, &(r_u->status ));
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void make_samr_q_unknown_3(SAMR_Q_UNKNOWN_3 *q_u,
+ POLICY_HND *user_pol, uint16 switch_value)
+{
+ if (q_u == NULL) return;
+
+ DEBUG(5,("samr_make_q_unknown_3\n"));
+
+ memcpy(&q_u->user_pol, user_pol, sizeof(q_u->user_pol));
+ q_u->switch_value = switch_value;
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_q_unknown_3(char *desc, SAMR_Q_UNKNOWN_3 *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_q_unknown_3");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("user_pol", &(q_u->user_pol), ps, depth);
+ prs_align(ps);
+
+ prs_uint16("switch_value", ps, depth, &(q_u->switch_value));
+ prs_align(ps);
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void make_samr_q_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u,
+ POLICY_HND *domain_pol, uint16 switch_value)
+{
+ if (q_u == NULL) return;
+
+ DEBUG(5,("samr_make_q_query_dom_info\n"));
+
+ memcpy(&q_u->domain_pol, domain_pol, sizeof(q_u->domain_pol));
+ q_u->switch_value = switch_value;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_q_query_dom_info(char *desc, SAMR_Q_QUERY_DOMAIN_INFO *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_q_query_dom_info");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("domain_pol", &(q_u->domain_pol), ps, depth);
+ prs_align(ps);
+
+ prs_uint16("switch_value", ps, depth, &(q_u->switch_value));
+ prs_align(ps);
+}
+
+/*******************************************************************
+makes a structure.
+********************************************************************/
+void make_unk_info2(SAM_UNK_INFO_2 *u_2, char *domain, char *server)
+{
+ int len_domain = strlen(domain);
+ int len_server = strlen(server);
+
+ if (u_2 == NULL) return;
+
+ u_2->unknown_0 = 0x00000000;
+ u_2->unknown_1 = 0x80000000;
+ u_2->unknown_2 = 0x00000000;
+
+ u_2->ptr_0 = 1;
+ make_uni_hdr(&(u_2->hdr_domain), len_domain, len_domain, 1);
+ make_uni_hdr(&(u_2->hdr_server), len_server, len_server, 1);
+
+ u_2->seq_num = 0x10000000;
+ u_2->unknown_3 = 0x00000000;
+
+ u_2->unknown_4 = 0x00000001;
+ u_2->unknown_5 = 0x00000003;
+ u_2->unknown_6 = 0x00000001;
+ u_2->num_domain_usrs = 0x00000008;
+ u_2->num_domain_grps = 0x00000003;
+ u_2->num_local_grps = 0x00000003;
+
+ memset(u_2->padding, 0, sizeof(u_2->padding)); /* 12 bytes zeros */
+
+ make_unistr2(&u_2->uni_domain, domain, len_domain);
+ make_unistr2(&u_2->uni_server, server, len_server);
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void sam_io_unk_info2(char *desc, SAM_UNK_INFO_2 *u_2, prs_struct *ps, int depth)
+{
+ if (u_2 == NULL) return;
+
+ prs_debug(ps, depth, desc, "sam_io_unk_info2");
+ depth++;
+
+ prs_uint32("unknown_0", ps, depth, &u_2->unknown_0); /* 0x0000 0000 */
+ prs_uint32("unknown_1", ps, depth, &u_2->unknown_1); /* 0x8000 0000 */
+ prs_uint32("unknown_2", ps, depth, &u_2->unknown_2); /* 0x0000 0000 */
+
+ prs_uint32("ptr_0", ps, depth, &u_2->ptr_0); /* pointer to unknown structure */
+ smb_io_unihdr("hdr_domain", &u_2->hdr_domain, ps, depth); /* domain name unicode header */
+ smb_io_unihdr("hdr_server", &u_2->hdr_server, ps, depth); /* server name unicode header */
+
+ /* put all the data in here, at the moment, including what the above
+ pointer is referring to
+ */
+
+ prs_uint32("seq_num ", ps, depth, &u_2->seq_num ); /* 0x0000 0099 or 0x1000 0000 */
+ prs_uint32("unknown_3 ", ps, depth, &u_2->unknown_3 ); /* 0x0000 0000 */
+
+ prs_uint32("unknown_4 ", ps, depth, &u_2->unknown_4 ); /* 0x0000 0001 */
+ prs_uint32("unknown_5 ", ps, depth, &u_2->unknown_5 ); /* 0x0000 0003 */
+ prs_uint32("unknown_6 ", ps, depth, &u_2->unknown_6 ); /* 0x0000 0001 */
+ prs_uint32("num_domain_usrs ", ps, depth, &u_2->num_domain_usrs ); /* 0x0000 0008 */
+ prs_uint32("num_domain_grps", ps, depth, &u_2->num_domain_grps); /* 0x0000 0003 */
+ prs_uint32("num_local_grps", ps, depth, &u_2->num_local_grps); /* 0x0000 0003 */
+
+ prs_uint8s(False, "padding", ps, depth, u_2->padding, sizeof(u_2->padding)); /* 12 bytes zeros */
+
+ smb_io_unistr2( "uni_domain", &u_2->uni_domain, u_2->hdr_domain.buffer, ps, depth); /* domain name unicode string */
+ smb_io_unistr2( "uni_server", &u_2->uni_server, u_2->hdr_server.buffer, ps, depth); /* server name unicode string */
+
+ prs_align(ps);
+
+}
+
+/*******************************************************************
+makes a SAMR_R_QUERY_DOMAIN_INFO structure.
+********************************************************************/
+void make_samr_r_query_dom_info(SAMR_R_QUERY_DOMAIN_INFO *r_u,
+ uint16 switch_value, SAM_UNK_CTR *ctr,
+ uint32 status)
+{
+ if (r_u == NULL || ctr == NULL) return;
+
+ DEBUG(5,("make_samr_r_query_dom_info\n"));
+
+ r_u->ptr_0 = 0;
+ r_u->switch_value = 0;
+ r_u->status = status; /* return status */
+
+ if (status == 0)
+ {
+ r_u->switch_value = switch_value;
+ r_u->ptr_0 = 1;
+ r_u->ctr = ctr;
+ }
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_r_query_dom_info(char *desc, SAMR_R_QUERY_DOMAIN_INFO *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_r_query_dom_info");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("ptr_0 ", ps, depth, &(r_u->ptr_0));
+ prs_uint16("switch_value", ps, depth, &(r_u->switch_value));
+ prs_align(ps);
+
+ if (r_u->ptr_0 != 0 && r_u->ctr != NULL)
+ {
+ switch (r_u->switch_value)
+ {
+ case 0x02:
+ {
+ sam_io_unk_info2("unk_inf2", &r_u->ctr->info.inf2, ps, depth);
+ break;
+ }
+ default:
+ {
+ DEBUG(3,("samr_io_r_query_dom_info: unknown switch level 0x%x\n",
+ r_u->switch_value));
+ return;
+ }
+ }
+ }
+}
+
+
+/*******************************************************************
+ makes a DOM_SID3 structure.
+
+ calculate length by adding up the size of the components.
+ ********************************************************************/
+void make_dom_sid3(DOM_SID3 *sid3, uint16 unk_0, uint16 unk_1, DOM_SID *sid)
+{
+ if (sid3 == NULL) return;
+
+ sid3->sid = *sid;
+ sid3->len = 2 + 8 + sid3->sid.num_auths * 4;
+}
+
+/*******************************************************************
+reads or writes a SAM_SID3 structure.
+
+this one's odd, because the length (in bytes) is specified at the beginning.
+the length _includes_ the length of the length, too :-)
+
+********************************************************************/
+static void sam_io_dom_sid3(char *desc, DOM_SID3 *sid3, prs_struct *ps, int depth)
+{
+ if (sid3 == NULL) return;
+
+ prs_debug(ps, depth, desc, "sam_io_dom_sid3");
+ depth++;
+
+ prs_uint16("len", ps, depth, &(sid3->len));
+ prs_align(ps);
+ smb_io_dom_sid("", &(sid3->sid), ps, depth);
+}
+
+/*******************************************************************
+makes a SAMR_R_UNKNOWN3 structure.
+
+unknown_2 : 0x0001
+unknown_3 : 0x8004
+
+unknown_4,5 : 0x0000 0014
+
+unknown_6 : 0x0002
+unknown_7 : 0x5800 or 0x0070
+
+********************************************************************/
+static void make_sam_sid_stuff(SAM_SID_STUFF *stf,
+ uint16 unknown_2, uint16 unknown_3,
+ uint32 unknown_4, uint16 unknown_6, uint16 unknown_7,
+ int num_sid3s, DOM_SID3 sid3[MAX_SAM_SIDS])
+{
+ stf->unknown_2 = unknown_2;
+ stf->unknown_3 = unknown_3;
+
+ memset((char *)stf->padding1, '\0', sizeof(stf->padding1));
+
+ stf->unknown_4 = unknown_4;
+ stf->unknown_5 = unknown_4;
+
+ stf->unknown_6 = unknown_6;
+ stf->unknown_7 = unknown_7;
+
+ stf->num_sids = num_sid3s;
+
+ stf->padding2 = 0x0000;
+
+ memcpy(stf->sid, sid3, sizeof(DOM_SID3) * num_sid3s);
+}
+
+/*******************************************************************
+reads or writes a SAM_SID_STUFF structure.
+********************************************************************/
+static void sam_io_sid_stuff(char *desc, SAM_SID_STUFF *stf, prs_struct *ps, int depth)
+{
+ int i;
+
+ if (stf == NULL) return;
+
+ DEBUG(5,("make_sam_sid_stuff\n"));
+
+ prs_uint16("unknown_2", ps, depth, &(stf->unknown_2));
+ prs_uint16("unknown_3", ps, depth, &(stf->unknown_3));
+
+ prs_uint8s(False, "padding1", ps, depth, stf->padding1, sizeof(stf->padding1));
+
+ prs_uint32("unknown_4", ps, depth, &(stf->unknown_4));
+ prs_uint32("unknown_5", ps, depth, &(stf->unknown_5));
+ prs_uint16("unknown_6", ps, depth, &(stf->unknown_6));
+ prs_uint16("unknown_7", ps, depth, &(stf->unknown_7));
+
+ prs_uint32("num_sids ", ps, depth, &(stf->num_sids ));
+ prs_uint16("padding2 ", ps, depth, &(stf->padding2 ));
+
+ SMB_ASSERT_ARRAY(stf->sid, stf->num_sids);
+
+ for (i = 0; i < stf->num_sids; i++)
+ {
+ sam_io_dom_sid3("", &(stf->sid[i]), ps, depth);
+ }
+}
+
+/*******************************************************************
+reads or writes a SAMR_R_UNKNOWN3 structure.
+********************************************************************/
+void make_samr_r_unknown_3(SAMR_R_UNKNOWN_3 *r_u,
+ uint16 unknown_2, uint16 unknown_3,
+ uint32 unknown_4, uint16 unknown_6, uint16 unknown_7,
+ int num_sid3s, DOM_SID3 sid3[MAX_SAM_SIDS],
+ uint32 status)
+{
+ if (r_u == NULL) return;
+
+ DEBUG(5,("samr_make_r_unknown_3\n"));
+
+ r_u->ptr_0 = 0;
+ r_u->ptr_1 = 0;
+
+ if (status == 0x0)
+ {
+ r_u->ptr_0 = 1;
+ r_u->ptr_1 = 1;
+ make_sam_sid_stuff(&(r_u->sid_stuff), unknown_2, unknown_3,
+ unknown_4, unknown_6, unknown_7,
+ num_sid3s, sid3);
+ }
+
+ r_u->status = status;
+}
+
+
+/*******************************************************************
+reads or writes a SAMR_R_UNKNOWN_3 structure.
+
+this one's odd, because the daft buggers use a different mechanism
+for writing out the array of sids. they put the number of sids in
+only one place: they've calculated the length of each sid and jumped
+by that amount. then, retrospectively, the length of the whole buffer
+is put at the beginning of the data stream.
+
+wierd.
+
+********************************************************************/
+void samr_io_r_unknown_3(char *desc, SAMR_R_UNKNOWN_3 *r_u, prs_struct *ps, int depth)
+{
+ int ptr_len0=0;
+ int ptr_len1=0;
+ int ptr_sid_stuff = 0;
+
+ if (r_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_r_unknown_3");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("ptr_0 ", ps, depth, &(r_u->ptr_0 ));
+
+ if (ps->io)
+ {
+ /* reading. do the length later */
+ prs_uint32("sid_stuff_len0", ps, depth, &(r_u->sid_stuff_len0));
+ }
+ else
+ {
+ /* storing */
+ ptr_len0 = ps->offset; ps->offset += 4;
+ }
+
+ if (r_u->ptr_0 != 0)
+ {
+ prs_uint32("ptr_1 ", ps, depth, &(r_u->ptr_1 ));
+ if (ps->io)
+ {
+ /* reading. do the length later */
+ prs_uint32("sid_stuff_len1", ps, depth, &(r_u->sid_stuff_len1));
+ }
+ else
+ {
+ /* storing */
+ ptr_len1 = ps->offset; ps->offset += 4;
+ }
+
+ if (r_u->ptr_1 != 0)
+ {
+ ptr_sid_stuff = ps->offset;
+ sam_io_sid_stuff("", &(r_u->sid_stuff), ps, depth);
+ }
+ }
+
+ if (!(ps->io)) /* storing not reading. do the length, now. */
+ {
+ if (ptr_sid_stuff != 0)
+ {
+ uint32 sid_stuff_len = ps->offset - ptr_sid_stuff;
+ int old_len = ps->offset;
+
+ ps->offset = ptr_len0;
+ prs_uint32("sid_stuff_len0", ps, depth, &sid_stuff_len);
+
+ ps->offset = ptr_len1;
+ prs_uint32("sid_stuff_len1", ps, depth, &sid_stuff_len);
+
+ ps->offset = old_len;
+ }
+ }
+
+ prs_uint32("status", ps, depth, &(r_u->status));
+}
+
+/*******************************************************************
+reads or writes a SAM_STR1 structure.
+********************************************************************/
+static void sam_io_sam_str1(char *desc, SAM_STR1 *sam, uint32 acct_buf, uint32 name_buf, uint32 desc_buf, prs_struct *ps, int depth)
+{
+ if (sam == NULL) return;
+
+ prs_debug(ps, depth, desc, "sam_io_sam_str1");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_unistr2("unistr2", &(sam->uni_acct_name), acct_buf, ps, depth); /* account name unicode string */
+ smb_io_unistr2("unistr2", &(sam->uni_full_name), name_buf, ps, depth); /* full name unicode string */
+ smb_io_unistr2("unistr2", &(sam->uni_acct_desc), desc_buf, ps, depth); /* account description unicode string */
+}
+
+/*******************************************************************
+makes a SAM_ENTRY1 structure.
+********************************************************************/
+static void make_sam_entry1(SAM_ENTRY1 *sam, uint32 user_idx,
+ uint32 len_sam_name, uint32 len_sam_full, uint32 len_sam_desc,
+ uint32 rid_user, uint16 acb_info)
+{
+ if (sam == NULL) return;
+
+ DEBUG(5,("make_sam_entry1\n"));
+
+ sam->user_idx = user_idx;
+ sam->rid_user = rid_user;
+ sam->acb_info = acb_info;
+ sam->pad = 0;
+
+ make_uni_hdr(&(sam->hdr_acct_name), len_sam_name, len_sam_name, len_sam_name != 0);
+ make_uni_hdr(&(sam->hdr_user_name), len_sam_full, len_sam_full, len_sam_full != 0);
+ make_uni_hdr(&(sam->hdr_user_desc), len_sam_desc, len_sam_desc, len_sam_desc != 0);
+}
+
+/*******************************************************************
+reads or writes a SAM_ENTRY1 structure.
+********************************************************************/
+static void sam_io_sam_entry1(char *desc, SAM_ENTRY1 *sam, prs_struct *ps, int depth)
+{
+ if (sam == NULL) return;
+
+ prs_debug(ps, depth, desc, "sam_io_sam_entry1");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("user_idx ", ps, depth, &(sam->user_idx ));
+
+ prs_uint32("rid_user ", ps, depth, &(sam->rid_user ));
+ prs_uint16("acb_info ", ps, depth, &(sam->acb_info ));
+ prs_uint16("pad ", ps, depth, &(sam->pad ));
+
+ smb_io_unihdr("unihdr", &(sam->hdr_acct_name), ps, depth); /* account name unicode string header */
+ smb_io_unihdr("unihdr", &(sam->hdr_user_name), ps, depth); /* account name unicode string header */
+ smb_io_unihdr("unihdr", &(sam->hdr_user_desc), ps, depth); /* account name unicode string header */
+}
+
+/*******************************************************************
+reads or writes a SAM_STR2 structure.
+********************************************************************/
+static void sam_io_sam_str2(char *desc, SAM_STR2 *sam, uint32 acct_buf, uint32 desc_buf, prs_struct *ps, int depth)
+{
+ if (sam == NULL) return;
+
+ prs_debug(ps, depth, desc, "sam_io_sam_str2");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_unistr2("unistr2", &(sam->uni_srv_name), acct_buf, ps, depth); /* account name unicode string */
+ smb_io_unistr2("unistr2", &(sam->uni_srv_desc), desc_buf, ps, depth); /* account description unicode string */
+}
+
+/*******************************************************************
+makes a SAM_ENTRY2 structure.
+********************************************************************/
+static void make_sam_entry2(SAM_ENTRY2 *sam, uint32 user_idx,
+ uint32 len_sam_name, uint32 len_sam_desc,
+ uint32 rid_user, uint16 acb_info)
+{
+ if (sam == NULL) return;
+
+ DEBUG(5,("make_sam_entry2\n"));
+
+ sam->user_idx = user_idx;
+ sam->rid_user = rid_user;
+ sam->acb_info = acb_info;
+ sam->pad = 0;
+
+ make_uni_hdr(&(sam->hdr_srv_name), len_sam_name, len_sam_name, len_sam_name != 0);
+ make_uni_hdr(&(sam->hdr_srv_desc), len_sam_desc, len_sam_desc, len_sam_desc != 0);
+}
+
+/*******************************************************************
+reads or writes a SAM_ENTRY2 structure.
+********************************************************************/
+static void sam_io_sam_entry2(char *desc, SAM_ENTRY2 *sam, prs_struct *ps, int depth)
+{
+ if (sam == NULL) return;
+
+ prs_debug(ps, depth, desc, "sam_io_sam_entry2");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("user_idx ", ps, depth, &(sam->user_idx ));
+
+ prs_uint32("rid_user ", ps, depth, &(sam->rid_user ));
+ prs_uint16("acb_info ", ps, depth, &(sam->acb_info ));
+ prs_uint16("pad ", ps, depth, &(sam->pad ));
+
+ smb_io_unihdr("unihdr", &(sam->hdr_srv_name), ps, depth); /* account name unicode string header */
+ smb_io_unihdr("unihdr", &(sam->hdr_srv_desc), ps, depth); /* account name unicode string header */
+}
+
+/*******************************************************************
+reads or writes a SAM_STR3 structure.
+********************************************************************/
+static void sam_io_sam_str3(char *desc, SAM_STR3 *sam, uint32 acct_buf, uint32 desc_buf, prs_struct *ps, int depth)
+{
+ if (sam == NULL) return;
+
+ prs_debug(ps, depth, desc, "sam_io_sam_str3");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_unistr2("unistr2", &(sam->uni_grp_name), acct_buf, ps, depth); /* account name unicode string */
+ smb_io_unistr2("unistr2", &(sam->uni_grp_desc), desc_buf, ps, depth); /* account description unicode string */
+}
+
+/*******************************************************************
+makes a SAM_ENTRY3 structure.
+********************************************************************/
+static void make_sam_entry3(SAM_ENTRY3 *sam, uint32 grp_idx,
+ uint32 len_grp_name, uint32 len_grp_desc, uint32 rid_grp)
+{
+ if (sam == NULL) return;
+
+ DEBUG(5,("make_sam_entry3\n"));
+
+ sam->grp_idx = grp_idx;
+ sam->rid_grp = rid_grp;
+ sam->attr = 0x07; /* group rid attributes - gets ignored by nt 4.0 */
+
+ make_uni_hdr(&(sam->hdr_grp_name), len_grp_name, len_grp_name, len_grp_name != 0);
+ make_uni_hdr(&(sam->hdr_grp_desc), len_grp_desc, len_grp_desc, len_grp_desc != 0);
+}
+
+/*******************************************************************
+reads or writes a SAM_ENTRY3 structure.
+********************************************************************/
+static void sam_io_sam_entry3(char *desc, SAM_ENTRY3 *sam, prs_struct *ps, int depth)
+{
+ if (sam == NULL) return;
+
+ prs_debug(ps, depth, desc, "sam_io_sam_entry3");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("grp_idx", ps, depth, &(sam->grp_idx));
+
+ prs_uint32("rid_grp", ps, depth, &(sam->rid_grp));
+ prs_uint32("attr ", ps, depth, &(sam->attr ));
+
+ smb_io_unihdr("unihdr", &(sam->hdr_grp_name), ps, depth); /* account name unicode string header */
+ smb_io_unihdr("unihdr", &(sam->hdr_grp_desc), ps, depth); /* account name unicode string header */
+}
+
+/*******************************************************************
+makes a SAM_ENTRY structure.
+********************************************************************/
+static void make_sam_entry(SAM_ENTRY *sam, uint32 len_sam_name, uint32 rid)
+{
+ if (sam == NULL) return;
+
+ DEBUG(5,("make_sam_entry\n"));
+
+ sam->rid = rid;
+ make_uni_hdr(&(sam->hdr_name), len_sam_name, len_sam_name, len_sam_name != 0);
+}
+
+/*******************************************************************
+reads or writes a SAM_ENTRY structure.
+********************************************************************/
+static void sam_io_sam_entry(char *desc, SAM_ENTRY *sam, prs_struct *ps, int depth)
+{
+ if (sam == NULL) return;
+
+ prs_debug(ps, depth, desc, "sam_io_sam_entry");
+ depth++;
+
+ prs_align(ps);
+ prs_uint32("rid", ps, depth, &(sam->rid ));
+ smb_io_unihdr("unihdr", &(sam->hdr_name), ps, depth); /* account name unicode string header */
+}
+
+
+/*******************************************************************
+makes a SAMR_Q_ENUM_DOM_USERS structure.
+********************************************************************/
+void make_samr_q_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_e, POLICY_HND *pol,
+ uint16 req_num_entries, uint16 unk_0,
+ uint16 acb_mask, uint16 unk_1, uint32 size)
+{
+ if (q_e == NULL || pol == NULL) return;
+
+ DEBUG(5,("make_q_enum_dom_users\n"));
+
+ memcpy(&(q_e->pol), pol, sizeof(*pol));
+
+ q_e->req_num_entries = req_num_entries; /* zero indicates lots */
+ q_e->unknown_0 = unk_0; /* this gets returned in the response */
+ q_e->acb_mask = acb_mask;
+ q_e->unknown_1 = unk_1;
+ q_e->max_size = size;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_q_enum_dom_users(char *desc, SAMR_Q_ENUM_DOM_USERS *q_e, prs_struct *ps, int depth)
+{
+ if (q_e == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_q_enum_dom_users");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("pol", &(q_e->pol), ps, depth);
+ prs_align(ps);
+
+ prs_uint16("req_num_entries", ps, depth, &(q_e->req_num_entries));
+ prs_uint16("unknown_0 ", ps, depth, &(q_e->unknown_0 ));
+
+ prs_uint16("acb_mask ", ps, depth, &(q_e->acb_mask ));
+ prs_uint16("unknown_1 ", ps, depth, &(q_e->unknown_1 ));
+
+ prs_uint32("max_size ", ps, depth, &(q_e->max_size ));
+
+ prs_align(ps);
+}
+
+
+/*******************************************************************
+makes a SAMR_R_ENUM_DOM_USERS structure.
+********************************************************************/
+void make_samr_r_enum_dom_users(SAMR_R_ENUM_DOM_USERS *r_u,
+ uint16 total_num_entries, uint16 unk_0,
+ uint32 num_sam_entries, SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES], uint32 status)
+{
+ int i;
+
+ if (r_u == NULL) return;
+
+ DEBUG(5,("make_samr_r_enum_dom_users\n"));
+
+ if (num_sam_entries >= MAX_SAM_ENTRIES)
+ {
+ num_sam_entries = MAX_SAM_ENTRIES;
+ DEBUG(5,("limiting number of entries to %d\n",
+ num_sam_entries));
+ }
+
+ r_u->total_num_entries = total_num_entries;
+ r_u->unknown_0 = unk_0;
+
+ if (total_num_entries > 0)
+ {
+ r_u->ptr_entries1 = 1;
+ r_u->ptr_entries2 = 1;
+ r_u->num_entries2 = num_sam_entries;
+ r_u->num_entries3 = num_sam_entries;
+
+ SMB_ASSERT_ARRAY(r_u->sam, num_sam_entries);
+ SMB_ASSERT_ARRAY(r_u->uni_acct_name, num_sam_entries);
+
+ for (i = 0; i < num_sam_entries; i++)
+ {
+ make_sam_entry(&(r_u->sam[i]),
+ pass[i].uni_user_name.uni_str_len,
+ pass[i].user_rid);
+
+ copy_unistr2(&(r_u->uni_acct_name[i]), &(pass[i].uni_user_name));
+ }
+
+ r_u->num_entries4 = num_sam_entries;
+ }
+ else
+ {
+ r_u->ptr_entries1 = 0;
+ r_u->num_entries2 = num_sam_entries;
+ r_u->ptr_entries2 = 1;
+ }
+
+ r_u->status = status;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_r_enum_dom_users(char *desc, SAMR_R_ENUM_DOM_USERS *r_u, prs_struct *ps, int depth)
+{
+ int i;
+
+ if (r_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_r_enum_dom_users");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint16("total_num_entries", ps, depth, &(r_u->total_num_entries));
+ prs_uint16("unknown_0 ", ps, depth, &(r_u->unknown_0 ));
+ prs_uint32("ptr_entries1", ps, depth, &(r_u->ptr_entries1));
+
+ if (r_u->total_num_entries != 0 && r_u->ptr_entries1 != 0)
+ {
+ prs_uint32("num_entries2", ps, depth, &(r_u->num_entries2));
+ prs_uint32("ptr_entries2", ps, depth, &(r_u->ptr_entries2));
+ prs_uint32("num_entries3", ps, depth, &(r_u->num_entries3));
+
+ SMB_ASSERT_ARRAY(r_u->sam, r_u->num_entries2);
+
+ for (i = 0; i < r_u->num_entries2; i++)
+ {
+ prs_grow(ps);
+ sam_io_sam_entry("", &(r_u->sam[i]), ps, depth);
+ }
+
+ SMB_ASSERT_ARRAY(r_u->uni_acct_name, r_u->num_entries2);
+
+ for (i = 0; i < r_u->num_entries2; i++)
+ {
+ prs_grow(ps);
+ smb_io_unistr2("", &(r_u->uni_acct_name[i]), r_u->sam[i].hdr_name.buffer, ps, depth);
+ }
+
+ prs_align(ps);
+
+ prs_uint32("num_entries4", ps, depth, &(r_u->num_entries4));
+ }
+
+ prs_uint32("status", ps, depth, &(r_u->status));
+}
+
+/*******************************************************************
+makes a SAMR_Q_ENUM_DOM_ALIASES structure.
+********************************************************************/
+void make_samr_q_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES *q_e, POLICY_HND *pol, uint32 size)
+{
+ if (q_e == NULL || pol == NULL) return;
+
+ DEBUG(5,("make_q_enum_dom_aliases\n"));
+
+ memcpy(&(q_e->pol), pol, sizeof(*pol));
+
+ q_e->unknown_0 = 0;
+ q_e->max_size = size;
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_q_enum_dom_aliases(char *desc, SAMR_Q_ENUM_DOM_ALIASES *q_e, prs_struct *ps, int depth)
+{
+ if (q_e == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_q_enum_dom_aliases");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("pol", &(q_e->pol), ps, depth);
+ prs_align(ps);
+
+ prs_uint32("unknown_0", ps, depth, &(q_e->unknown_0));
+ prs_uint32("max_size ", ps, depth, &(q_e->max_size ));
+
+ prs_align(ps);
+}
+
+
+/*******************************************************************
+makes a SAMR_R_ENUM_DOM_ALIASES structure.
+********************************************************************/
+void make_samr_r_enum_dom_aliases(SAMR_R_ENUM_DOM_ALIASES *r_u,
+ uint32 num_sam_entries, SAM_USER_INFO_21 grps[MAX_SAM_ENTRIES],
+ uint32 status)
+{
+ int i;
+
+ if (r_u == NULL) return;
+
+ DEBUG(5,("make_samr_r_enum_dom_aliases\n"));
+
+ if (num_sam_entries >= MAX_SAM_ENTRIES)
+ {
+ num_sam_entries = MAX_SAM_ENTRIES;
+ DEBUG(5,("limiting number of entries to %d\n",
+ num_sam_entries));
+ }
+
+ r_u->num_entries = num_sam_entries;
+
+ if (num_sam_entries > 0)
+ {
+ r_u->ptr_entries = 1;
+ r_u->num_entries2 = num_sam_entries;
+ r_u->ptr_entries2 = 1;
+ r_u->num_entries3 = num_sam_entries;
+
+ SMB_ASSERT_ARRAY(r_u->sam, num_sam_entries);
+
+ for (i = 0; i < num_sam_entries; i++)
+ {
+ make_sam_entry(&(r_u->sam[i]),
+ grps[i].uni_user_name.uni_str_len,
+ grps[i].user_rid);
+
+ copy_unistr2(&(r_u->uni_grp_name[i]), &(grps[i].uni_user_name));
+ }
+
+ r_u->num_entries4 = num_sam_entries;
+ }
+ else
+ {
+ r_u->ptr_entries = 0;
+ }
+
+ r_u->status = status;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_r_enum_dom_aliases(char *desc, SAMR_R_ENUM_DOM_ALIASES *r_u, prs_struct *ps, int depth)
+{
+ int i;
+
+ if (r_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_r_enum_dom_aliases");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("num_entries", ps, depth, &(r_u->num_entries));
+ prs_uint32("ptr_entries", ps, depth, &(r_u->ptr_entries));
+
+ if (r_u->num_entries != 0 && r_u->ptr_entries != 0)
+ {
+ prs_uint32("num_entries2", ps, depth, &(r_u->num_entries2));
+ prs_uint32("ptr_entries2", ps, depth, &(r_u->ptr_entries2));
+ prs_uint32("num_entries3", ps, depth, &(r_u->num_entries3));
+
+ SMB_ASSERT_ARRAY(r_u->sam, r_u->num_entries);
+
+ for (i = 0; i < r_u->num_entries; i++)
+ {
+ sam_io_sam_entry("", &(r_u->sam[i]), ps, depth);
+ }
+
+ for (i = 0; i < r_u->num_entries; i++)
+ {
+ smb_io_unistr2("", &(r_u->uni_grp_name[i]), r_u->sam[i].hdr_name.buffer, ps, depth);
+ }
+
+ prs_align(ps);
+
+ prs_uint32("num_entries4", ps, depth, &(r_u->num_entries4));
+ }
+
+ prs_uint32("status", ps, depth, &(r_u->status));
+}
+
+
+/*******************************************************************
+makes a SAMR_Q_QUERY_DISPINFO structure.
+********************************************************************/
+void make_samr_q_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_e, POLICY_HND *pol,
+ uint16 switch_level, uint32 start_idx, uint32 size)
+{
+ if (q_e == NULL || pol == NULL) return;
+
+ DEBUG(5,("make_q_query_dispinfo\n"));
+
+ memcpy(&(q_e->pol), pol, sizeof(*pol));
+
+ q_e->switch_level = switch_level;
+
+ q_e->unknown_0 = 0;
+ q_e->start_idx = start_idx;
+ q_e->unknown_1 = 0x000007d0;
+ q_e->max_size = size;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_q_query_dispinfo(char *desc, SAMR_Q_QUERY_DISPINFO *q_e, prs_struct *ps, int depth)
+{
+ if (q_e == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_q_query_dispinfo");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("pol", &(q_e->pol), ps, depth);
+ prs_align(ps);
+
+ prs_uint16("switch_level", ps, depth, &(q_e->switch_level));
+ prs_uint16("unknown_0 ", ps, depth, &(q_e->unknown_0 ));
+ prs_uint32("start_idx ", ps, depth, &(q_e->start_idx ));
+ prs_uint32("unknown_1 ", ps, depth, &(q_e->unknown_1 ));
+ prs_uint32("max_size ", ps, depth, &(q_e->max_size ));
+
+ prs_align(ps);
+}
+
+
+/*******************************************************************
+makes a SAM_INFO_2 structure.
+********************************************************************/
+void make_sam_info_2(SAM_INFO_2 *sam, uint32 acb_mask,
+ uint32 start_idx, uint32 num_sam_entries,
+ SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES])
+{
+ int i;
+ int entries_added;
+
+ if (sam == NULL) return;
+
+ DEBUG(5,("make_sam_info_2\n"));
+
+ if (num_sam_entries >= MAX_SAM_ENTRIES)
+ {
+ num_sam_entries = MAX_SAM_ENTRIES;
+ DEBUG(5,("limiting number of entries to %d\n",
+ num_sam_entries));
+ }
+
+ for (i = start_idx, entries_added = 0; i < num_sam_entries; i++)
+ {
+ if (IS_BITS_SET_ALL(pass[i].acb_info, acb_mask))
+ {
+ make_sam_entry2(&(sam->sam[entries_added]),
+ start_idx + entries_added + 1,
+ pass[i].uni_user_name.uni_str_len,
+ pass[i].uni_acct_desc.uni_str_len,
+ pass[i].user_rid,
+ pass[i].acb_info);
+
+ copy_unistr2(&(sam->str[entries_added].uni_srv_name), &(pass[i].uni_user_name));
+ copy_unistr2(&(sam->str[entries_added].uni_srv_desc), &(pass[i].uni_acct_desc));
+
+ entries_added++;
+ }
+
+ sam->num_entries = entries_added;
+ sam->ptr_entries = 1;
+ sam->num_entries2 = entries_added;
+ }
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static void sam_io_sam_info_2(char *desc, SAM_INFO_2 *sam, prs_struct *ps, int depth)
+{
+ int i;
+
+ if (sam == NULL) return;
+
+ prs_debug(ps, depth, desc, "sam_io_sam_info_2");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("num_entries ", ps, depth, &(sam->num_entries ));
+ prs_uint32("ptr_entries ", ps, depth, &(sam->ptr_entries ));
+
+ prs_uint32("num_entries2 ", ps, depth, &(sam->num_entries2 ));
+
+ SMB_ASSERT_ARRAY(sam->sam, sam->num_entries);
+
+ for (i = 0; i < sam->num_entries; i++)
+ {
+ prs_grow(ps);
+ sam_io_sam_entry2("", &(sam->sam[i]), ps, depth);
+ }
+
+ for (i = 0; i < sam->num_entries; i++)
+ {
+ prs_grow(ps);
+ sam_io_sam_str2 ("", &(sam->str[i]),
+ sam->sam[i].hdr_srv_name.buffer,
+ sam->sam[i].hdr_srv_desc.buffer,
+ ps, depth);
+ }
+}
+
+
+/*******************************************************************
+makes a SAM_INFO_1 structure.
+********************************************************************/
+void make_sam_info_1(SAM_INFO_1 *sam, uint32 acb_mask,
+ uint32 start_idx, uint32 num_sam_entries,
+ SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES])
+{
+ int i;
+ int entries_added;
+
+ if (sam == NULL) return;
+
+ DEBUG(5,("make_sam_info_1\n"));
+
+ if (num_sam_entries >= MAX_SAM_ENTRIES)
+ {
+ num_sam_entries = MAX_SAM_ENTRIES;
+ DEBUG(5,("limiting number of entries to %d\n",
+ num_sam_entries));
+ }
+
+ for (i = start_idx, entries_added = 0; i < num_sam_entries; i++)
+ {
+ if (IS_BITS_SET_ALL(pass[i].acb_info, acb_mask))
+ {
+ make_sam_entry1(&(sam->sam[entries_added]),
+ start_idx + entries_added + 1,
+ pass[i].uni_user_name.uni_str_len,
+ pass[i].uni_full_name.uni_str_len,
+ pass[i].uni_acct_desc.uni_str_len,
+ pass[i].user_rid,
+ pass[i].acb_info);
+
+ copy_unistr2(&(sam->str[entries_added].uni_acct_name), &(pass[i].uni_user_name));
+ copy_unistr2(&(sam->str[entries_added].uni_full_name), &(pass[i].uni_full_name));
+ copy_unistr2(&(sam->str[entries_added].uni_acct_desc), &(pass[i].uni_acct_desc));
+
+ entries_added++;
+ }
+ }
+
+ sam->num_entries = entries_added;
+ sam->ptr_entries = 1;
+ sam->num_entries2 = entries_added;
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static void sam_io_sam_info_1(char *desc, SAM_INFO_1 *sam, prs_struct *ps, int depth)
+{
+ int i;
+
+ if (sam == NULL) return;
+
+ prs_debug(ps, depth, desc, "sam_io_sam_info_1");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("num_entries ", ps, depth, &(sam->num_entries ));
+ prs_uint32("ptr_entries ", ps, depth, &(sam->ptr_entries ));
+
+ prs_uint32("num_entries2 ", ps, depth, &(sam->num_entries2 ));
+
+ SMB_ASSERT_ARRAY(sam->sam, sam->num_entries);
+
+ for (i = 0; i < sam->num_entries; i++)
+ {
+ prs_grow(ps);
+ sam_io_sam_entry1("", &(sam->sam[i]), ps, depth);
+ }
+
+ for (i = 0; i < sam->num_entries; i++)
+ {
+ prs_grow(ps);
+ sam_io_sam_str1 ("", &(sam->str[i]),
+ sam->sam[i].hdr_acct_name.buffer,
+ sam->sam[i].hdr_user_name.buffer,
+ sam->sam[i].hdr_user_desc.buffer,
+ ps, depth);
+ }
+}
+
+
+/*******************************************************************
+makes a SAMR_R_QUERY_DISPINFO structure.
+********************************************************************/
+void make_samr_r_query_dispinfo(SAMR_R_QUERY_DISPINFO *r_u,
+ uint16 switch_level, SAM_INFO_CTR *ctr, uint32 status)
+{
+ if (r_u == NULL) return;
+
+ DEBUG(5,("make_samr_r_query_dispinfo\n"));
+
+ if (status == 0x0)
+ {
+ r_u->unknown_0 = 0x0000001;
+ r_u->unknown_1 = 0x0000001;
+ }
+ else
+ {
+ r_u->unknown_0 = 0x0;
+ r_u->unknown_1 = 0x0;
+ }
+
+ r_u->switch_level = switch_level;
+ r_u->ctr = ctr;
+ r_u->status = status;
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_r_query_dispinfo(char *desc, SAMR_R_QUERY_DISPINFO *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_r_query_dispinfo");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("unknown_0 ", ps, depth, &(r_u->unknown_0 ));
+ prs_uint32("unknown_1 ", ps, depth, &(r_u->unknown_1 ));
+ prs_uint16("switch_level ", ps, depth, &(r_u->switch_level ));
+
+ prs_align(ps);
+
+ switch (r_u->switch_level)
+ {
+ case 0x1:
+ {
+ sam_io_sam_info_1("users", r_u->ctr->sam.info1, ps, depth);
+ break;
+ }
+ case 0x2:
+ {
+ sam_io_sam_info_2("servers", r_u->ctr->sam.info2, ps, depth);
+ break;
+ }
+ default:
+ {
+ DEBUG(5,("samr_io_r_query_dispinfo: unknown switch value\n"));
+ break;
+ }
+ }
+
+ prs_uint32("status", ps, depth, &(r_u->status));
+}
+
+
+/*******************************************************************
+makes a SAMR_Q_ENUM_DOM_GROUPS structure.
+********************************************************************/
+void make_samr_q_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_e, POLICY_HND *pol,
+ uint16 switch_level, uint32 start_idx, uint32 size)
+{
+ if (q_e == NULL || pol == NULL) return;
+
+ DEBUG(5,("make_q_enum_dom_groups\n"));
+
+ memcpy(&(q_e->pol), pol, sizeof(*pol));
+
+ q_e->switch_level = switch_level;
+
+ q_e->unknown_0 = 0;
+ q_e->start_idx = start_idx;
+ q_e->unknown_1 = 0x000007d0;
+ q_e->max_size = size;
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_q_enum_dom_groups(char *desc, SAMR_Q_ENUM_DOM_GROUPS *q_e, prs_struct *ps, int depth)
+{
+ if (q_e == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_q_enum_dom_groups");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("pol", &(q_e->pol), ps, depth);
+ prs_align(ps);
+
+ prs_uint16("switch_level", ps, depth, &(q_e->switch_level));
+ prs_uint16("unknown_0 ", ps, depth, &(q_e->unknown_0 ));
+ prs_uint32("start_idx ", ps, depth, &(q_e->start_idx ));
+ prs_uint32("unknown_1 ", ps, depth, &(q_e->unknown_1 ));
+ prs_uint32("max_size ", ps, depth, &(q_e->max_size ));
+
+ prs_align(ps);
+}
+
+
+/*******************************************************************
+makes a SAMR_R_ENUM_DOM_GROUPS structure.
+********************************************************************/
+void make_samr_r_enum_dom_groups(SAMR_R_ENUM_DOM_GROUPS *r_u,
+ uint32 start_idx, uint32 num_sam_entries,
+ SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES],
+ uint32 status)
+{
+ int i;
+ int entries_added;
+
+ if (r_u == NULL) return;
+
+ DEBUG(5,("make_samr_r_enum_dom_groups\n"));
+
+ if (num_sam_entries >= MAX_SAM_ENTRIES)
+ {
+ num_sam_entries = MAX_SAM_ENTRIES;
+ DEBUG(5,("limiting number of entries to %d\n",
+ num_sam_entries));
+ }
+
+ if (status == 0x0)
+ {
+ for (i = start_idx, entries_added = 0; i < num_sam_entries; i++)
+ {
+ make_sam_entry3(&(r_u->sam[entries_added]),
+ start_idx + entries_added + 1,
+ pass[i].uni_user_name.uni_str_len,
+ pass[i].uni_acct_desc.uni_str_len,
+ pass[i].user_rid);
+
+ copy_unistr2(&(r_u->str[entries_added].uni_grp_name), &(pass[i].uni_user_name));
+ copy_unistr2(&(r_u->str[entries_added].uni_grp_desc), &(pass[i].uni_acct_desc));
+
+ entries_added++;
+ }
+
+ if (entries_added > 0)
+ {
+ r_u->unknown_0 = 0x0000492;
+ r_u->unknown_1 = 0x000049a;
+ }
+ else
+ {
+ r_u->unknown_0 = 0x0;
+ r_u->unknown_1 = 0x0;
+ }
+ r_u->switch_level = 3;
+ r_u->num_entries = entries_added;
+ r_u->ptr_entries = 1;
+ r_u->num_entries2 = entries_added;
+ }
+ else
+ {
+ r_u->switch_level = 0;
+ }
+
+ r_u->status = status;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_r_enum_dom_groups(char *desc, SAMR_R_ENUM_DOM_GROUPS *r_u, prs_struct *ps, int depth)
+{
+ int i;
+
+ if (r_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_r_enum_dom_groups");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("unknown_0 ", ps, depth, &(r_u->unknown_0 ));
+ prs_uint32("unknown_1 ", ps, depth, &(r_u->unknown_1 ));
+ prs_uint32("switch_level ", ps, depth, &(r_u->switch_level ));
+
+ if (r_u->switch_level != 0)
+ {
+ prs_uint32("num_entries ", ps, depth, &(r_u->num_entries ));
+ prs_uint32("ptr_entries ", ps, depth, &(r_u->ptr_entries ));
+
+ prs_uint32("num_entries2 ", ps, depth, &(r_u->num_entries2 ));
+
+ SMB_ASSERT_ARRAY(r_u->sam, r_u->num_entries);
+
+ for (i = 0; i < r_u->num_entries; i++)
+ {
+ prs_grow(ps);
+ sam_io_sam_entry3("", &(r_u->sam[i]), ps, depth);
+ }
+
+ for (i = 0; i < r_u->num_entries; i++)
+ {
+ prs_grow(ps);
+ sam_io_sam_str3 ("", &(r_u->str[i]),
+ r_u->sam[i].hdr_grp_name.buffer,
+ r_u->sam[i].hdr_grp_desc.buffer,
+ ps, depth);
+ }
+ }
+
+ prs_uint32("status", ps, depth, &(r_u->status));
+}
+
+
+/*******************************************************************
+makes a SAMR_Q_QUERY_ALIASINFO structure.
+********************************************************************/
+void make_samr_q_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_e,
+ POLICY_HND *pol,
+ uint16 switch_level)
+{
+ if (q_e == NULL || pol == NULL) return;
+
+ DEBUG(5,("make_q_query_aliasinfo\n"));
+
+ memcpy(&(q_e->pol), pol, sizeof(*pol));
+
+ q_e->switch_level = switch_level;
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_q_query_aliasinfo(char *desc, SAMR_Q_QUERY_ALIASINFO *q_e, prs_struct *ps, int depth)
+{
+ if (q_e == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_q_query_aliasinfo");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("pol", &(q_e->pol), ps, depth);
+ prs_align(ps);
+
+ prs_uint16("switch_level", ps, depth, &(q_e->switch_level));
+}
+
+
+/*******************************************************************
+makes a SAMR_R_QUERY_ALIASINFO structure.
+********************************************************************/
+void make_samr_r_query_aliasinfo(SAMR_R_QUERY_ALIASINFO *r_u,
+ uint16 switch_value, char *acct_desc,
+ uint32 status)
+{
+ if (r_u == NULL) return;
+
+ DEBUG(5,("make_samr_r_query_aliasinfo\n"));
+
+ r_u->ptr = 0;
+
+ if (status == 0)
+ {
+ r_u->switch_value = switch_value;
+
+ switch (switch_value)
+ {
+ case 3:
+ {
+ int acct_len = acct_desc ? strlen(acct_desc) : 0;
+
+ r_u->ptr = 1;
+
+ make_uni_hdr(&(r_u->alias.info3.hdr_acct_desc), acct_len , acct_len, acct_desc ? 1 : 0);
+ make_unistr2(&(r_u->alias.info3.uni_acct_desc), acct_desc, acct_len);
+
+ break;
+ }
+
+ default:
+ {
+ DEBUG(4,("make_samr_r_query_aliasinfo: unsupported switch level\n"));
+ break;
+ }
+ }
+ }
+
+ r_u->status = status;
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_r_query_aliasinfo(char *desc, SAMR_R_QUERY_ALIASINFO *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_r_query_aliasinfo");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("ptr ", ps, depth, &(r_u->ptr ));
+
+ if (r_u->ptr != 0)
+ {
+ prs_uint16("switch_value", ps, depth, &(r_u->switch_value));
+ prs_align(ps);
+
+ if (r_u->switch_value != 0)
+ {
+ switch (r_u->switch_value)
+ {
+ case 3:
+ {
+ smb_io_unihdr ("", &(r_u->alias.info3.hdr_acct_desc), ps, depth);
+ smb_io_unistr2("", &(r_u->alias.info3.uni_acct_desc), r_u->alias.info3.hdr_acct_desc.buffer, ps, depth);
+ break;
+ }
+ default:
+ {
+ DEBUG(4,("samr_io_r_query_aliasinfo: unsupported switch level\n"));
+ break;
+ }
+ }
+ }
+ }
+
+ prs_align(ps);
+
+ prs_uint32("status", ps, depth, &(r_u->status));
+}
+
+/*******************************************************************
+reads or writes a SAMR_Q_LOOKUP_IDS structure.
+********************************************************************/
+void samr_io_q_lookup_ids(char *desc, SAMR_Q_LOOKUP_IDS *q_u, prs_struct *ps, int depth)
+{
+ fstring tmp;
+ int i;
+
+ if (q_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_q_lookup_ids");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("pol", &(q_u->pol), ps, depth);
+ prs_align(ps);
+
+ prs_uint32("num_sids1", ps, depth, &(q_u->num_sids1));
+ prs_uint32("ptr ", ps, depth, &(q_u->ptr ));
+ prs_uint32("num_sids2", ps, depth, &(q_u->num_sids2));
+
+ SMB_ASSERT_ARRAY(q_u->ptr_sid, q_u->num_sids2);
+
+ for (i = 0; i < q_u->num_sids2; i++)
+ {
+ slprintf(tmp, sizeof(tmp) - 1, "ptr[%02d]", i);
+ prs_uint32(tmp, ps, depth, &(q_u->ptr_sid[i]));
+ }
+
+ for (i = 0; i < q_u->num_sids2; i++)
+ {
+ if (q_u->ptr_sid[i] != 0)
+ {
+ prs_grow(ps);
+ slprintf(tmp, sizeof(tmp)-1, "sid[%02d]", i);
+ smb_io_dom_sid2(tmp, &(q_u->sid[i]), ps, depth);
+ }
+ }
+
+ prs_align(ps);
+}
+
+
+/*******************************************************************
+makes a SAMR_R_LOOKUP_IDS structure.
+********************************************************************/
+void make_samr_r_lookup_ids(SAMR_R_LOOKUP_IDS *r_u,
+ uint32 num_rids, uint32 *rid, uint32 status)
+{
+ int i;
+ if (r_u == NULL) return;
+
+ DEBUG(5,("make_samr_r_lookup_ids\n"));
+
+ if (status == 0x0)
+ {
+ r_u->num_entries = num_rids;
+ r_u->ptr = 1;
+ r_u->num_entries2 = num_rids;
+
+ SMB_ASSERT_ARRAY(r_u->rid, num_rids);
+
+ for (i = 0; i < num_rids; i++)
+ {
+ r_u->rid[i] = rid[i];
+ }
+ }
+ else
+ {
+ r_u->num_entries = 0;
+ r_u->ptr = 0;
+ r_u->num_entries2 = 0;
+ }
+
+ r_u->status = status;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_r_lookup_ids(char *desc, SAMR_R_LOOKUP_IDS *r_u, prs_struct *ps, int depth)
+{
+ fstring tmp;
+ int i;
+ if (r_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_r_lookup_ids");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("num_entries", ps, depth, &(r_u->num_entries));
+ prs_uint32("ptr ", ps, depth, &(r_u->ptr ));
+ prs_uint32("num_entries2", ps, depth, &(r_u->num_entries2));
+
+ if (r_u->num_entries != 0)
+ {
+ SMB_ASSERT_ARRAY(r_u->rid, r_u->num_entries2);
+
+ for (i = 0; i < r_u->num_entries2; i++)
+ {
+ slprintf(tmp, sizeof(tmp)-1, "rid[%02d]", i);
+ prs_uint32(tmp, ps, depth, &(r_u->rid[i]));
+ }
+ }
+
+ prs_uint32("status", ps, depth, &(r_u->status));
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_q_lookup_names(char *desc, SAMR_Q_LOOKUP_NAMES *q_u, prs_struct *ps, int depth)
+{
+ int i;
+
+ if (q_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_q_lookup_names");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("pol", &(q_u->pol), ps, depth);
+ prs_align(ps);
+
+ prs_uint32("num_rids1", ps, depth, &(q_u->num_rids1));
+ prs_uint32("rid ", ps, depth, &(q_u->rid ));
+ prs_uint32("ptr ", ps, depth, &(q_u->ptr ));
+ prs_uint32("num_rids2", ps, depth, &(q_u->num_rids2));
+
+ SMB_ASSERT_ARRAY(q_u->hdr_user_name, q_u->num_rids2);
+
+ for (i = 0; i < q_u->num_rids2; i++)
+ {
+ prs_grow(ps);
+ smb_io_unihdr ("", &(q_u->hdr_user_name[i]), ps, depth);
+ }
+ for (i = 0; i < q_u->num_rids2; i++)
+ {
+ prs_grow(ps);
+ smb_io_unistr2("", &(q_u->uni_user_name[i]), q_u->hdr_user_name[i].buffer, ps, depth);
+ }
+
+ prs_align(ps);
+}
+
+
+/*******************************************************************
+makes a SAMR_R_LOOKUP_NAMES structure.
+********************************************************************/
+void make_samr_r_lookup_names(SAMR_R_LOOKUP_NAMES *r_u,
+ uint32 num_rids, uint32 *rid, uint32 status)
+{
+ int i;
+ if (r_u == NULL) return;
+
+ DEBUG(5,("make_samr_r_lookup_names\n"));
+
+ if (status == 0x0)
+ {
+ r_u->num_entries = num_rids;
+ r_u->undoc_buffer = 1;
+ r_u->num_entries2 = num_rids;
+
+ SMB_ASSERT_ARRAY(r_u->dom_rid, num_rids);
+
+ for (i = 0; i < num_rids; i++)
+ {
+ make_dom_rid3(&(r_u->dom_rid[i]), rid[i], 0x01);
+ }
+
+ r_u->num_entries3 = num_rids;
+ }
+ else
+ {
+ r_u->num_entries = 0;
+ r_u->undoc_buffer = 0;
+ r_u->num_entries2 = 0;
+ r_u->num_entries3 = 0;
+ }
+
+ r_u->status = status;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_r_lookup_names(char *desc, SAMR_R_LOOKUP_NAMES *r_u, prs_struct *ps, int depth)
+{
+ int i;
+ if (r_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_r_lookup_names");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("num_entries ", ps, depth, &(r_u->num_entries ));
+ prs_uint32("undoc_buffer", ps, depth, &(r_u->undoc_buffer));
+ prs_uint32("num_entries2", ps, depth, &(r_u->num_entries2));
+
+ if (r_u->num_entries != 0)
+ {
+ SMB_ASSERT_ARRAY(r_u->dom_rid, r_u->num_entries2);
+
+ for (i = 0; i < r_u->num_entries2; i++)
+ {
+ prs_grow(ps);
+ smb_io_dom_rid3("", &(r_u->dom_rid[i]), ps, depth);
+ }
+
+ }
+
+ prs_uint32("num_entries3", ps, depth, &(r_u->num_entries3));
+
+ prs_uint32("status", ps, depth, &(r_u->status));
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_q_unknown_12(char *desc, SAMR_Q_UNKNOWN_12 *q_u, prs_struct *ps, int depth)
+{
+ int i;
+ fstring tmp;
+
+ if (q_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_q_unknown_12");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("pol", &(q_u->pol), ps, depth);
+ prs_align(ps);
+
+ prs_uint32("num_gids1", ps, depth, &(q_u->num_gids1));
+ prs_uint32("rid ", ps, depth, &(q_u->rid ));
+ prs_uint32("ptr ", ps, depth, &(q_u->ptr ));
+ prs_uint32("num_gids2", ps, depth, &(q_u->num_gids2));
+
+ SMB_ASSERT_ARRAY(q_u->gid, q_u->num_gids2);
+
+ for (i = 0; i < q_u->num_gids2; i++)
+ {
+ prs_grow(ps);
+ slprintf(tmp, sizeof(tmp) - 1, "gid[%02d] ", i);
+ prs_uint32(tmp, ps, depth, &(q_u->gid[i]));
+ }
+
+ prs_align(ps);
+}
+
+
+/*******************************************************************
+makes a SAMR_R_UNKNOWN_12 structure.
+********************************************************************/
+void make_samr_r_unknown_12(SAMR_R_UNKNOWN_12 *r_u,
+ uint32 num_aliases, fstring *als_name, uint32 *num_als_usrs,
+ uint32 status)
+{
+ int i;
+ if (r_u == NULL || als_name == NULL || num_als_usrs == NULL) return;
+
+ DEBUG(5,("make_samr_r_unknown_12\n"));
+
+ if (status == 0x0)
+ {
+ r_u->num_aliases1 = num_aliases;
+ r_u->ptr_aliases = 1;
+ r_u->num_aliases2 = num_aliases;
+
+ r_u->num_als_usrs1 = num_aliases;
+ r_u->ptr_als_usrs = 1;
+ r_u->num_als_usrs2 = num_aliases;
+
+ SMB_ASSERT_ARRAY(r_u->hdr_als_name, num_aliases);
+
+ for (i = 0; i < num_aliases; i++)
+ {
+ int als_len = als_name[i] != NULL ? strlen(als_name[i]) : 0;
+ make_uni_hdr(&(r_u->hdr_als_name[i]), als_len , als_len, als_name[i] ? 1 : 0);
+ make_unistr2(&(r_u->uni_als_name[i]), als_name[i], als_len);
+ r_u->num_als_usrs[i] = num_als_usrs[i];
+ }
+ }
+ else
+ {
+ r_u->num_aliases1 = num_aliases;
+ r_u->ptr_aliases = 0;
+ r_u->num_aliases2 = num_aliases;
+
+ r_u->num_als_usrs1 = num_aliases;
+ r_u->ptr_als_usrs = 0;
+ r_u->num_als_usrs2 = num_aliases;
+ }
+
+ r_u->status = status;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_r_unknown_12(char *desc, SAMR_R_UNKNOWN_12 *r_u, prs_struct *ps, int depth)
+{
+ int i;
+ fstring tmp;
+ if (r_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_r_unknown_12");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("num_aliases1", ps, depth, &(r_u->num_aliases1));
+ prs_uint32("ptr_aliases ", ps, depth, &(r_u->ptr_aliases ));
+ prs_uint32("num_aliases2", ps, depth, &(r_u->num_aliases2));
+
+ if (r_u->ptr_aliases != 0 && r_u->num_aliases1 != 0)
+ {
+ SMB_ASSERT_ARRAY(r_u->hdr_als_name, r_u->num_aliases2);
+
+ for (i = 0; i < r_u->num_aliases2; i++)
+ {
+ prs_grow(ps);
+ slprintf(tmp, sizeof(tmp) - 1, "als_hdr[%02d] ", i);
+ smb_io_unihdr ("", &(r_u->hdr_als_name[i]), ps, depth);
+ }
+ for (i = 0; i < r_u->num_aliases2; i++)
+ {
+ prs_grow(ps);
+ slprintf(tmp, sizeof(tmp) - 1, "als_str[%02d] ", i);
+ smb_io_unistr2("", &(r_u->uni_als_name[i]), r_u->hdr_als_name[i].buffer, ps, depth);
+ }
+ }
+
+ prs_align(ps);
+
+ prs_uint32("num_als_usrs1", ps, depth, &(r_u->num_als_usrs1));
+ prs_uint32("ptr_als_usrs ", ps, depth, &(r_u->ptr_als_usrs ));
+ prs_uint32("num_als_usrs2", ps, depth, &(r_u->num_als_usrs2));
+
+ if (r_u->ptr_als_usrs != 0 && r_u->num_als_usrs1 != 0)
+ {
+ SMB_ASSERT_ARRAY(r_u->num_als_usrs, r_u->num_als_usrs2);
+
+ for (i = 0; i < r_u->num_als_usrs2; i++)
+ {
+ prs_grow(ps);
+ slprintf(tmp, sizeof(tmp) - 1, "als_usrs[%02d] ", i);
+ prs_uint32(tmp, ps, depth, &(r_u->num_als_usrs[i]));
+ }
+ }
+
+ prs_uint32("status", ps, depth, &(r_u->status));
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void make_samr_q_open_user(SAMR_Q_OPEN_USER *q_u,
+ POLICY_HND *pol,
+ uint32 unk_0, uint32 rid)
+{
+ if (q_u == NULL) return;
+
+ DEBUG(5,("samr_make_q_open_user\n"));
+
+ memcpy(&q_u->domain_pol, pol, sizeof(q_u->domain_pol));
+
+ q_u->unknown_0 = unk_0;
+ q_u->user_rid = rid;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_q_open_user(char *desc, SAMR_Q_OPEN_USER *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_q_open_user");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("domain_pol", &(q_u->domain_pol), ps, depth);
+ prs_align(ps);
+
+ prs_uint32("unknown_0", ps, depth, &(q_u->unknown_0));
+ prs_uint32("user_rid ", ps, depth, &(q_u->user_rid ));
+
+ prs_align(ps);
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_r_open_user(char *desc, SAMR_R_OPEN_USER *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_r_open_user");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("user_pol", &(r_u->user_pol), ps, depth);
+ prs_align(ps);
+
+ prs_uint32("status", ps, depth, &(r_u->status));
+}
+
+/*******************************************************************
+makes a SAMR_Q_QUERY_USERGROUPS structure.
+********************************************************************/
+void make_samr_q_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
+ POLICY_HND *hnd)
+{
+ if (q_u == NULL || hnd == NULL) return;
+
+ DEBUG(5,("make_samr_q_query_usergroups\n"));
+
+ memcpy(&(q_u->pol), hnd, sizeof(q_u->pol));
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_q_query_usergroups(char *desc, SAMR_Q_QUERY_USERGROUPS *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_q_query_usergroups");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("pol", &(q_u->pol), ps, depth);
+ prs_align(ps);
+}
+
+/*******************************************************************
+makes a SAMR_R_QUERY_USERGROUPS structure.
+********************************************************************/
+void make_samr_r_query_usergroups(SAMR_R_QUERY_USERGROUPS *r_u,
+ uint32 num_gids, DOM_GID *gid, uint32 status)
+{
+ if (r_u == NULL) return;
+
+ DEBUG(5,("make_samr_r_query_usergroups\n"));
+
+ if (status == 0x0)
+ {
+ r_u->ptr_0 = 1;
+ r_u->num_entries = num_gids;
+ r_u->ptr_1 = 1;
+ r_u->num_entries2 = num_gids;
+
+ r_u->gid = gid;
+ }
+ else
+ {
+ r_u->ptr_0 = 0;
+ r_u->num_entries = 0;
+ r_u->ptr_1 = 0;
+ }
+
+ r_u->status = status;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_r_query_usergroups(char *desc, SAMR_R_QUERY_USERGROUPS *r_u, prs_struct *ps, int depth)
+{
+ int i;
+ if (r_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_r_query_usergroups");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("ptr_0 ", ps, depth, &(r_u->ptr_0 ));
+
+ if (r_u->ptr_0 != 0)
+ {
+ prs_uint32("num_entries ", ps, depth, &(r_u->num_entries));
+ prs_uint32("ptr_1 ", ps, depth, &(r_u->ptr_1 ));
+
+ if (r_u->num_entries != 0)
+ {
+ prs_uint32("num_entries2", ps, depth, &(r_u->num_entries2));
+
+ for (i = 0; i < r_u->num_entries2; i++)
+ {
+ prs_grow(ps);
+ smb_io_gid("", &(r_u->gid[i]), ps, depth);
+ }
+ }
+ }
+ prs_uint32("status", ps, depth, &(r_u->status));
+}
+
+/*******************************************************************
+makes a SAMR_Q_QUERY_USERINFO structure.
+********************************************************************/
+void make_samr_q_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
+ POLICY_HND *hnd, uint16 switch_value)
+{
+ if (q_u == NULL || hnd == NULL) return;
+
+ DEBUG(5,("make_samr_q_query_userinfo\n"));
+
+ memcpy(&(q_u->pol), hnd, sizeof(q_u->pol));
+ q_u->switch_value = switch_value;
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_q_query_userinfo(char *desc, SAMR_Q_QUERY_USERINFO *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_q_query_userinfo");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("pol", &(q_u->pol), ps, depth);
+ prs_align(ps);
+
+ prs_uint16("switch_value", ps, depth, &(q_u->switch_value)); /* 0x0015 or 0x0011 */
+
+ prs_align(ps);
+}
+
+/*******************************************************************
+reads or writes a LOGON_HRS structure.
+********************************************************************/
+static void sam_io_logon_hrs(char *desc, LOGON_HRS *hrs, prs_struct *ps, int depth)
+{
+ if (hrs == NULL) return;
+
+ prs_debug(ps, depth, desc, "sam_io_logon_hrs");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32 ( "len ", ps, depth, &(hrs->len ));
+
+ if (hrs->len > 64)
+ {
+ DEBUG(5,("sam_io_logon_hrs: truncating length\n"));
+ hrs->len = 64;
+ }
+
+ prs_uint8s (False, "hours", ps, depth, hrs->hours, hrs->len);
+}
+
+/*******************************************************************
+makes a SAM_USER_INFO_10 structure.
+********************************************************************/
+void make_sam_user_info10(SAM_USER_INFO_10 *usr,
+ uint32 acb_info)
+{
+ if (usr == NULL) return;
+
+ DEBUG(5,("make_sam_user_info10\n"));
+
+ usr->acb_info = acb_info;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void sam_io_user_info10(char *desc, SAM_USER_INFO_10 *usr, prs_struct *ps, int depth)
+{
+ if (usr == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_r_user_info10");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("acb_info", ps, depth, &(usr->acb_info));
+}
+
+/*******************************************************************
+makes a SAM_USER_INFO_11 structure.
+********************************************************************/
+void make_sam_user_info11(SAM_USER_INFO_11 *usr,
+ NTTIME *expiry,
+ char *mach_acct,
+ uint32 rid_user,
+ uint32 rid_group,
+ uint16 acct_ctrl)
+
+{
+ int len_mach_acct;
+ if (usr == NULL || expiry == NULL || mach_acct == NULL) return;
+
+ DEBUG(5,("make_sam_user_info11\n"));
+
+ len_mach_acct = strlen(mach_acct);
+
+ memcpy(&(usr->expiry),expiry, sizeof(usr->expiry)); /* expiry time or something? */
+ memset((char *)usr->padding_1, '\0', sizeof(usr->padding_1)); /* 0 - padding 24 bytes */
+
+ make_uni_hdr(&(usr->hdr_mach_acct), len_mach_acct, len_mach_acct, 4); /* unicode header for machine account */
+ usr->padding_2 = 0; /* 0 - padding 4 bytes */
+
+ usr->ptr_1 = 1; /* pointer */
+ memset((char *)usr->padding_3, '\0', sizeof(usr->padding_3)); /* 0 - padding 32 bytes */
+ usr->padding_4 = 0; /* 0 - padding 4 bytes */
+
+ usr->ptr_2 = 1; /* pointer */
+ usr->padding_5 = 0; /* 0 - padding 4 bytes */
+
+ usr->ptr_3 = 1; /* pointer */
+ memset((char *)usr->padding_6, '\0', sizeof(usr->padding_6)); /* 0 - padding 32 bytes */
+
+ usr->rid_user = rid_user;
+ usr->rid_group = rid_group;
+
+ usr->acct_ctrl = acct_ctrl;
+ usr->unknown_3 = 0x0000;
+
+ usr->unknown_4 = 0x003f; /* 0x003f - 16 bit unknown */
+ usr->unknown_5 = 0x003c; /* 0x003c - 16 bit unknown */
+
+ memset((char *)usr->padding_7, '\0', sizeof(usr->padding_7)); /* 0 - padding 16 bytes */
+ usr->padding_8 = 0; /* 0 - padding 4 bytes */
+
+ make_unistr2(&(usr->uni_mach_acct), mach_acct, len_mach_acct); /* unicode string for machine account */
+
+ memset((char *)usr->padding_9, '\0', sizeof(usr->padding_9)); /* 0 - padding 48 bytes */
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void sam_io_user_info11(char *desc, SAM_USER_INFO_11 *usr, prs_struct *ps, int depth)
+{
+ if (usr == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_r_unknown_24");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint8s (False, "padding_0", ps, depth, usr->padding_0, sizeof(usr->padding_0));
+
+ smb_io_time("time", &(usr->expiry), ps, depth);
+
+ prs_uint8s (False, "padding_1", ps, depth, usr->padding_1, sizeof(usr->padding_1));
+
+ smb_io_unihdr ("unihdr", &(usr->hdr_mach_acct), ps, depth);
+ prs_uint32( "padding_2", ps, depth, &(usr->padding_2));
+
+ prs_uint32( "ptr_1 ", ps, depth, &(usr->ptr_1 ));
+ prs_uint8s (False, "padding_3", ps, depth, usr->padding_3, sizeof(usr->padding_3));
+ prs_uint32( "padding_4", ps, depth, &(usr->padding_4));
+
+ prs_uint32( "ptr_2 ", ps, depth, &(usr->ptr_2 ));
+ prs_uint32( "padding_5", ps, depth, &(usr->padding_5));
+
+ prs_uint32( "ptr_3 ", ps, depth, &(usr->ptr_3 ));
+ prs_uint8s (False, "padding_6", ps, depth, usr->padding_6, sizeof(usr->padding_6));
+
+ prs_uint32( "rid_user ", ps, depth, &(usr->rid_user ));
+ prs_uint32( "rid_group", ps, depth, &(usr->rid_group));
+ prs_uint16( "acct_ctrl", ps, depth, &(usr->acct_ctrl));
+ prs_uint16( "unknown_3", ps, depth, &(usr->unknown_3));
+ prs_uint16( "unknown_4", ps, depth, &(usr->unknown_4));
+ prs_uint16( "unknown_5", ps, depth, &(usr->unknown_5));
+
+ prs_uint8s (False, "padding_7", ps, depth, usr->padding_7, sizeof(usr->padding_7));
+ prs_uint32( "padding_8", ps, depth, &(usr->padding_8));
+
+ smb_io_unistr2("unistr2", &(usr->uni_mach_acct), True, ps, depth);
+ prs_align(ps);
+
+ prs_uint8s (False, "padding_9", ps, depth, usr->padding_9, sizeof(usr->padding_9));
+}
+/*************************************************************************
+ make_sam_user_info21
+
+ unknown_3 = 0x00ff ffff
+ unknown_5 = 0x0002 0000
+ unknown_6 = 0x0000 04ec
+
+ *************************************************************************/
+void make_sam_user_info21(SAM_USER_INFO_21 *usr,
+
+ NTTIME *logon_time,
+ NTTIME *logoff_time,
+ NTTIME *kickoff_time,
+ NTTIME *pass_last_set_time,
+ NTTIME *pass_can_change_time,
+ NTTIME *pass_must_change_time,
+
+ char *user_name,
+ char *full_name,
+ char *home_dir,
+ char *dir_drive,
+ char *logon_script,
+ char *profile_path,
+ char *description,
+ char *workstations,
+ char *unknown_str,
+ char *munged_dial,
+
+ uint32 user_rid,
+ uint32 group_rid,
+ uint16 acb_info,
+
+ uint32 unknown_3,
+ uint16 logon_divs,
+ LOGON_HRS *hrs,
+ uint32 unknown_5,
+ uint32 unknown_6)
+{
+ int len_user_name = user_name != NULL ? strlen(user_name ) : 0;
+ int len_full_name = full_name != NULL ? strlen(full_name ) : 0;
+ int len_home_dir = home_dir != NULL ? strlen(home_dir ) : 0;
+ int len_dir_drive = dir_drive != NULL ? strlen(dir_drive ) : 0;
+ int len_logon_script = logon_script != NULL ? strlen(logon_script) : 0;
+ int len_profile_path = profile_path != NULL ? strlen(profile_path) : 0;
+ int len_description = description != NULL ? strlen(description ) : 0;
+ int len_workstations = workstations != NULL ? strlen(workstations) : 0;
+ int len_unknown_str = unknown_str != NULL ? strlen(unknown_str ) : 0;
+ int len_munged_dial = munged_dial != NULL ? strlen(munged_dial ) : 0;
+
+ usr->logon_time = *logon_time;
+ usr->logoff_time = *logoff_time;
+ usr->kickoff_time = *kickoff_time;
+ usr->pass_last_set_time = *pass_last_set_time;
+ usr->pass_can_change_time = *pass_can_change_time;
+ usr->pass_must_change_time = *pass_must_change_time;
+
+ make_uni_hdr(&(usr->hdr_user_name ), len_user_name , len_user_name , 1);
+ make_uni_hdr(&(usr->hdr_full_name ), len_full_name , len_full_name , 1);
+ make_uni_hdr(&(usr->hdr_home_dir ), len_home_dir , len_home_dir , 1);
+ make_uni_hdr(&(usr->hdr_dir_drive ), len_dir_drive , len_dir_drive , 1);
+ make_uni_hdr(&(usr->hdr_logon_script), len_logon_script, len_logon_script, 1);
+ make_uni_hdr(&(usr->hdr_profile_path), len_profile_path, len_profile_path, 1);
+ make_uni_hdr(&(usr->hdr_acct_desc ), len_description , len_description , 1);
+ make_uni_hdr(&(usr->hdr_workstations), len_workstations, len_workstations, 1);
+ make_uni_hdr(&(usr->hdr_unknown_str ), len_unknown_str , len_unknown_str , 1);
+ make_uni_hdr(&(usr->hdr_munged_dial ), len_munged_dial , len_munged_dial , 1);
+
+ memset((char *)usr->nt_pwd, '\0', sizeof(usr->nt_pwd));
+ memset((char *)usr->lm_pwd, '\0', sizeof(usr->lm_pwd));
+
+ usr->user_rid = user_rid;
+ usr->group_rid = group_rid;
+ usr->acb_info = acb_info;
+ usr->unknown_3 = unknown_3; /* 0x00ff ffff */
+
+ usr->logon_divs = logon_divs; /* should be 168 (hours/week) */
+ usr->ptr_logon_hrs = hrs ? 1 : 0;
+ usr->unknown_5 = unknown_5; /* 0x0002 0000 */
+
+ memset((char *)usr->padding1, '\0', sizeof(usr->padding1));
+
+ make_unistr2(&(usr->uni_user_name ), user_name , len_user_name );
+ make_unistr2(&(usr->uni_full_name ), full_name , len_full_name );
+ make_unistr2(&(usr->uni_home_dir ), home_dir , len_home_dir );
+ make_unistr2(&(usr->uni_dir_drive ), dir_drive , len_dir_drive );
+ make_unistr2(&(usr->uni_logon_script), logon_script, len_logon_script);
+ make_unistr2(&(usr->uni_profile_path), profile_path, len_profile_path);
+ make_unistr2(&(usr->uni_acct_desc ), description , len_description );
+ make_unistr2(&(usr->uni_workstations), workstations, len_workstations);
+ make_unistr2(&(usr->uni_unknown_str ), unknown_str , len_unknown_str );
+ make_unistr2(&(usr->uni_munged_dial ), munged_dial , len_munged_dial );
+
+ usr->unknown_6 = unknown_6; /* 0x0000 04ec */
+ usr->padding4 = 0;
+
+ if (hrs)
+ {
+ memcpy(&(usr->logon_hrs), hrs, sizeof(usr->logon_hrs));
+ }
+ else
+ {
+ memset(&(usr->logon_hrs), 0xff, sizeof(usr->logon_hrs));
+ }
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static void sam_io_user_info21(char *desc, SAM_USER_INFO_21 *usr, prs_struct *ps, int depth)
+{
+ if (usr == NULL) return;
+
+ prs_debug(ps, depth, desc, "lsa_io_user_info");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_time("logon_time ", &(usr->logon_time) , ps, depth);
+ smb_io_time("logoff_time ", &(usr->logoff_time) , ps, depth);
+ smb_io_time("kickoff_time ", &(usr->kickoff_time) , ps, depth);
+ smb_io_time("pass_last_set_time ", &(usr->pass_last_set_time) , ps, depth);
+ smb_io_time("pass_can_change_time ", &(usr->pass_can_change_time) , ps, depth);
+ smb_io_time("pass_must_change_time", &(usr->pass_must_change_time), ps, depth);
+
+ smb_io_unihdr("hdr_user_name ", &(usr->hdr_user_name) , ps, depth); /* username unicode string header */
+ smb_io_unihdr("hdr_full_name ", &(usr->hdr_full_name) , ps, depth); /* user's full name unicode string header */
+ smb_io_unihdr("hdr_home_dir ", &(usr->hdr_home_dir) , ps, depth); /* home directory unicode string header */
+ smb_io_unihdr("hdr_dir_drive ", &(usr->hdr_dir_drive) , ps, depth); /* home directory drive */
+ smb_io_unihdr("hdr_logon_script", &(usr->hdr_logon_script), ps, depth); /* logon script unicode string header */
+ smb_io_unihdr("hdr_profile_path", &(usr->hdr_profile_path), ps, depth); /* profile path unicode string header */
+ smb_io_unihdr("hdr_acct_desc ", &(usr->hdr_acct_desc ) , ps, depth); /* account description */
+ smb_io_unihdr("hdr_workstations", &(usr->hdr_workstations), ps, depth); /* workstations user can log on from */
+ smb_io_unihdr("hdr_unknown_str ", &(usr->hdr_unknown_str ), ps, depth); /* unknown string */
+ smb_io_unihdr("hdr_munged_dial ", &(usr->hdr_munged_dial ), ps, depth); /* workstations user can log on from */
+
+ prs_uint8s (False, "lm_pwd ", ps, depth, usr->lm_pwd , sizeof(usr->lm_pwd ));
+ prs_uint8s (False, "nt_pwd ", ps, depth, usr->nt_pwd , sizeof(usr->nt_pwd ));
+
+ prs_uint32("user_rid ", ps, depth, &(usr->user_rid )); /* User ID */
+ prs_uint32("group_rid ", ps, depth, &(usr->group_rid )); /* Group ID */
+ prs_uint16("acb_info ", ps, depth, &(usr->acb_info )); /* Group ID */
+ prs_align(ps);
+
+ prs_uint32("unknown_3 ", ps, depth, &(usr->unknown_3 ));
+ prs_uint16("logon_divs ", ps, depth, &(usr->logon_divs )); /* logon divisions per week */
+ prs_align(ps);
+ prs_uint32("ptr_logon_hrs ", ps, depth, &(usr->ptr_logon_hrs));
+ prs_uint32("unknown_5 ", ps, depth, &(usr->unknown_5 ));
+
+ prs_uint8s (False, "padding1 ", ps, depth, usr->padding1, sizeof(usr->padding1));
+
+ /* here begins pointed-to data */
+
+ smb_io_unistr2("uni_user_name ", &(usr->uni_user_name) , usr->hdr_user_name .buffer, ps, depth); /* username unicode string */
+ smb_io_unistr2("uni_full_name ", &(usr->uni_full_name) , usr->hdr_full_name .buffer, ps, depth); /* user's full name unicode string */
+ smb_io_unistr2("uni_home_dir ", &(usr->uni_home_dir) , usr->hdr_home_dir .buffer, ps, depth); /* home directory unicode string */
+ smb_io_unistr2("uni_dir_drive ", &(usr->uni_dir_drive) , usr->hdr_dir_drive .buffer, ps, depth); /* home directory drive unicode string */
+ smb_io_unistr2("uni_logon_script", &(usr->uni_logon_script), usr->hdr_logon_script.buffer, ps, depth); /* logon script unicode string */
+ smb_io_unistr2("uni_profile_path", &(usr->uni_profile_path), usr->hdr_profile_path.buffer, ps, depth); /* profile path unicode string */
+ smb_io_unistr2("uni_acct_desc ", &(usr->uni_acct_desc ), usr->hdr_acct_desc .buffer, ps, depth); /* user description unicode string */
+ smb_io_unistr2("uni_workstations", &(usr->uni_workstations), usr->hdr_workstations.buffer, ps, depth); /* worksations user can log on from */
+ smb_io_unistr2("uni_unknown_str ", &(usr->uni_unknown_str ), usr->hdr_unknown_str .buffer, ps, depth); /* unknown string */
+ smb_io_unistr2("uni_munged_dial ", &(usr->uni_munged_dial ), usr->hdr_munged_dial .buffer, ps, depth); /* worksations user can log on from */
+
+ prs_uint32("unknown_6 ", ps, depth, &(usr->unknown_6 ));
+ prs_uint32("padding4 ", ps, depth, &(usr->padding4 ));
+
+ if (usr->ptr_logon_hrs)
+ {
+ sam_io_logon_hrs("logon_hrs", &(usr->logon_hrs) , ps, depth);
+ prs_align(ps);
+ }
+}
+
+
+/*******************************************************************
+makes a SAMR_R_QUERY_USERINFO structure.
+********************************************************************/
+void make_samr_r_query_userinfo(SAMR_R_QUERY_USERINFO *r_u,
+ uint16 switch_value, void *info, uint32 status)
+
+{
+ if (r_u == NULL || info == NULL) return;
+
+ DEBUG(5,("make_samr_r_query_userinfo\n"));
+
+ r_u->ptr = 0;
+ r_u->switch_value = 0;
+
+ if (status == 0)
+ {
+ r_u->switch_value = switch_value;
+
+ switch (switch_value)
+ {
+ case 0x10:
+ {
+ r_u->ptr = 1;
+ r_u->info.id10 = (SAM_USER_INFO_10*)info;
+
+ break;
+ }
+
+ case 0x11:
+ {
+ r_u->ptr = 1;
+ r_u->info.id11 = (SAM_USER_INFO_11*)info;
+
+ break;
+ }
+
+ case 21:
+ {
+ r_u->ptr = 1;
+ r_u->info.id21 = (SAM_USER_INFO_21*)info;
+
+ break;
+ }
+
+ default:
+ {
+ DEBUG(4,("make_samr_r_query_aliasinfo: unsupported switch level\n"));
+ break;
+ }
+ }
+ }
+
+ r_u->status = status; /* return status */
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_r_query_userinfo(char *desc, SAMR_R_QUERY_USERINFO *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_r_query_userinfo");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("ptr ", ps, depth, &(r_u->ptr ));
+ prs_uint16("switch_value", ps, depth, &(r_u->switch_value));
+ prs_align(ps);
+
+ if (r_u->ptr != 0 && r_u->switch_value != 0)
+ {
+ switch (r_u->switch_value)
+ {
+ case 0x10:
+ {
+ if (r_u->info.id10 != NULL)
+ {
+ sam_io_user_info10("", r_u->info.id10, ps, depth);
+ }
+ else
+ {
+ DEBUG(2,("samr_io_r_query_userinfo: info pointer not initialised\n"));
+ return;
+ }
+ break;
+ }
+/*
+ case 0x11:
+ {
+ if (r_u->info.id11 != NULL)
+ {
+ sam_io_user_info11("", r_u->info.id11, ps, depth);
+ }
+ else
+ {
+ DEBUG(2,("samr_io_r_query_userinfo: info pointer not initialised\n"));
+ return;
+ }
+ break;
+ }
+*/
+ case 21:
+ {
+ if (r_u->info.id21 != NULL)
+ {
+ sam_io_user_info21("", r_u->info.id21, ps, depth);
+ }
+ else
+ {
+ DEBUG(2,("samr_io_r_query_userinfo: info pointer not initialised\n"));
+ return;
+ }
+ break;
+ }
+ default:
+ {
+ DEBUG(2,("samr_io_r_query_userinfo: unknown switch level\n"));
+ break;
+ }
+
+ }
+ }
+
+ prs_uint32("status", ps, depth, &(r_u->status));
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_q_unknown_32(char *desc, SAMR_Q_UNKNOWN_32 *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_q_unknown_32");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("pol", &(q_u->pol), ps, depth);
+ prs_align(ps);
+
+ smb_io_unihdr ("", &(q_u->hdr_mach_acct), ps, depth);
+ smb_io_unistr2("", &(q_u->uni_mach_acct), q_u->hdr_mach_acct.buffer, ps, depth);
+
+ prs_align(ps);
+
+ prs_uint32("acct_ctrl", ps, depth, &(q_u->acct_ctrl));
+ prs_uint16("unknown_1", ps, depth, &(q_u->unknown_1));
+ prs_uint16("unknown_2", ps, depth, &(q_u->unknown_2));
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_r_unknown_32(char *desc, SAMR_R_UNKNOWN_32 *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_r_unknown_32");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("pol", &(r_u->pol), ps, depth);
+ prs_align(ps);
+
+ prs_uint32("status", ps, depth, &(r_u->status));
+}
+
+
+/*******************************************************************
+makes a SAMR_Q_CONNECT structure.
+********************************************************************/
+void make_samr_q_connect(SAMR_Q_CONNECT *q_u,
+ char *srv_name, uint32 unknown_0)
+{
+ int len_srv_name = strlen(srv_name);
+
+ if (q_u == NULL) return;
+
+ DEBUG(5,("make_q_connect\n"));
+
+ /* make PDC server name \\server */
+ q_u->ptr_srv_name = len_srv_name > 0 ? 1 : 0;
+ make_unistr2(&(q_u->uni_srv_name), srv_name, len_srv_name+1);
+
+ /* example values: 0x0000 0002 */
+ q_u->unknown_0 = unknown_0;
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_q_connect(char *desc, SAMR_Q_CONNECT *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_q_connect");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("ptr_srv_name", ps, depth, &(q_u->ptr_srv_name));
+ smb_io_unistr2("", &(q_u->uni_srv_name), q_u->ptr_srv_name, ps, depth);
+
+ prs_align(ps);
+
+ prs_uint32("unknown_0 ", ps, depth, &(q_u->unknown_0 ));
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_r_connect(char *desc, SAMR_R_CONNECT *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_r_connect");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("connect_pol", &(r_u->connect_pol), ps, depth);
+ prs_align(ps);
+
+ prs_uint32("status", ps, depth, &(r_u->status));
+}
+
+/*******************************************************************
+makes a SAMR_Q_CONNECT_ANON structure.
+********************************************************************/
+void make_samr_q_connect_anon(SAMR_Q_CONNECT_ANON *q_u)
+{
+ if (q_u == NULL) return;
+
+ DEBUG(5,("make_q_connect_anon\n"));
+
+ q_u->ptr = 1;
+ q_u->unknown_0 = 0x5c; /* server name (?!!) */
+ q_u->unknown_1 = 0x01;
+ q_u->unknown_2 = 0x20;
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_q_connect_anon(char *desc, SAMR_Q_CONNECT_ANON *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_q_connect_anon");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("ptr ", ps, depth, &(q_u->ptr ));
+ prs_uint16("unknown_0", ps, depth, &(q_u->unknown_0));
+ prs_uint16("unknown_1", ps, depth, &(q_u->unknown_1));
+ prs_uint32("unknown_2", ps, depth, &(q_u->unknown_2));
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_r_connect_anon(char *desc, SAMR_R_CONNECT_ANON *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_r_connect_anon");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("connect_pol", &(r_u->connect_pol), ps, depth);
+ prs_align(ps);
+
+ prs_uint32("status", ps, depth, &(r_u->status));
+}
+
+/*******************************************************************
+makes a SAMR_Q_OPEN_ALIAS structure.
+********************************************************************/
+void make_samr_q_open_alias(SAMR_Q_OPEN_ALIAS *q_u,
+ uint32 unknown_0, uint32 rid)
+{
+ if (q_u == NULL) return;
+
+ DEBUG(5,("make_q_open_alias\n"));
+
+ /* example values: 0x0000 0008 */
+ q_u->unknown_0 = unknown_0;
+
+ q_u->rid_alias = rid;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_q_open_alias(char *desc, SAMR_Q_OPEN_ALIAS *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_q_open_alias");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("unknown_0", ps, depth, &(q_u->unknown_0));
+ prs_uint32("rid_alias", ps, depth, &(q_u->rid_alias));
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_r_open_alias(char *desc, SAMR_R_OPEN_ALIAS *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_r_open_alias");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("pol", &(r_u->pol), ps, depth);
+ prs_align(ps);
+
+ prs_uint32("status", ps, depth, &(r_u->status));
+}
+
+/*******************************************************************
+makes a SAMR_Q_UNKNOWN_12 structure.
+********************************************************************/
+void make_samr_q_unknown_12(SAMR_Q_UNKNOWN_12 *q_u,
+ POLICY_HND *pol, uint32 rid,
+ uint32 num_gids, uint32 *gid)
+{
+ int i;
+ if (q_u == NULL) return;
+
+ DEBUG(5,("make_samr_r_unknwon_12\n"));
+
+ memcpy(&(q_u->pol), pol, sizeof(*pol));
+
+ q_u->num_gids1 = num_gids;
+ q_u->rid = rid;
+ q_u->ptr = 0;
+ q_u->num_gids2 = num_gids;
+
+ for (i = 0; i < num_gids; i++)
+ {
+ q_u->gid[i] = gid[i];
+ }
+}
+
+
+/*******************************************************************
+makes a SAMR_Q_UNKNOWN_21 structure.
+********************************************************************/
+void make_samr_q_unknown_21(SAMR_Q_UNKNOWN_21 *q_c,
+ POLICY_HND *hnd, uint16 unk_1, uint16 unk_2)
+{
+ if (q_c == NULL || hnd == NULL) return;
+
+ DEBUG(5,("make_samr_q_unknown_21\n"));
+
+ memcpy(&(q_c->group_pol), hnd, sizeof(q_c->group_pol));
+ q_c->unknown_1 = unk_1;
+ q_c->unknown_2 = unk_2;
+}
+
+
+/*******************************************************************
+makes a SAMR_Q_UNKNOWN_13 structure.
+********************************************************************/
+void make_samr_q_unknown_13(SAMR_Q_UNKNOWN_13 *q_c,
+ POLICY_HND *hnd, uint16 unk_1, uint16 unk_2)
+{
+ if (q_c == NULL || hnd == NULL) return;
+
+ DEBUG(5,("make_samr_q_unknown_13\n"));
+
+ memcpy(&(q_c->alias_pol), hnd, sizeof(q_c->alias_pol));
+ q_c->unknown_1 = unk_1;
+ q_c->unknown_2 = unk_2;
+}
+
+
+/*******************************************************************
+makes a SAMR_Q_UNKNOWN_38 structure.
+********************************************************************/
+void make_samr_q_unknown_38(SAMR_Q_UNKNOWN_38 *q_u, char *srv_name)
+{
+ int len_srv_name = strlen(srv_name);
+
+ if (q_u == NULL) return;
+
+ DEBUG(5,("make_q_unknown_38\n"));
+
+ q_u->ptr = 1;
+ make_uni_hdr(&(q_u->hdr_srv_name), len_srv_name, len_srv_name, len_srv_name != 0);
+ make_unistr2(&(q_u->uni_srv_name), srv_name, len_srv_name);
+
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_q_unknown_38(char *desc, SAMR_Q_UNKNOWN_38 *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_q_unknown_38");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("ptr", ps, depth, &(q_u->ptr));
+ if (q_u->ptr != 0)
+ {
+ smb_io_unihdr ("", &(q_u->hdr_srv_name), ps, depth);
+ smb_io_unistr2("", &(q_u->uni_srv_name), q_u->hdr_srv_name.buffer, ps, depth);
+ }
+}
+
+/*******************************************************************
+makes a SAMR_R_UNKNOWN_38 structure.
+********************************************************************/
+void make_samr_r_unknown_38(SAMR_R_UNKNOWN_38 *r_u)
+{
+ if (r_u == NULL) return;
+
+ DEBUG(5,("make_r_unknown_38\n"));
+
+ r_u->unk_0 = 0;
+ r_u->unk_1 = 0;
+ r_u->unk_2 = 0;
+ r_u->unk_3 = 0;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_r_unknown_38(char *desc, SAMR_R_UNKNOWN_38 *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_r_unknown_38");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint16("unk_0", ps, depth, &(r_u->unk_0));
+ prs_align(ps);
+ prs_uint16("unk_1", ps, depth, &(r_u->unk_1));
+ prs_align(ps);
+ prs_uint16("unk_2", ps, depth, &(r_u->unk_2));
+ prs_align(ps);
+ prs_uint16("unk_3", ps, depth, &(r_u->unk_3));
+ prs_align(ps);
+}
+
+/*******************************************************************
+make a SAMR_ENC_PASSWD structure.
+********************************************************************/
+void make_enc_passwd(SAMR_ENC_PASSWD *pwd, char pass[512])
+{
+ if (pwd == NULL) return;
+
+ pwd->ptr = 1;
+ memcpy(pwd->pass, pass, sizeof(pwd->pass));
+}
+
+/*******************************************************************
+reads or writes a SAMR_ENC_PASSWD structure.
+********************************************************************/
+void samr_io_enc_passwd(char *desc, SAMR_ENC_PASSWD *pwd, prs_struct *ps, int depth)
+{
+ if (pwd == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_enc_passwd");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("ptr", ps, depth, &(pwd->ptr));
+ prs_uint8s(False, "pwd", ps, depth, pwd->pass, sizeof(pwd->pass));
+}
+
+/*******************************************************************
+makes a SAMR_ENC_HASH structure.
+********************************************************************/
+void make_enc_hash(SAMR_ENC_HASH *hsh, uchar hash[16])
+{
+ if (hsh == NULL) return;
+
+ hsh->ptr = 1;
+ memcpy(hsh->hash, hash, sizeof(hsh->hash));
+}
+
+/*******************************************************************
+reads or writes a SAMR_ENC_HASH structure.
+********************************************************************/
+void samr_io_enc_hash(char *desc, SAMR_ENC_HASH *hsh, prs_struct *ps, int depth)
+{
+ if (hsh == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_enc_hash");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("ptr ", ps, depth, &(hsh->ptr));
+ prs_uint8s(False, "hash", ps, depth, hsh->hash, sizeof(hsh->hash));
+}
+
+/*******************************************************************
+makes a SAMR_R_UNKNOWN_38 structure.
+********************************************************************/
+void make_samr_q_chgpasswd_user(SAMR_Q_CHGPASSWD_USER *q_u,
+ char *dest_host, char *user_name,
+ char nt_newpass[516], uchar nt_oldhash[16],
+ char lm_newpass[516], uchar lm_oldhash[16])
+{
+ int len_dest_host = strlen(dest_host);
+ int len_user_name = strlen(user_name);
+
+ if (q_u == NULL) return;
+
+ DEBUG(5,("make_samr_q_chgpasswd_user\n"));
+
+ q_u->ptr_0 = 1;
+ make_uni_hdr(&(q_u->hdr_dest_host), len_dest_host, len_dest_host, len_dest_host != 0);
+ make_unistr2(&(q_u->uni_dest_host), dest_host, len_dest_host);
+ make_uni_hdr(&(q_u->hdr_user_name), len_user_name, len_user_name, len_user_name != 0);
+ make_unistr2(&(q_u->uni_user_name), user_name, len_user_name);
+
+ make_enc_passwd(&(q_u->nt_newpass), nt_newpass);
+ make_enc_hash (&(q_u->nt_oldhash), nt_oldhash);
+
+ q_u->unknown = 0x01;
+
+ make_enc_passwd(&(q_u->lm_newpass), lm_newpass);
+ make_enc_hash (&(q_u->lm_oldhash), lm_oldhash);
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_q_chgpasswd_user(char *desc, SAMR_Q_CHGPASSWD_USER *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_q_chgpasswd_user");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("ptr_0", ps, depth, &(q_u->ptr_0));
+
+ smb_io_unihdr ("", &(q_u->hdr_dest_host), ps, depth);
+ smb_io_unistr2("", &(q_u->uni_dest_host), q_u->hdr_dest_host.buffer, ps, depth);
+ smb_io_unihdr ("", &(q_u->hdr_user_name), ps, depth);
+ smb_io_unistr2("", &(q_u->uni_user_name), q_u->hdr_user_name.buffer, ps, depth);
+
+ samr_io_enc_passwd("nt_newpass", &(q_u->nt_newpass), ps, depth);
+ prs_grow(ps);
+ samr_io_enc_hash ("nt_oldhash", &(q_u->nt_oldhash), ps, depth);
+
+ prs_uint32("unknown", ps, depth, &(q_u->unknown));
+
+ samr_io_enc_passwd("lm_newpass", &(q_u->lm_newpass), ps, depth);
+ prs_grow(ps);
+ samr_io_enc_hash ("lm_oldhash", &(q_u->lm_oldhash), ps, depth);
+}
+
+/*******************************************************************
+makes a SAMR_R_CHGPASSWD_USER structure.
+********************************************************************/
+void make_samr_r_chgpasswd_user(SAMR_R_CHGPASSWD_USER *r_u, uint32 status)
+{
+ if (r_u == NULL) return;
+
+ DEBUG(5,("make_r_chgpasswd_user\n"));
+
+ r_u->status = status;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_r_chgpasswd_user(char *desc, SAMR_R_CHGPASSWD_USER *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_r_chgpasswd_user");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("status", ps, depth, &(r_u->status));
+}
+
+
prs_uint32("status ", ps, depth, &(r_n->status));
}
+/*******************************************************************
+ makes a SESS_INFO_0_STR structure
+********************************************************************/
+void make_srv_sess_info0_str(SESS_INFO_0_STR *ss0, char *name)
+{
+ if (ss0 == NULL) return;
+
+ DEBUG(5,("make_srv_sess_info0_str\n"));
+
+ make_unistr2(&(ss0->uni_name), name, strlen(name)+1);
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static void srv_io_sess_info0_str(char *desc, SESS_INFO_0_STR *ss0, prs_struct *ps, int depth)
+{
+ if (ss0 == NULL) return;
+
+ prs_debug(ps, depth, desc, "srv_io_sess_info0_str");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_unistr2("", &(ss0->uni_name), True, ps, depth);
+}
+
+/*******************************************************************
+ makes a SESS_INFO_0 structure
+********************************************************************/
+void make_srv_sess_info0(SESS_INFO_0 *ss0, char *name)
+{
+ if (ss0 == NULL) return;
+
+ DEBUG(5,("make_srv_sess_info0: %s\n", name));
+
+ ss0->ptr_name = name != NULL ? 1 : 0;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static void srv_io_sess_info0(char *desc, SESS_INFO_0 *ss0, prs_struct *ps, int depth)
+{
+ if (ss0 == NULL) return;
+
+ prs_debug(ps, depth, desc, "srv_io_sess_info0");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("ptr_name", ps, depth, &(ss0->ptr_name));
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static void srv_io_srv_sess_info_0(char *desc, SRV_SESS_INFO_0 *ss0, prs_struct *ps, int depth)
+{
+ if (ss0 == NULL) return;
+
+ prs_debug(ps, depth, desc, "srv_io_srv_sess_info_0");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("num_entries_read", ps, depth, &(ss0->num_entries_read));
+ prs_uint32("ptr_sess_info", ps, depth, &(ss0->ptr_sess_info));
+
+ if (ss0->ptr_sess_info != 0)
+ {
+ int i;
+ int num_entries = ss0->num_entries_read;
+ if (num_entries > MAX_SESS_ENTRIES)
+ {
+ num_entries = MAX_SESS_ENTRIES; /* report this! */
+ }
+
+ prs_uint32("num_entries_read2", ps, depth, &(ss0->num_entries_read2));
+
+ SMB_ASSERT_ARRAY(ss0->info_0, num_entries);
+
+ for (i = 0; i < num_entries; i++)
+ {
+ prs_grow(ps);
+ srv_io_sess_info0("", &(ss0->info_0[i]), ps, depth);
+ }
+
+ for (i = 0; i < num_entries; i++)
+ {
+ prs_grow(ps);
+ srv_io_sess_info0_str("", &(ss0->info_0_str[i]), ps, depth);
+ }
+
+ prs_align(ps);
+ }
+}
+
+/*******************************************************************
+ makes a SESS_INFO_1_STR structure
+********************************************************************/
+void make_srv_sess_info1_str(SESS_INFO_1_STR *ss1, char *name, char *user)
+{
+ if (ss1 == NULL) return;
+
+ DEBUG(5,("make_srv_sess_info1_str\n"));
+
+ make_unistr2(&(ss1->uni_name), name, strlen(name)+1);
+ make_unistr2(&(ss1->uni_user), name, strlen(user)+1);
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static void srv_io_sess_info1_str(char *desc, SESS_INFO_1_STR *ss1, prs_struct *ps, int depth)
+{
+ if (ss1 == NULL) return;
+
+ prs_debug(ps, depth, desc, "srv_io_sess_info1_str");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_unistr2("", &(ss1->uni_name), True, ps, depth);
+ smb_io_unistr2("", &(ss1->uni_user), True, ps, depth);
+}
+
+/*******************************************************************
+ makes a SESS_INFO_1 structure
+********************************************************************/
+void make_srv_sess_info1(SESS_INFO_1 *ss1,
+ char *name, char *user,
+ uint32 num_opens, uint32 open_time, uint32 idle_time,
+ uint32 user_flags)
+{
+ if (ss1 == NULL) return;
+
+ DEBUG(5,("make_srv_sess_info1: %s\n", name));
+
+ ss1->ptr_name = name != NULL ? 1 : 0;
+ ss1->ptr_user = user != NULL ? 1 : 0;
+
+ ss1->num_opens = num_opens;
+ ss1->open_time = open_time;
+ ss1->idle_time = idle_time;
+ ss1->user_flags = user_flags;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static void srv_io_sess_info1(char *desc, SESS_INFO_1 *ss1, prs_struct *ps, int depth)
+{
+ if (ss1 == NULL) return;
+
+ prs_debug(ps, depth, desc, "srv_io_sess_info1");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("ptr_name ", ps, depth, &(ss1->ptr_name ));
+ prs_uint32("ptr_user ", ps, depth, &(ss1->ptr_user ));
+
+ prs_uint32("num_opens ", ps, depth, &(ss1->num_opens ));
+ prs_uint32("open_time ", ps, depth, &(ss1->open_time ));
+ prs_uint32("idle_time ", ps, depth, &(ss1->idle_time ));
+ prs_uint32("user_flags", ps, depth, &(ss1->user_flags));
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static void srv_io_srv_sess_info_1(char *desc, SRV_SESS_INFO_1 *ss1, prs_struct *ps, int depth)
+{
+ if (ss1 == NULL) return;
+
+ prs_debug(ps, depth, desc, "srv_io_srv_sess_info_1");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("num_entries_read", ps, depth, &(ss1->num_entries_read));
+ prs_uint32("ptr_sess_info", ps, depth, &(ss1->ptr_sess_info));
+
+ if (ss1->ptr_sess_info != 0)
+ {
+ int i;
+ int num_entries = ss1->num_entries_read;
+ if (num_entries > MAX_SESS_ENTRIES)
+ {
+ num_entries = MAX_SESS_ENTRIES; /* report this! */
+ }
+
+ prs_uint32("num_entries_read2", ps, depth, &(ss1->num_entries_read2));
+
+ SMB_ASSERT_ARRAY(ss1->info_1, num_entries);
+
+ for (i = 0; i < num_entries; i++)
+ {
+ prs_grow(ps);
+ srv_io_sess_info1("", &(ss1->info_1[i]), ps, depth);
+ }
+
+ for (i = 0; i < num_entries; i++)
+ {
+ prs_grow(ps);
+ srv_io_sess_info1_str("", &(ss1->info_1_str[i]), ps, depth);
+ }
+
+ prs_align(ps);
+ }
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static void srv_io_srv_sess_ctr(char *desc, SRV_SESS_INFO_CTR *ctr, prs_struct *ps, int depth)
+{
+ if (ctr == NULL) return;
+
+ prs_debug(ps, depth, desc, "srv_io_srv_sess_ctr");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("switch_value", ps, depth, &(ctr->switch_value));
+ prs_uint32("ptr_sess_ctr", ps, depth, &(ctr->ptr_sess_ctr));
+
+ if (ctr->ptr_sess_ctr != 0)
+ {
+ switch (ctr->switch_value)
+ {
+ case 0:
+ {
+ srv_io_srv_sess_info_0("", &(ctr->sess.info0), ps, depth);
+ break;
+ }
+ case 1:
+ {
+ srv_io_srv_sess_info_1("", &(ctr->sess.info1), ps, depth);
+ break;
+ }
+ default:
+ {
+ DEBUG(5,("%s no session info at switch_value %d\n",
+ tab_depth(depth), ctr->switch_value));
+ break;
+ }
+ }
+ }
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void make_srv_q_net_sess_enum(SRV_Q_NET_SESS_ENUM *q_n,
+ char *srv_name, char *qual_name,
+ uint32 sess_level, SRV_SESS_INFO_CTR *ctr,
+ uint32 preferred_len,
+ ENUM_HND *hnd)
+{
+ if (q_n == NULL || ctr == NULL || hnd == NULL) return;
+
+ q_n->ctr = ctr;
+
+ DEBUG(5,("make_q_net_sess_enum\n"));
+
+ make_buf_unistr2(&(q_n->uni_srv_name), &(q_n->ptr_srv_name), srv_name);
+ make_buf_unistr2(&(q_n->uni_qual_name), &(q_n->ptr_qual_name), qual_name);
+
+ q_n->sess_level = sess_level;
+ q_n->preferred_len = preferred_len;
+
+ memcpy(&(q_n->enum_hnd), hnd, sizeof(*hnd));
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void srv_io_q_net_sess_enum(char *desc, SRV_Q_NET_SESS_ENUM *q_n, prs_struct *ps, int depth)
+{
+ if (q_n == NULL) return;
+
+ prs_debug(ps, depth, desc, "srv_io_q_net_sess_enum");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("ptr_srv_name", ps, depth, &(q_n->ptr_srv_name));
+ smb_io_unistr2("", &(q_n->uni_srv_name), True, ps, depth);
+
+ prs_align(ps);
+
+ prs_uint32("ptr_qual_name", ps, depth, &(q_n->ptr_qual_name));
+ smb_io_unistr2("", &(q_n->uni_qual_name), q_n->ptr_qual_name, ps, depth);
+
+ prs_align(ps);
+
+ prs_uint32("sess_level", ps, depth, &(q_n->sess_level ));
+
+ if (q_n->sess_level != -1)
+ {
+ srv_io_srv_sess_ctr("sess_ctr", q_n->ctr, ps, depth);
+ }
+
+ prs_uint32("preferred_len", ps, depth, &(q_n->preferred_len));
+
+ smb_io_enum_hnd("enum_hnd", &(q_n->enum_hnd), ps, depth);
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void srv_io_r_net_sess_enum(char *desc, SRV_R_NET_SESS_ENUM *r_n, prs_struct *ps, int depth)
+{
+ if (r_n == NULL) return;
+
+ prs_debug(ps, depth, desc, "srv_io_r_net_sess_enum");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("sess_level", ps, depth, &(r_n->sess_level));
+
+ if (r_n->sess_level != -1)
+ {
+ srv_io_srv_sess_ctr("sess_ctr", r_n->ctr, ps, depth);
+ }
+
+ prs_uint32("total_entries", ps, depth, &(r_n->total_entries));
+ smb_io_enum_hnd("enum_hnd", &(r_n->enum_hnd), ps, depth);
+ prs_uint32("status ", ps, depth, &(r_n->status));
+}
+
+/*******************************************************************
+ makes a CONN_INFO_0 structure
+********************************************************************/
+void make_srv_conn_info0(CONN_INFO_0 *ss0, uint32 id)
+{
+ if (ss0 == NULL) return;
+
+ DEBUG(5,("make_srv_conn_info0\n"));
+
+ ss0->id = id;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static void srv_io_conn_info0(char *desc, CONN_INFO_0 *ss0, prs_struct *ps, int depth)
+{
+ if (ss0 == NULL) return;
+
+ prs_debug(ps, depth, desc, "srv_io_conn_info0");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("id", ps, depth, &(ss0->id));
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static void srv_io_srv_conn_info_0(char *desc, SRV_CONN_INFO_0 *ss0, prs_struct *ps, int depth)
+{
+ if (ss0 == NULL) return;
+
+ prs_debug(ps, depth, desc, "srv_io_srv_conn_info_0");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("num_entries_read", ps, depth, &(ss0->num_entries_read));
+ prs_uint32("ptr_conn_info", ps, depth, &(ss0->ptr_conn_info));
+
+ if (ss0->ptr_conn_info != 0)
+ {
+ int i;
+ int num_entries = ss0->num_entries_read;
+ if (num_entries > MAX_CONN_ENTRIES)
+ {
+ num_entries = MAX_CONN_ENTRIES; /* report this! */
+ }
+
+ prs_uint32("num_entries_read2", ps, depth, &(ss0->num_entries_read2));
+
+ for (i = 0; i < num_entries; i++)
+ {
+ prs_grow(ps);
+ srv_io_conn_info0("", &(ss0->info_0[i]), ps, depth);
+ }
+
+ prs_align(ps);
+ }
+}
+
+/*******************************************************************
+ makes a CONN_INFO_1_STR structure
+********************************************************************/
+void make_srv_conn_info1_str(CONN_INFO_1_STR *ss1, char *usr_name, char *net_name)
+{
+ if (ss1 == NULL) return;
+
+ DEBUG(5,("make_srv_conn_info1_str\n"));
+
+ make_unistr2(&(ss1->uni_usr_name), usr_name, strlen(usr_name)+1);
+ make_unistr2(&(ss1->uni_net_name), net_name, strlen(net_name)+1);
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static void srv_io_conn_info1_str(char *desc, CONN_INFO_1_STR *ss1, prs_struct *ps, int depth)
+{
+ if (ss1 == NULL) return;
+
+ prs_debug(ps, depth, desc, "srv_io_conn_info1_str");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_unistr2("", &(ss1->uni_usr_name), True, ps, depth);
+ smb_io_unistr2("", &(ss1->uni_net_name), True, ps, depth);
+}
+
+/*******************************************************************
+ makes a CONN_INFO_1 structure
+********************************************************************/
+void make_srv_conn_info1(CONN_INFO_1 *ss1,
+ uint32 id, uint32 type,
+ uint32 num_opens, uint32 num_users, uint32 open_time,
+ char *usr_name, char *net_name)
+{
+ if (ss1 == NULL) return;
+
+ DEBUG(5,("make_srv_conn_info1: %s %s\n", usr_name, net_name));
+
+ ss1->id = id ;
+ ss1->type = type ;
+ ss1->num_opens = num_opens ;
+ ss1->num_users = num_users;
+ ss1->open_time = open_time;
+
+ ss1->ptr_usr_name = usr_name != NULL ? 1 : 0;
+ ss1->ptr_net_name = net_name != NULL ? 1 : 0;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static void srv_io_conn_info1(char *desc, CONN_INFO_1 *ss1, prs_struct *ps, int depth)
+{
+ if (ss1 == NULL) return;
+
+ prs_debug(ps, depth, desc, "srv_io_conn_info1");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("id ", ps, depth, &(ss1->id ));
+ prs_uint32("type ", ps, depth, &(ss1->type ));
+ prs_uint32("num_opens ", ps, depth, &(ss1->num_opens ));
+ prs_uint32("num_users ", ps, depth, &(ss1->num_users ));
+ prs_uint32("open_time ", ps, depth, &(ss1->open_time ));
+
+ prs_uint32("ptr_usr_name", ps, depth, &(ss1->ptr_usr_name));
+ prs_uint32("ptr_net_name", ps, depth, &(ss1->ptr_net_name));
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static void srv_io_srv_conn_info_1(char *desc, SRV_CONN_INFO_1 *ss1, prs_struct *ps, int depth)
+{
+ if (ss1 == NULL) return;
+
+ prs_debug(ps, depth, desc, "srv_io_srv_conn_info_1");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("num_entries_read", ps, depth, &(ss1->num_entries_read));
+ prs_uint32("ptr_conn_info", ps, depth, &(ss1->ptr_conn_info));
+
+ if (ss1->ptr_conn_info != 0)
+ {
+ int i;
+ int num_entries = ss1->num_entries_read;
+ if (num_entries > MAX_CONN_ENTRIES)
+ {
+ num_entries = MAX_CONN_ENTRIES; /* report this! */
+ }
+
+ prs_uint32("num_entries_read2", ps, depth, &(ss1->num_entries_read2));
+
+ for (i = 0; i < num_entries; i++)
+ {
+ prs_grow(ps);
+ srv_io_conn_info1("", &(ss1->info_1[i]), ps, depth);
+ }
+
+ for (i = 0; i < num_entries; i++)
+ {
+ prs_grow(ps);
+ srv_io_conn_info1_str("", &(ss1->info_1_str[i]), ps, depth);
+ }
+
+ prs_align(ps);
+ }
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static void srv_io_srv_conn_ctr(char *desc, SRV_CONN_INFO_CTR *ctr, prs_struct *ps, int depth)
+{
+ if (ctr == NULL) return;
+
+ prs_debug(ps, depth, desc, "srv_io_srv_conn_ctr");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("switch_value", ps, depth, &(ctr->switch_value));
+ prs_uint32("ptr_conn_ctr", ps, depth, &(ctr->ptr_conn_ctr));
+
+ if (ctr->ptr_conn_ctr != 0)
+ {
+ switch (ctr->switch_value)
+ {
+ case 0:
+ {
+ srv_io_srv_conn_info_0("", &(ctr->conn.info0), ps, depth);
+ break;
+ }
+ case 1:
+ {
+ srv_io_srv_conn_info_1("", &(ctr->conn.info1), ps, depth);
+ break;
+ }
+ default:
+ {
+ DEBUG(5,("%s no connection info at switch_value %d\n",
+ tab_depth(depth), ctr->switch_value));
+ break;
+ }
+ }
+ }
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void make_srv_q_net_conn_enum(SRV_Q_NET_CONN_ENUM *q_n,
+ char *srv_name, char *qual_name,
+ uint32 conn_level, SRV_CONN_INFO_CTR *ctr,
+ uint32 preferred_len,
+ ENUM_HND *hnd)
+{
+ if (q_n == NULL || ctr == NULL || hnd == NULL) return;
+
+ q_n->ctr = ctr;
+
+ DEBUG(5,("make_q_net_conn_enum\n"));
+
+ make_buf_unistr2(&(q_n->uni_srv_name ), &(q_n->ptr_srv_name ), srv_name );
+ make_buf_unistr2(&(q_n->uni_qual_name), &(q_n->ptr_qual_name), qual_name);
+
+ q_n->conn_level = conn_level;
+ q_n->preferred_len = preferred_len;
+
+ memcpy(&(q_n->enum_hnd), hnd, sizeof(*hnd));
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void srv_io_q_net_conn_enum(char *desc, SRV_Q_NET_CONN_ENUM *q_n, prs_struct *ps, int depth)
+{
+ if (q_n == NULL) return;
+
+ prs_debug(ps, depth, desc, "srv_io_q_net_conn_enum");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("ptr_srv_name ", ps, depth, &(q_n->ptr_srv_name));
+ smb_io_unistr2("", &(q_n->uni_srv_name), q_n->ptr_srv_name, ps, depth);
+
+ prs_align(ps);
+
+ prs_uint32("ptr_qual_name", ps, depth, &(q_n->ptr_qual_name));
+ smb_io_unistr2("", &(q_n->uni_qual_name), q_n->ptr_qual_name, ps, depth);
+
+ prs_align(ps);
+
+ prs_uint32("conn_level", ps, depth, &(q_n->conn_level ));
+
+ if (q_n->conn_level != -1)
+ {
+ srv_io_srv_conn_ctr("conn_ctr", q_n->ctr, ps, depth);
+ }
+
+ prs_uint32("preferred_len", ps, depth, &(q_n->preferred_len));
+
+ smb_io_enum_hnd("enum_hnd", &(q_n->enum_hnd), ps, depth);
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void srv_io_r_net_conn_enum(char *desc, SRV_R_NET_CONN_ENUM *r_n, prs_struct *ps, int depth)
+{
+ if (r_n == NULL) return;
+
+ prs_debug(ps, depth, desc, "srv_io_r_net_conn_enum");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("conn_level", ps, depth, &(r_n->conn_level));
+
+ if (r_n->conn_level != -1)
+ {
+ srv_io_srv_conn_ctr("conn_ctr", r_n->ctr, ps, depth);
+ }
+
+ prs_uint32("total_entries", ps, depth, &(r_n->total_entries));
+ smb_io_enum_hnd("enum_hnd", &(r_n->enum_hnd), ps, depth);
+ prs_uint32("status ", ps, depth, &(r_n->status));
+}
+
+/*******************************************************************
+ makes a FILE_INFO_3_STR structure
+********************************************************************/
+void make_srv_file_info3_str(FILE_INFO_3_STR *fi3, char *user_name, char *path_name)
+{
+ if (fi3 == NULL) return;
+
+ DEBUG(5,("make_srv_file_info3_str\n"));
+
+ make_unistr2(&(fi3->uni_path_name), path_name, strlen(path_name)+1);
+ make_unistr2(&(fi3->uni_user_name), user_name, strlen(user_name)+1);
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static void srv_io_file_info3_str(char *desc, FILE_INFO_3_STR *sh1, prs_struct *ps, int depth)
+{
+ if (sh1 == NULL) return;
+
+ prs_debug(ps, depth, desc, "srv_io_file_info3_str");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_unistr2("", &(sh1->uni_path_name), True, ps, depth);
+ smb_io_unistr2("", &(sh1->uni_user_name), True, ps, depth);
+}
+
+/*******************************************************************
+ makes a FILE_INFO_3 structure
+********************************************************************/
+void make_srv_file_info3(FILE_INFO_3 *fl3,
+ uint32 id, uint32 perms, uint32 num_locks,
+ char *path_name, char *user_name)
+{
+ if (fl3 == NULL) return;
+
+ DEBUG(5,("make_srv_file_info3: %s %s\n", path_name, user_name));
+
+ fl3->id = id;
+ fl3->perms = perms;
+ fl3->num_locks = num_locks;
+
+ fl3->ptr_path_name = path_name != NULL ? 1 : 0;
+ fl3->ptr_user_name = user_name != NULL ? 1 : 0;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static void srv_io_file_info3(char *desc, FILE_INFO_3 *fl3, prs_struct *ps, int depth)
+{
+ if (fl3 == NULL) return;
+
+ prs_debug(ps, depth, desc, "srv_io_file_info3");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("id ", ps, depth, &(fl3->id ));
+ prs_uint32("perms ", ps, depth, &(fl3->perms ));
+ prs_uint32("num_locks ", ps, depth, &(fl3->num_locks ));
+ prs_uint32("ptr_path_name", ps, depth, &(fl3->ptr_path_name));
+ prs_uint32("ptr_user_name", ps, depth, &(fl3->ptr_user_name));
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static void srv_io_srv_file_info_3(char *desc, SRV_FILE_INFO_3 *fl3, prs_struct *ps, int depth)
+{
+ if (fl3 == NULL) return;
+
+ prs_debug(ps, depth, desc, "srv_io_file_3_fl3");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("num_entries_read", ps, depth, &(fl3->num_entries_read));
+ prs_uint32("ptr_file_fl3", ps, depth, &(fl3->ptr_file_info));
+ if (fl3->ptr_file_info != 0)
+ {
+ int i;
+ int num_entries = fl3->num_entries_read;
+ if (num_entries > MAX_FILE_ENTRIES)
+ {
+ num_entries = MAX_FILE_ENTRIES; /* report this! */
+ }
+
+ prs_uint32("num_entries_read2", ps, depth, &(fl3->num_entries_read2));
+
+ for (i = 0; i < num_entries; i++)
+ {
+ prs_grow(ps);
+ srv_io_file_info3("", &(fl3->info_3[i]), ps, depth);
+ }
+
+ for (i = 0; i < num_entries; i++)
+ {
+ prs_grow(ps);
+ srv_io_file_info3_str("", &(fl3->info_3_str[i]), ps, depth);
+ }
+
+ prs_align(ps);
+ }
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static void srv_io_srv_file_ctr(char *desc, SRV_FILE_INFO_CTR *ctr, prs_struct *ps, int depth)
+{
+ if (ctr == NULL) return;
+
+ prs_debug(ps, depth, desc, "srv_io_srv_file_ctr");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("switch_value", ps, depth, &(ctr->switch_value));
+ prs_uint32("ptr_file_ctr", ps, depth, &(ctr->ptr_file_ctr));
+
+ if (ctr->ptr_file_ctr != 0)
+ {
+ switch (ctr->switch_value)
+ {
+ case 3:
+ {
+ srv_io_srv_file_info_3("", &(ctr->file.info3), ps, depth);
+ break;
+ }
+ default:
+ {
+ DEBUG(5,("%s no file info at switch_value %d\n",
+ tab_depth(depth), ctr->switch_value));
+ break;
+ }
+ }
+ }
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void make_srv_q_net_file_enum(SRV_Q_NET_FILE_ENUM *q_n,
+ char *srv_name, char *qual_name,
+ uint32 file_level, SRV_FILE_INFO_CTR *ctr,
+ uint32 preferred_len,
+ ENUM_HND *hnd)
+{
+ if (q_n == NULL || ctr == NULL || hnd == NULL) return;
+
+ q_n->ctr = ctr;
+
+ DEBUG(5,("make_q_net_file_enum\n"));
+
+ make_buf_unistr2(&(q_n->uni_srv_name), &(q_n->ptr_srv_name), srv_name);
+ make_buf_unistr2(&(q_n->uni_qual_name), &(q_n->ptr_qual_name), qual_name);
+
+ q_n->file_level = file_level;
+ q_n->preferred_len = preferred_len;
+
+ memcpy(&(q_n->enum_hnd), hnd, sizeof(*hnd));
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void srv_io_q_net_file_enum(char *desc, SRV_Q_NET_FILE_ENUM *q_n, prs_struct *ps, int depth)
+{
+ if (q_n == NULL) return;
+
+ prs_debug(ps, depth, desc, "srv_io_q_net_file_enum");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("ptr_srv_name", ps, depth, &(q_n->ptr_srv_name));
+ smb_io_unistr2("", &(q_n->uni_srv_name), True, ps, depth);
+
+ prs_align(ps);
+
+ prs_uint32("ptr_qual_name", ps, depth, &(q_n->ptr_qual_name));
+ smb_io_unistr2("", &(q_n->uni_qual_name), q_n->ptr_qual_name, ps, depth);
+
+ prs_align(ps);
+
+ prs_uint32("file_level", ps, depth, &(q_n->file_level ));
+
+ if (q_n->file_level != -1)
+ {
+ srv_io_srv_file_ctr("file_ctr", q_n->ctr, ps, depth);
+ }
+
+ prs_uint32("preferred_len", ps, depth, &(q_n->preferred_len));
+
+ smb_io_enum_hnd("enum_hnd", &(q_n->enum_hnd), ps, depth);
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void srv_io_r_net_file_enum(char *desc, SRV_R_NET_FILE_ENUM *r_n, prs_struct *ps, int depth)
+{
+ if (r_n == NULL) return;
+
+ prs_debug(ps, depth, desc, "srv_io_r_net_file_enum");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("file_level", ps, depth, &(r_n->file_level));
+
+ if (r_n->file_level != 0)
+ {
+ srv_io_srv_file_ctr("file_ctr", r_n->ctr, ps, depth);
+ }
+
+ prs_uint32("total_entries", ps, depth, &(r_n->total_entries));
+ smb_io_enum_hnd("enum_hnd", &(r_n->enum_hnd), ps, depth);
+ prs_uint32("status ", ps, depth, &(r_n->status));
+}
+
/*******************************************************************
makes a SRV_INFO_101 structure.
********************************************************************/
lsa_io_r_open_pol("", &r_o, rdata, 0);
}
+/***************************************************************************
+make_dom_query
+ ***************************************************************************/
+static void make_dom_query(DOM_QUERY *d_q, char *dom_name, DOM_SID *dom_sid)
+{
+ int domlen = strlen(dom_name);
+
+ d_q->uni_dom_max_len = domlen * 2;
+ d_q->uni_dom_str_len = domlen * 2;
+
+ d_q->buffer_dom_name = 4; /* domain buffer pointer */
+ d_q->buffer_dom_sid = 2; /* domain sid pointer */
+
+ /* this string is supposed to be character short */
+ make_unistr2(&(d_q->uni_domain_name), dom_name, domlen);
+
+ make_dom_sid2(&(d_q->dom_sid), dom_sid);
+}
+
/***************************************************************************
lsa_reply_query_info
***************************************************************************/
lsa_io_r_enum_trust_dom("", &r_e, rdata, 0);
}
-/***************************************************************************
-make_dom_query
- ***************************************************************************/
-static void make_dom_query(DOM_QUERY *d_q, char *dom_name, DOM_SID *dom_sid)
-{
- int domlen = strlen(dom_name);
-
- d_q->uni_dom_max_len = domlen * 2;
- d_q->uni_dom_str_len = domlen * 2;
-
- d_q->buffer_dom_name = 4; /* domain buffer pointer */
- d_q->buffer_dom_sid = 2; /* domain sid pointer */
-
- /* this string is supposed to be character short */
- make_unistr2(&(d_q->uni_domain_name), dom_name, domlen);
-
- make_dom_sid2(&(d_q->dom_sid), dom_sid);
-}
/***************************************************************************
lsa_reply_query_info
***************************************************************************/
}
+/***************************************************************************
+make_dom_ref
+ ***************************************************************************/
+static void make_dom_ref(DOM_R_REF *ref, int num_domains,
+ char **dom_names, DOM_SID **dom_sids)
+
+{
+ int i;
+
+ if (num_domains > MAX_REF_DOMAINS)
+ {
+ num_domains = MAX_REF_DOMAINS;
+ }
+
+ ref->undoc_buffer = 1;
+ ref->num_ref_doms_1 = num_domains;
+ ref->undoc_buffer2 = 1;
+ ref->max_entries = MAX_REF_DOMAINS;
+ ref->num_ref_doms_2 = num_domains;
+
+ for (i = 0; i < num_domains; i++)
+ {
+ int len = dom_names[i] != NULL ? strlen(dom_names[i]) : 0;
+
+ make_uni_hdr(&(ref->hdr_ref_dom[i].hdr_dom_name), len, len, len != 0 ? 1 : 0);
+ ref->hdr_ref_dom[i].ptr_dom_sid = dom_sids[i] != NULL ? 1 : 0;
+
+ make_unistr2 (&(ref->ref_dom[i].uni_dom_name), dom_names[i], len);
+ make_dom_sid2(&(ref->ref_dom[i].ref_dom ), dom_sids [i]);
+ }
+
+}
+
+/***************************************************************************
+make_reply_lookup_rids
+ ***************************************************************************/
+static void make_reply_lookup_rids(LSA_R_LOOKUP_RIDS *r_l,
+ int num_entries, uint32 dom_rids[MAX_LOOKUP_SIDS],
+ int num_ref_doms,
+ char **dom_names, DOM_SID **dom_sids)
+{
+ int i;
+
+ make_dom_ref(&(r_l->dom_ref), num_ref_doms, dom_names, dom_sids);
+
+ r_l->num_entries = num_entries;
+ r_l->undoc_buffer = 1;
+ r_l->num_entries2 = num_entries;
+
+ SMB_ASSERT_ARRAY(r_l->dom_rid, num_entries);
+
+ for (i = 0; i < num_entries; i++)
+ {
+ make_dom_rid2(&(r_l->dom_rid[i]), dom_rids[i], 0x01);
+ }
+
+ r_l->num_entries3 = num_entries;
+}
+
+/***************************************************************************
+make_lsa_trans_names
+ ***************************************************************************/
+static void make_lsa_trans_names(LSA_TRANS_NAME_ENUM *trn,
+ int num_entries, DOM_SID2 sid[MAX_LOOKUP_SIDS],
+ uint32 *total)
+{
+ uint32 status = 0x0;
+ int i;
+ (*total) = 0;
+
+ SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
+
+ for (i = 0; i < num_entries; i++)
+ {
+ uint32 rid = 0xffffffff;
+ uint8 num_auths = sid[i].sid.num_auths;
+ fstring name;
+ uint32 type;
+
+ SMB_ASSERT_ARRAY(sid[i].sid.sub_auths, num_auths);
+
+ /* find the rid to look up */
+ if (num_auths != 0)
+ {
+ rid = sid[i].sid.sub_auths[num_auths-1];
+
+ status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
+
+ status = (status != 0x0) ? lookup_user_name (rid, name, &type) : status;
+ status = (status != 0x0) ? lookup_group_name(rid, name, &type) : status;
+ status = (status != 0x0) ? lookup_alias_name(rid, name, &type) : status;
+ }
+
+ if (status == 0x0)
+ {
+ make_lsa_trans_name(&(trn->name [(*total)]),
+ &(trn->uni_name[(*total)]),
+ type, name, (*total));
+ (*total)++;
+ }
+ }
+
+ trn->num_entries = (*total);
+ trn->ptr_trans_names = 1;
+ trn->num_entries2 = (*total);
+}
+
+/***************************************************************************
+make_reply_lookup_sids
+ ***************************************************************************/
+static void make_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l,
+ DOM_R_REF *ref, LSA_TRANS_NAME_ENUM *names,
+ uint32 mapped_count, uint32 status)
+{
+ r_l->dom_ref = ref;
+ r_l->names = names;
+ r_l->mapped_count = mapped_count;
+ r_l->status = status;
+}
+
+/***************************************************************************
+lsa_reply_lookup_sids
+ ***************************************************************************/
+static void lsa_reply_lookup_sids(prs_struct *rdata,
+ int num_entries, DOM_SID2 sid[MAX_LOOKUP_SIDS],
+ int num_ref_doms,
+ char **dom_names, DOM_SID **dom_sids)
+{
+ LSA_R_LOOKUP_SIDS r_l;
+ DOM_R_REF ref;
+ LSA_TRANS_NAME_ENUM names;
+ uint32 mapped_count = 0;
+
+ ZERO_STRUCT(r_l);
+ ZERO_STRUCT(ref);
+ ZERO_STRUCT(names);
+
+ /* set up the LSA Lookup SIDs response */
+ make_dom_ref(&ref, num_ref_doms, dom_names, dom_sids);
+ make_lsa_trans_names(&names, num_entries, sid, &mapped_count);
+ make_reply_lookup_sids(&r_l, &ref, &names, mapped_count, 0x0);
+
+ /* store the response in the SMB stream */
+ lsa_io_r_lookup_sids("", &r_l, rdata, 0);
+}
+
+/***************************************************************************
+lsa_reply_lookup_rids
+ ***************************************************************************/
+static void lsa_reply_lookup_rids(prs_struct *rdata,
+ int num_entries, uint32 dom_rids[MAX_LOOKUP_SIDS],
+ int num_ref_doms,
+ char **dom_names, DOM_SID **dom_sids)
+{
+ LSA_R_LOOKUP_RIDS r_l;
+
+ ZERO_STRUCT(r_l);
+
+ /* set up the LSA Lookup RIDs response */
+ make_reply_lookup_rids(&r_l, num_entries, dom_rids,
+ num_ref_doms, dom_names, dom_sids);
+ r_l.status = 0x0;
+
+ /* store the response in the SMB stream */
+ lsa_io_r_lookup_rids("", &r_l, rdata, 0);
+}
+
/***************************************************************************
api_lsa_open_policy
***************************************************************************/
lsa_reply_query_info(&q_i, rdata, dom_name, &global_sam_sid);
}
+/***************************************************************************
+api_lsa_lookup_sids
+ ***************************************************************************/
+static void api_lsa_lookup_sids( uint16 vuid, prs_struct *data,
+ prs_struct *rdata )
+{
+ LSA_Q_LOOKUP_SIDS q_l;
+ pstring dom_name;
+ DOM_SID sid_S_1_1;
+ DOM_SID sid_S_1_3;
+ DOM_SID sid_S_1_5;
+
+ DOM_SID *sid_array[4];
+ char *dom_names[4];
+
+ ZERO_STRUCT(q_l);
+ ZERO_STRUCT(sid_S_1_1);
+ ZERO_STRUCT(sid_S_1_3);
+ ZERO_STRUCT(sid_S_1_5);
+
+ /* grab the info class and policy handle */
+ lsa_io_q_lookup_sids("", &q_l, data, 0);
+
+ pstrcpy(dom_name, lp_workgroup());
+
+ string_to_sid(&sid_S_1_1, "S-1-1");
+ string_to_sid(&sid_S_1_3, "S-1-3");
+ string_to_sid(&sid_S_1_5, "S-1-5");
+
+ dom_names[0] = dom_name;
+ sid_array[0] = &global_sam_sid;
+
+ dom_names[1] = "Everyone";
+ sid_array[1] = &sid_S_1_1;
+
+ dom_names[2] = "don't know";
+ sid_array[2] = &sid_S_1_3;
+
+ dom_names[3] = "NT AUTHORITY";
+ sid_array[3] = &sid_S_1_5;
+
+ /* construct reply. return status is always 0x0 */
+ lsa_reply_lookup_sids(rdata,
+ q_l.sids.num_entries, q_l.sids.sid, /* SIDs */
+ 4, dom_names, sid_array);
+}
+
+/***************************************************************************
+api_lsa_lookup_names
+ ***************************************************************************/
+static void api_lsa_lookup_names( uint16 vuid, prs_struct *data,
+ prs_struct *rdata )
+{
+ int i;
+ LSA_Q_LOOKUP_RIDS q_l;
+ pstring dom_name;
+ uint32 dom_rids[MAX_LOOKUP_SIDS];
+ uint32 dummy_g_rid;
+
+ DOM_SID sid_S_1_1;
+ DOM_SID sid_S_1_3;
+ DOM_SID sid_S_1_5;
+
+ DOM_SID *sid_array[4];
+ char *dom_names[4];
+
+ ZERO_STRUCT(q_l);
+ ZERO_STRUCT(sid_S_1_1);
+ ZERO_STRUCT(sid_S_1_3);
+ ZERO_STRUCT(sid_S_1_5);
+ ZERO_ARRAY(dom_rids);
+
+ /* grab the info class and policy handle */
+ lsa_io_q_lookup_rids("", &q_l, data, 0);
+
+ pstrcpy(dom_name, lp_workgroup());
+
+ string_to_sid(&sid_S_1_1, "S-1-1");
+ string_to_sid(&sid_S_1_3, "S-1-3");
+ string_to_sid(&sid_S_1_5, "S-1-5");
+
+ dom_names[0] = dom_name;
+ sid_array[0] = &global_sam_sid;
+
+ dom_names[1] = "Everyone";
+ sid_array[1] = &sid_S_1_1;
+
+ dom_names[2] = "don't know";
+ sid_array[2] = &sid_S_1_3;
+
+ dom_names[3] = "NT AUTHORITY";
+ sid_array[3] = &sid_S_1_5;
+
+ SMB_ASSERT_ARRAY(q_l.lookup_name, q_l.num_entries);
+
+ /* convert received RIDs to strings, so we can do them. */
+ for (i = 0; i < q_l.num_entries; i++)
+ {
+ fstring user_name;
+ fstrcpy(user_name, unistr2(q_l.lookup_name[i].str.buffer));
+
+ /*
+ * Map to the UNIX username.
+ */
+ map_username(user_name);
+
+ /*
+ * Do any case conversions.
+ */
+ (void)Get_Pwnam(user_name, True);
+
+ if (!pdb_name_to_rid(user_name, &dom_rids[i], &dummy_g_rid))
+ {
+ /* WHOOPS! we should really do something about this... */
+ dom_rids[i] = 0;
+ }
+ }
+
+ /* construct reply. return status is always 0x0 */
+ lsa_reply_lookup_rids(rdata,
+ q_l.num_entries, dom_rids, /* text-converted SIDs */
+ 4, dom_names, sid_array);
+}
+
/***************************************************************************
api_lsa_close
***************************************************************************/
{ "LSA_ENUMTRUSTDOM" , LSA_ENUMTRUSTDOM , api_lsa_enum_trust_dom },
{ "LSA_CLOSE" , LSA_CLOSE , api_lsa_close },
{ "LSA_OPENSECRET" , LSA_OPENSECRET , api_lsa_open_secret },
+ { "LSA_LOOKUPSIDS" , LSA_LOOKUPSIDS , api_lsa_lookup_sids },
+ { "LSA_LOOKUPNAMES" , LSA_LOOKUPNAMES , api_lsa_lookup_names },
{ NULL , 0 , NULL }
};
static struct api_cmd api_fd_commands[] =
{
{ "lsarpc", "lsass", api_ntlsa_rpc },
+ { "samr", "lsass", api_samr_rpc },
{ "srvsvc", "ntsvcs", api_srvsvc_rpc },
+ { "wkssvc", "ntsvcs", api_wkssvc_rpc },
{ "NETLOGON", "lsass", api_netlog_rpc },
+ { "winreg", "winreg", api_reg_rpc },
{ NULL, NULL, NULL }
};
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* removed in SAMBA_2_0 branch. */
+
+#include "includes.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+
+
+/*******************************************************************
+ reg_reply_unknown_1
+ ********************************************************************/
+static void reg_reply_close(REG_Q_CLOSE *q_r,
+ prs_struct *rdata)
+{
+ REG_R_CLOSE r_u;
+
+ /* set up the REG unknown_1 response */
+ memset((char *)r_u.pol.data, '\0', POL_HND_SIZE);
+
+ /* close the policy handle */
+ if (close_lsa_policy_hnd(&(q_r->pol)))
+ {
+ r_u.status = 0;
+ }
+ else
+ {
+ r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_INVALID;
+ }
+
+ DEBUG(5,("reg_unknown_1: %d\n", __LINE__));
+
+ /* store the response in the SMB stream */
+ reg_io_r_close("", &r_u, rdata, 0);
+
+ DEBUG(5,("reg_unknown_1: %d\n", __LINE__));
+}
+
+/*******************************************************************
+ api_reg_close
+ ********************************************************************/
+static void api_reg_close( uint16 vuid, prs_struct *data,
+ prs_struct *rdata )
+{
+ REG_Q_CLOSE q_r;
+
+ /* grab the reg unknown 1 */
+ reg_io_q_close("", &q_r, data, 0);
+
+ /* construct reply. always indicate success */
+ reg_reply_close(&q_r, rdata);
+}
+
+
+/*******************************************************************
+ reg_reply_open
+ ********************************************************************/
+static void reg_reply_open(REG_Q_OPEN_HKLM *q_r,
+ prs_struct *rdata)
+{
+ REG_R_OPEN_HKLM r_u;
+
+ r_u.status = 0x0;
+ /* get a (unique) handle. open a policy on it. */
+ if (r_u.status == 0x0 && !open_lsa_policy_hnd(&(r_u.pol)))
+ {
+ r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+
+ DEBUG(5,("reg_open: %d\n", __LINE__));
+
+ /* store the response in the SMB stream */
+ reg_io_r_open_hklm("", &r_u, rdata, 0);
+
+ DEBUG(5,("reg_open: %d\n", __LINE__));
+}
+
+/*******************************************************************
+ api_reg_open
+ ********************************************************************/
+static void api_reg_open( uint16 vuid, prs_struct *data,
+ prs_struct *rdata )
+{
+ REG_Q_OPEN_HKLM q_u;
+
+ /* grab the reg open */
+ reg_io_q_open_hklm("", &q_u, data, 0);
+
+ /* construct reply. always indicate success */
+ reg_reply_open(&q_u, rdata);
+}
+
+
+/*******************************************************************
+ reg_reply_open_entry
+ ********************************************************************/
+static void reg_reply_open_entry(REG_Q_OPEN_ENTRY *q_u,
+ prs_struct *rdata)
+{
+ uint32 status = 0;
+ POLICY_HND pol;
+ REG_R_OPEN_ENTRY r_u;
+ fstring name;
+
+ DEBUG(5,("reg_open_entry: %d\n", __LINE__));
+
+ if (status == 0 && find_lsa_policy_by_hnd(&(q_u->pol)) == -1)
+ {
+ status = 0xC000000 | NT_STATUS_INVALID_HANDLE;
+ }
+
+ if (status == 0x0 && !open_lsa_policy_hnd(&pol))
+ {
+ status = 0xC000000 | NT_STATUS_TOO_MANY_SECRETS; /* ha ha very droll */
+ }
+
+ fstrcpy(name, unistrn2(q_u->uni_name.buffer, q_u->uni_name.uni_str_len));
+
+ if (status == 0x0)
+ {
+ DEBUG(5,("reg_open_entry: %s\n", name));
+ /* lkcl XXXX do a check on the name, here */
+ }
+
+ if (status == 0x0 && !set_lsa_policy_reg_name(&pol, name))
+ {
+ status = 0xC000000 | NT_STATUS_TOO_MANY_SECRETS; /* ha ha very droll */
+ }
+
+ make_reg_r_open_entry(&r_u, &pol, status);
+
+ /* store the response in the SMB stream */
+ reg_io_r_open_entry("", &r_u, rdata, 0);
+
+ DEBUG(5,("reg_open_entry: %d\n", __LINE__));
+}
+
+/*******************************************************************
+ api_reg_open_entry
+ ********************************************************************/
+static void api_reg_open_entry( uint16 vuid, prs_struct *data,
+ prs_struct *rdata )
+{
+ REG_Q_OPEN_ENTRY q_u;
+
+ /* grab the reg open entry */
+ reg_io_q_open_entry("", &q_u, data, 0);
+
+ /* construct reply. */
+ reg_reply_open_entry(&q_u, rdata);
+}
+
+
+/*******************************************************************
+ reg_reply_info
+ ********************************************************************/
+static void reg_reply_info(REG_Q_INFO *q_u,
+ prs_struct *rdata)
+{
+ uint32 status = 0;
+
+ REG_R_INFO r_u;
+
+ DEBUG(5,("reg_info: %d\n", __LINE__));
+
+ if (status == 0 && find_lsa_policy_by_hnd(&(q_u->pol)) == -1)
+ {
+ status = 0xC000000 | NT_STATUS_INVALID_HANDLE;
+ }
+
+ if (status == 0)
+ {
+ }
+
+ make_reg_r_info(&r_u, 1, "LanmanNT", 0x12, 0x12, status);
+
+ /* store the response in the SMB stream */
+ reg_io_r_info("", &r_u, rdata, 0);
+
+ DEBUG(5,("reg_open_entry: %d\n", __LINE__));
+}
+
+/*******************************************************************
+ api_reg_info
+ ********************************************************************/
+static void api_reg_info( uint16 vuid, prs_struct *data,
+ prs_struct *rdata )
+{
+ REG_Q_INFO q_u;
+
+ /* grab the reg unknown 0x11*/
+ reg_io_q_info("", &q_u, data, 0);
+
+ /* construct reply. always indicate success */
+ reg_reply_info(&q_u, rdata);
+}
+
+
+/*******************************************************************
+ array of \PIPE\reg operations
+ ********************************************************************/
+static struct api_struct api_reg_cmds[] =
+{
+ { "REG_CLOSE" , REG_CLOSE , api_reg_close },
+ { "REG_OPEN_ENTRY" , REG_OPEN_ENTRY , api_reg_open_entry },
+ { "REG_OPEN" , REG_OPEN_HKLM , api_reg_open },
+ { "REG_INFO" , REG_INFO , api_reg_info },
+ { NULL, 0 , NULL }
+};
+
+/*******************************************************************
+ receives a reg pipe and responds.
+ ********************************************************************/
+BOOL api_reg_rpc(pipes_struct *p, prs_struct *data)
+{
+ return api_rpcTNP(p, "api_reg_rpc", api_reg_cmds, data);
+}
+
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* removed in SAMBA_2_0 branch */
+
+#include "includes.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+
+extern fstring global_myworkgroup;
+extern pstring global_myname;
+extern DOM_SID global_sam_sid;
+
+extern rid_name domain_group_rids[];
+extern rid_name domain_alias_rids[];
+extern rid_name builtin_alias_rids[];
+
+/*******************************************************************
+ This next function should be replaced with something that
+ dynamically returns the correct user info..... JRA.
+ ********************************************************************/
+
+static BOOL get_sampwd_entries(SAM_USER_INFO_21 *pw_buf,
+ int start_idx,
+ int *total_entries, int *num_entries,
+ int max_num_entries,
+ uint16 acb_mask)
+{
+ void *vp = NULL;
+ struct sam_passwd *pwd = NULL;
+
+ (*num_entries) = 0;
+ (*total_entries) = 0;
+
+ if (pw_buf == NULL) return False;
+
+ vp = startsmbpwent(False);
+ if (!vp)
+ {
+ DEBUG(0, ("get_sampwd_entries: Unable to open SMB password database.\n"));
+ return False;
+ }
+
+ while (((pwd = getsam21pwent(vp)) != NULL) && (*num_entries) < max_num_entries)
+ {
+ int user_name_len;
+
+ if (start_idx > 0)
+ {
+ /* skip the requested number of entries.
+ not very efficient, but hey...
+ */
+ start_idx--;
+ continue;
+ }
+
+ user_name_len = strlen(pwd->smb_name);
+ make_unistr2(&(pw_buf[(*num_entries)].uni_user_name), pwd->smb_name, user_name_len);
+ make_uni_hdr(&(pw_buf[(*num_entries)].hdr_user_name), user_name_len,
+ user_name_len, 1);
+ pw_buf[(*num_entries)].user_rid = pwd->user_rid;
+ memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
+
+ /* Now check if the NT compatible password is available. */
+ if (pwd->smb_nt_passwd != NULL)
+ {
+ memcpy( pw_buf[(*num_entries)].nt_pwd , pwd->smb_nt_passwd, 16);
+ }
+
+ pw_buf[(*num_entries)].acb_info = (uint16)pwd->acct_ctrl;
+
+ DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x",
+ (*num_entries), pwd->smb_name,
+ pwd->user_rid, pwd->acct_ctrl));
+
+ if (acb_mask == 0 || IS_BITS_SET_SOME(pwd->acct_ctrl, acb_mask))
+ {
+ DEBUG(5,(" acb_mask %x accepts\n", acb_mask));
+ (*num_entries)++;
+ }
+ else
+ {
+ DEBUG(5,(" acb_mask %x rejects\n", acb_mask));
+ }
+
+ (*total_entries)++;
+ }
+
+ endsmbpwent(vp);
+
+ return (*num_entries) > 0;
+}
+
+/*******************************************************************
+ samr_reply_unknown_1
+ ********************************************************************/
+static void samr_reply_close_hnd(SAMR_Q_CLOSE_HND *q_u,
+ prs_struct *rdata)
+{
+ SAMR_R_CLOSE_HND r_u;
+
+ /* set up the SAMR unknown_1 response */
+ memset((char *)r_u.pol.data, '\0', POL_HND_SIZE);
+
+ /* close the policy handle */
+ if (close_lsa_policy_hnd(&(q_u->pol)))
+ {
+ r_u.status = 0;
+ }
+ else
+ {
+ r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_INVALID;
+ }
+
+ DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
+
+ /* store the response in the SMB stream */
+ samr_io_r_close_hnd("", &r_u, rdata, 0);
+
+ DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
+
+}
+
+/*******************************************************************
+ api_samr_close_hnd
+ ********************************************************************/
+static void api_samr_close_hnd( uint16 vuid, prs_struct *data, prs_struct *rdata)
+{
+ SAMR_Q_CLOSE_HND q_u;
+
+ /* grab the samr unknown 1 */
+ samr_io_q_close_hnd("", &q_u, data, 0);
+
+ /* construct reply. always indicate success */
+ samr_reply_close_hnd(&q_u, rdata);
+}
+
+
+/*******************************************************************
+ samr_reply_open_domain
+ ********************************************************************/
+static void samr_reply_open_domain(SAMR_Q_OPEN_DOMAIN *q_u,
+ prs_struct *rdata)
+{
+ SAMR_R_OPEN_DOMAIN r_u;
+ BOOL pol_open = False;
+
+ r_u.status = 0x0;
+
+ /* find the connection policy handle. */
+ if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->connect_pol)) == -1))
+ {
+ r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+ }
+
+ /* get a (unique) handle. open a policy on it. */
+ if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.domain_pol))))
+ {
+ r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+
+ /* associate the domain SID with the (unique) handle. */
+ if (r_u.status == 0x0 && !set_lsa_policy_samr_sid(&(r_u.domain_pol), &(q_u->dom_sid.sid)))
+ {
+ /* oh, whoops. don't know what error message to return, here */
+ r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+
+ if (r_u.status != 0 && pol_open)
+ {
+ close_lsa_policy_hnd(&(r_u.domain_pol));
+ }
+
+ DEBUG(5,("samr_open_domain: %d\n", __LINE__));
+
+ /* store the response in the SMB stream */
+ samr_io_r_open_domain("", &r_u, rdata, 0);
+
+ DEBUG(5,("samr_open_domain: %d\n", __LINE__));
+
+}
+
+/*******************************************************************
+ api_samr_open_domain
+ ********************************************************************/
+static void api_samr_open_domain( uint16 vuid, prs_struct *data, prs_struct *rdata)
+{
+ SAMR_Q_OPEN_DOMAIN q_u;
+
+ /* grab the samr open */
+ samr_io_q_open_domain("", &q_u, data, 0);
+
+ /* construct reply. always indicate success */
+ samr_reply_open_domain(&q_u, rdata);
+}
+
+
+/*******************************************************************
+ samr_reply_unknown_2c
+ ********************************************************************/
+static void samr_reply_unknown_2c(SAMR_Q_UNKNOWN_2C *q_u,
+ prs_struct *rdata)
+{
+ SAMR_R_UNKNOWN_2C r_u;
+ uint32 status = 0x0;
+
+ /* find the policy handle. open a policy on it. */
+ if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->user_pol)) == -1))
+ {
+ status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+ }
+
+ /* find the user's rid */
+ if ((status == 0x0) && (get_lsa_policy_samr_rid(&(q_u->user_pol)) == 0xffffffff))
+ {
+ status = NT_STATUS_OBJECT_TYPE_MISMATCH;
+ }
+
+ make_samr_r_unknown_2c(&r_u, status);
+
+ DEBUG(5,("samr_unknown_2c: %d\n", __LINE__));
+
+ /* store the response in the SMB stream */
+ samr_io_r_unknown_2c("", &r_u, rdata, 0);
+
+ DEBUG(5,("samr_unknown_2c: %d\n", __LINE__));
+
+}
+
+/*******************************************************************
+ api_samr_unknown_2c
+ ********************************************************************/
+static void api_samr_unknown_2c( uint16 vuid, prs_struct *data, prs_struct *rdata)
+{
+ SAMR_Q_UNKNOWN_2C q_u;
+
+ /* grab the samr open */
+ samr_io_q_unknown_2c("", &q_u, data, 0);
+
+ /* construct reply. always indicate success */
+ samr_reply_unknown_2c(&q_u, rdata);
+}
+
+
+/*******************************************************************
+ samr_reply_unknown_3
+ ********************************************************************/
+static void samr_reply_unknown_3(SAMR_Q_UNKNOWN_3 *q_u,
+ prs_struct *rdata)
+{
+ SAMR_R_UNKNOWN_3 r_u;
+ DOM_SID3 sid[MAX_SAM_SIDS];
+ uint32 rid;
+ uint32 status;
+
+ status = 0x0;
+
+ /* find the policy handle. open a policy on it. */
+ if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->user_pol)) == -1))
+ {
+ status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+ }
+
+ /* find the user's rid */
+ if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->user_pol))) == 0xffffffff)
+ {
+ status = NT_STATUS_OBJECT_TYPE_MISMATCH;
+ }
+
+ if (status == 0x0)
+ {
+ DOM_SID user_sid;
+ DOM_SID everyone_sid;
+
+ user_sid = global_sam_sid;
+
+ SMB_ASSERT_ARRAY(user_sid.sub_auths, user_sid.num_auths+1);
+
+ /*
+ * Add the user RID.
+ */
+ user_sid.sub_auths[user_sid.num_auths++] = rid;
+
+ string_to_sid(&everyone_sid, "S-1-1");
+
+ /* maybe need another 1 or 2 (S-1-5-0x20-0x220 and S-1-5-20-0x224) */
+ /* these two are DOMAIN_ADMIN and DOMAIN_ACCT_OP group RIDs */
+ make_dom_sid3(&(sid[0]), 0x035b, 0x0002, &everyone_sid);
+ make_dom_sid3(&(sid[1]), 0x0044, 0x0002, &user_sid);
+ }
+
+ make_samr_r_unknown_3(&r_u,
+ 0x0001, 0x8004,
+ 0x00000014, 0x0002, 0x0070,
+ 2, sid, status);
+
+ DEBUG(5,("samr_unknown_3: %d\n", __LINE__));
+
+ /* store the response in the SMB stream */
+ samr_io_r_unknown_3("", &r_u, rdata, 0);
+
+ DEBUG(5,("samr_unknown_3: %d\n", __LINE__));
+
+}
+
+/*******************************************************************
+ api_samr_unknown_3
+ ********************************************************************/
+static void api_samr_unknown_3( uint16 vuid, prs_struct *data, prs_struct *rdata)
+{
+ SAMR_Q_UNKNOWN_3 q_u;
+
+ /* grab the samr open */
+ samr_io_q_unknown_3("", &q_u, data, 0);
+
+ /* construct reply. always indicate success */
+ samr_reply_unknown_3(&q_u, rdata);
+}
+
+
+/*******************************************************************
+ samr_reply_enum_dom_users
+ ********************************************************************/
+static void samr_reply_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_u,
+ prs_struct *rdata)
+{
+ SAMR_R_ENUM_DOM_USERS r_e;
+ SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
+ int num_entries;
+ int total_entries;
+
+ r_e.status = 0x0;
+ r_e.total_num_entries = 0;
+
+ /* find the policy handle. open a policy on it. */
+ if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
+ {
+ r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+ }
+
+ DEBUG(5,("samr_reply_enum_dom_users: %d\n", __LINE__));
+
+ become_root(True);
+ get_sampwd_entries(pass, 0, &total_entries, &num_entries, MAX_SAM_ENTRIES, q_u->acb_mask);
+ unbecome_root(True);
+
+ make_samr_r_enum_dom_users(&r_e, total_entries,
+ q_u->unknown_0, num_entries,
+ pass, r_e.status);
+
+ /* store the response in the SMB stream */
+ samr_io_r_enum_dom_users("", &r_e, rdata, 0);
+
+ DEBUG(5,("samr_enum_dom_users: %d\n", __LINE__));
+
+}
+
+/*******************************************************************
+ api_samr_enum_dom_users
+ ********************************************************************/
+static void api_samr_enum_dom_users( uint16 vuid, prs_struct *data, prs_struct *rdata)
+{
+ SAMR_Q_ENUM_DOM_USERS q_e;
+
+ /* grab the samr open */
+ samr_io_q_enum_dom_users("", &q_e, data, 0);
+
+ /* construct reply. */
+ samr_reply_enum_dom_users(&q_e, rdata);
+}
+
+
+/*******************************************************************
+ samr_reply_enum_dom_groups
+ ********************************************************************/
+static void samr_reply_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_u,
+ prs_struct *rdata)
+{
+ SAMR_R_ENUM_DOM_GROUPS r_e;
+ SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
+ int num_entries;
+ BOOL got_grps;
+ char *dummy_group = "Domain Admins";
+
+ r_e.status = 0x0;
+ r_e.num_entries = 0;
+
+ /* find the policy handle. open a policy on it. */
+ if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
+ {
+ r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+ }
+
+ DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
+
+ got_grps = True;
+ num_entries = 1;
+ make_unistr2(&(pass[0].uni_user_name), dummy_group, strlen(dummy_group));
+ pass[0].user_rid = DOMAIN_GROUP_RID_ADMINS;
+
+ if (r_e.status == 0 && got_grps)
+ {
+ make_samr_r_enum_dom_groups(&r_e, q_u->start_idx, num_entries, pass, r_e.status);
+ }
+
+ /* store the response in the SMB stream */
+ samr_io_r_enum_dom_groups("", &r_e, rdata, 0);
+
+ DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
+
+}
+
+/*******************************************************************
+ api_samr_enum_dom_groups
+ ********************************************************************/
+static void api_samr_enum_dom_groups( uint16 vuid, prs_struct *data, prs_struct *rdata)
+{
+ SAMR_Q_ENUM_DOM_GROUPS q_e;
+
+ /* grab the samr open */
+ samr_io_q_enum_dom_groups("", &q_e, data, 0);
+
+ /* construct reply. */
+ samr_reply_enum_dom_groups(&q_e, rdata);
+}
+
+
+/*******************************************************************
+ samr_reply_enum_dom_aliases
+ ********************************************************************/
+static void samr_reply_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES *q_u,
+ prs_struct *rdata)
+{
+ SAMR_R_ENUM_DOM_ALIASES r_e;
+ SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
+ int num_entries = 0;
+ DOM_SID sid;
+ fstring sid_str;
+ fstring sam_sid_str;
+
+ r_e.status = 0x0;
+ r_e.num_entries = 0;
+
+ /* find the policy handle. open a policy on it. */
+ if (r_e.status == 0x0 && !get_lsa_policy_samr_sid(&q_u->pol, &sid))
+ {
+ r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+ }
+
+ sid_to_string(sid_str, &sid);
+ sid_to_string(sam_sid_str, &global_sam_sid);
+
+ DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
+
+ /* well-known aliases */
+ if (strequal(sid_str, "S-1-5-32"))
+ {
+ char *name;
+ while (num_entries < MAX_SAM_ENTRIES && ((name = builtin_alias_rids[num_entries].name) != NULL))
+ {
+ make_unistr2(&(pass[num_entries].uni_user_name), name, strlen(name));
+ pass[num_entries].user_rid = builtin_alias_rids[num_entries].rid;
+ num_entries++;
+ }
+ }
+ else if (strequal(sid_str, sam_sid_str))
+ {
+ /* local aliases */
+ /* oops! there's no code to deal with this */
+ DEBUG(3,("samr_reply_enum_dom_aliases: enum of aliases in our domain not supported yet\n"));
+ num_entries = 0;
+ }
+
+ make_samr_r_enum_dom_aliases(&r_e, num_entries, pass, r_e.status);
+
+ /* store the response in the SMB stream */
+ samr_io_r_enum_dom_aliases("", &r_e, rdata, 0);
+
+ DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
+
+}
+
+/*******************************************************************
+ api_samr_enum_dom_aliases
+ ********************************************************************/
+static void api_samr_enum_dom_aliases( uint16 vuid, prs_struct *data, prs_struct *rdata)
+{
+ SAMR_Q_ENUM_DOM_ALIASES q_e;
+
+ /* grab the samr open */
+ samr_io_q_enum_dom_aliases("", &q_e, data, 0);
+
+ /* construct reply. */
+ samr_reply_enum_dom_aliases(&q_e, rdata);
+}
+
+
+/*******************************************************************
+ samr_reply_query_dispinfo
+ ********************************************************************/
+static void samr_reply_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_u,
+ prs_struct *rdata)
+{
+ SAMR_R_QUERY_DISPINFO r_e;
+ SAM_INFO_CTR ctr;
+ SAM_INFO_1 info1;
+ SAM_INFO_2 info2;
+ SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
+ int num_entries = 0;
+ int total_entries = 0;
+ BOOL got_pwds;
+ uint16 switch_level = 0x0;
+
+ ZERO_STRUCT(r_e);
+
+ r_e.status = 0x0;
+
+ DEBUG(5,("samr_reply_query_dispinfo: %d\n", __LINE__));
+
+ /* find the policy handle. open a policy on it. */
+ if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
+ {
+ r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+ DEBUG(5,("samr_reply_query_dispinfo: invalid handle\n"));
+ }
+
+ if (r_e.status == 0x0)
+ {
+ become_root(True);
+ got_pwds = get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries, MAX_SAM_ENTRIES, 0);
+ unbecome_root(True);
+
+ switch (q_u->switch_level)
+ {
+ case 0x1:
+ {
+
+ /* query disp info is for users */
+ switch_level = 0x1;
+ make_sam_info_1(&info1, ACB_NORMAL,
+ q_u->start_idx, num_entries, pass);
+
+ ctr.sam.info1 = &info1;
+
+ break;
+ }
+ case 0x2:
+ {
+ /* query disp info is for servers */
+ switch_level = 0x2;
+ make_sam_info_2(&info2, ACB_WSTRUST,
+ q_u->start_idx, num_entries, pass);
+
+ ctr.sam.info2 = &info2;
+
+ break;
+ }
+ }
+ }
+
+ if (r_e.status == 0 && got_pwds)
+ {
+ make_samr_r_query_dispinfo(&r_e, switch_level, &ctr, r_e.status);
+ }
+
+ /* store the response in the SMB stream */
+ samr_io_r_query_dispinfo("", &r_e, rdata, 0);
+
+ DEBUG(5,("samr_query_dispinfo: %d\n", __LINE__));
+
+}
+
+/*******************************************************************
+ api_samr_query_dispinfo
+ ********************************************************************/
+static void api_samr_query_dispinfo( uint16 vuid, prs_struct *data, prs_struct *rdata)
+{
+ SAMR_Q_QUERY_DISPINFO q_e;
+
+ /* grab the samr open */
+ samr_io_q_query_dispinfo("", &q_e, data, 0);
+
+ /* construct reply. */
+ samr_reply_query_dispinfo(&q_e, rdata);
+}
+
+
+/*******************************************************************
+ samr_reply_query_aliasinfo
+ ********************************************************************/
+static void samr_reply_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_u,
+ prs_struct *rdata)
+{
+ SAMR_R_QUERY_ALIASINFO r_e;
+
+ r_e.status = 0x0;
+ r_e.ptr = 0;
+
+ /* find the policy handle. open a policy on it. */
+ if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
+ {
+ r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+ }
+
+ DEBUG(5,("samr_reply_query_aliasinfo: %d\n", __LINE__));
+
+ if (r_e.status == 0x0)
+ {
+ if (q_u->switch_level != 3)
+ {
+ r_e.status = NT_STATUS_INVALID_INFO_CLASS;
+ }
+ }
+
+ make_samr_r_query_aliasinfo(&r_e, q_u->switch_level,
+ "<account description>",
+ r_e.status);
+
+ /* store the response in the SMB stream */
+ samr_io_r_query_aliasinfo("", &r_e, rdata, 0);
+
+ DEBUG(5,("samr_query_aliasinfo: %d\n", __LINE__));
+
+}
+
+/*******************************************************************
+ api_samr_query_aliasinfo
+ ********************************************************************/
+static void api_samr_query_aliasinfo( uint16 vuid, prs_struct *data, prs_struct *rdata)
+{
+ SAMR_Q_QUERY_ALIASINFO q_e;
+
+ /* grab the samr open */
+ samr_io_q_query_aliasinfo("", &q_e, data, 0);
+
+ /* construct reply. */
+ samr_reply_query_aliasinfo(&q_e, rdata);
+}
+
+
+/*******************************************************************
+ samr_reply_lookup_ids
+ ********************************************************************/
+static void samr_reply_lookup_ids(SAMR_Q_LOOKUP_IDS *q_u,
+ prs_struct *rdata)
+{
+ uint32 rid[MAX_SAM_ENTRIES];
+ uint32 status = 0;
+ int num_rids = q_u->num_sids1;
+
+ SAMR_R_LOOKUP_IDS r_u;
+
+ DEBUG(5,("samr_lookup_ids: %d\n", __LINE__));
+
+ if (num_rids > MAX_SAM_ENTRIES)
+ {
+ num_rids = MAX_SAM_ENTRIES;
+ DEBUG(5,("samr_lookup_ids: truncating entries to %d\n", num_rids));
+ }
+
+#if 0
+ int i;
+ SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
+
+ for (i = 0; i < num_rids && status == 0; i++)
+ {
+ struct sam_passwd *sam_pass;
+ fstring user_name;
+
+
+ fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
+ q_u->uni_user_name[i].uni_str_len));
+
+ /* find the user account */
+ become_root(True);
+ sam_pass = get_smb21pwd_entry(user_name, 0);
+ unbecome_root(True);
+
+ if (sam_pass == NULL)
+ {
+ status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
+ rid[i] = 0;
+ }
+ else
+ {
+ rid[i] = sam_pass->user_rid;
+ }
+ }
+#endif
+
+ num_rids = 1;
+ rid[0] = BUILTIN_ALIAS_RID_USERS;
+
+ make_samr_r_lookup_ids(&r_u, num_rids, rid, status);
+
+ /* store the response in the SMB stream */
+ samr_io_r_lookup_ids("", &r_u, rdata, 0);
+
+ DEBUG(5,("samr_lookup_ids: %d\n", __LINE__));
+
+}
+
+/*******************************************************************
+ api_samr_lookup_ids
+ ********************************************************************/
+static void api_samr_lookup_ids( uint16 vuid, prs_struct *data, prs_struct *rdata)
+{
+ SAMR_Q_LOOKUP_IDS q_u;
+
+ /* grab the samr 0x10 */
+ samr_io_q_lookup_ids("", &q_u, data, 0);
+
+ /* construct reply. always indicate success */
+ samr_reply_lookup_ids(&q_u, rdata);
+}
+
+/*******************************************************************
+ samr_reply_lookup_names
+ ********************************************************************/
+static void samr_reply_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u,
+ prs_struct *rdata)
+{
+ uint32 rid[MAX_SAM_ENTRIES];
+ uint32 status = 0;
+ int i;
+ int num_rids = q_u->num_rids1;
+
+ SAMR_R_LOOKUP_NAMES r_u;
+
+ DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
+
+ if (num_rids > MAX_SAM_ENTRIES)
+ {
+ num_rids = MAX_SAM_ENTRIES;
+ DEBUG(5,("samr_lookup_names: truncating entries to %d\n", num_rids));
+ }
+
+ SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
+
+ for (i = 0; i < num_rids && status == 0; i++)
+ {
+ fstring name;
+
+ status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
+
+ fstrcpy(name, unistrn2(q_u->uni_user_name[i].buffer, q_u->uni_user_name[i].uni_str_len));
+
+ status = (status != 0x0) ? lookup_user_rid (name, &(rid[i])) : status;
+ status = (status != 0x0) ? lookup_group_rid(name, &(rid[i])) : status;
+ status = (status != 0x0) ? lookup_alias_rid(name, &(rid[i])) : status;
+ }
+
+ make_samr_r_lookup_names(&r_u, num_rids, rid, status);
+
+ /* store the response in the SMB stream */
+ samr_io_r_lookup_names("", &r_u, rdata, 0);
+
+ DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
+
+}
+
+/*******************************************************************
+ api_samr_lookup_names
+ ********************************************************************/
+static void api_samr_lookup_names( uint16 vuid, prs_struct *data, prs_struct *rdata)
+{
+ SAMR_Q_LOOKUP_NAMES q_u;
+
+ /* grab the samr lookup names */
+ samr_io_q_lookup_names("", &q_u, data, 0);
+
+ /* construct reply. always indicate success */
+ samr_reply_lookup_names(&q_u, rdata);
+}
+
+/*******************************************************************
+ samr_reply_chgpasswd_user
+ ********************************************************************/
+static void samr_reply_chgpasswd_user(SAMR_Q_CHGPASSWD_USER *q_u,
+ prs_struct *rdata)
+{
+ SAMR_R_CHGPASSWD_USER r_u;
+ uint32 status = 0x0;
+ fstring user_name;
+ fstring wks;
+
+ fstrcpy(user_name, unistrn2(q_u->uni_user_name.buffer, q_u->uni_user_name.uni_str_len));
+ fstrcpy(wks , unistrn2(q_u->uni_dest_host.buffer, q_u->uni_dest_host.uni_str_len));
+
+ DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
+
+ if (!pass_oem_change(user_name,
+ q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
+ q_u->nt_newpass.pass, q_u->nt_oldhash.hash))
+ {
+ status = 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
+ }
+
+ make_samr_r_chgpasswd_user(&r_u, status);
+
+ /* store the response in the SMB stream */
+ samr_io_r_chgpasswd_user("", &r_u, rdata, 0);
+
+ DEBUG(5,("samr_chgpasswd_user: %d\n", __LINE__));
+}
+
+/*******************************************************************
+ api_samr_chgpasswd_user
+ ********************************************************************/
+static void api_samr_chgpasswd_user( uint16 vuid, prs_struct *data, prs_struct *rdata)
+{
+ SAMR_Q_CHGPASSWD_USER q_u;
+
+ /* unknown 38 command */
+ samr_io_q_chgpasswd_user("", &q_u, data, 0);
+
+ /* construct reply. */
+ samr_reply_chgpasswd_user(&q_u, rdata);
+}
+
+
+/*******************************************************************
+ samr_reply_unknown_38
+ ********************************************************************/
+static void samr_reply_unknown_38(SAMR_Q_UNKNOWN_38 *q_u,
+ prs_struct *rdata)
+{
+ SAMR_R_UNKNOWN_38 r_u;
+
+ DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
+
+ make_samr_r_unknown_38(&r_u);
+
+ /* store the response in the SMB stream */
+ samr_io_r_unknown_38("", &r_u, rdata, 0);
+
+ DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
+}
+
+/*******************************************************************
+ api_samr_unknown_38
+ ********************************************************************/
+static void api_samr_unknown_38( uint16 vuid, prs_struct *data, prs_struct *rdata)
+{
+ SAMR_Q_UNKNOWN_38 q_u;
+
+ /* unknown 38 command */
+ samr_io_q_unknown_38("", &q_u, data, 0);
+
+ /* construct reply. always indicate success */
+ samr_reply_unknown_38(&q_u, rdata);
+}
+
+
+/*******************************************************************
+ samr_reply_unknown_12
+ ********************************************************************/
+static void samr_reply_unknown_12(SAMR_Q_UNKNOWN_12 *q_u,
+ prs_struct *rdata)
+{
+ fstring group_names[MAX_SAM_ENTRIES];
+ uint32 group_attrs[MAX_SAM_ENTRIES];
+ uint32 status = 0;
+ int num_gids = q_u->num_gids1;
+
+ SAMR_R_UNKNOWN_12 r_u;
+
+ DEBUG(5,("samr_unknown_12: %d\n", __LINE__));
+
+ /* find the policy handle. open a policy on it. */
+ if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
+ {
+ status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+ }
+
+ if (status == 0x0)
+ {
+ int i;
+ if (num_gids > MAX_SAM_ENTRIES)
+ {
+ num_gids = MAX_SAM_ENTRIES;
+ DEBUG(5,("samr_unknown_12: truncating entries to %d\n", num_gids));
+ }
+
+ for (i = 0; i < num_gids && status == 0; i++)
+ {
+ fstrcpy(group_names[i], "dummy group");
+ group_attrs[i] = 0x2;
+ }
+ }
+
+ make_samr_r_unknown_12(&r_u, num_gids, group_names, group_attrs, status);
+
+ /* store the response in the SMB stream */
+ samr_io_r_unknown_12("", &r_u, rdata, 0);
+
+ DEBUG(5,("samr_unknown_12: %d\n", __LINE__));
+
+}
+
+/*******************************************************************
+ api_samr_unknown_12
+ ********************************************************************/
+static void api_samr_unknown_12( uint16 vuid, prs_struct *data, prs_struct *rdata)
+{
+ SAMR_Q_UNKNOWN_12 q_u;
+
+ /* grab the samr lookup names */
+ samr_io_q_unknown_12("", &q_u, data, 0);
+
+ /* construct reply. always indicate success */
+ samr_reply_unknown_12(&q_u, rdata);
+}
+
+
+/*******************************************************************
+ samr_reply_open_user
+ ********************************************************************/
+static void samr_reply_open_user(SAMR_Q_OPEN_USER *q_u,
+ prs_struct *rdata,
+ int status)
+{
+ SAMR_R_OPEN_USER r_u;
+ struct sam_passwd *sam_pass;
+ BOOL pol_open = False;
+
+ /* set up the SAMR open_user response */
+ memset((char *)r_u.user_pol.data, '\0', POL_HND_SIZE);
+
+ r_u.status = 0x0;
+
+ /* find the policy handle. open a policy on it. */
+ if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->domain_pol)) == -1))
+ {
+ r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+ }
+
+ /* get a (unique) handle. open a policy on it. */
+ if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.user_pol))))
+ {
+ r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+
+ become_root(True);
+ sam_pass = getsam21pwrid(q_u->user_rid);
+ unbecome_root(True);
+
+ /* check that the RID exists in our domain. */
+ if (r_u.status == 0x0 && sam_pass == NULL)
+ {
+ r_u.status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
+ }
+
+ /* associate the RID with the (unique) handle. */
+ if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.user_pol), q_u->user_rid))
+ {
+ /* oh, whoops. don't know what error message to return, here */
+ r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+
+ if (r_u.status != 0 && pol_open)
+ {
+ close_lsa_policy_hnd(&(r_u.user_pol));
+ }
+
+ DEBUG(5,("samr_open_user: %d\n", __LINE__));
+
+ /* store the response in the SMB stream */
+ samr_io_r_open_user("", &r_u, rdata, 0);
+
+ DEBUG(5,("samr_open_user: %d\n", __LINE__));
+
+}
+
+/*******************************************************************
+ api_samr_open_user
+ ********************************************************************/
+static void api_samr_open_user( uint16 vuid, prs_struct *data, prs_struct *rdata)
+{
+ SAMR_Q_OPEN_USER q_u;
+
+ /* grab the samr unknown 22 */
+ samr_io_q_open_user("", &q_u, data, 0);
+
+ /* construct reply. always indicate success */
+ samr_reply_open_user(&q_u, rdata, 0x0);
+}
+
+
+/*************************************************************************
+ get_user_info_10
+ *************************************************************************/
+static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
+{
+ struct smb_passwd *smb_pass;
+
+ if (!pdb_rid_is_user(user_rid))
+ {
+ DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
+ return False;
+ }
+
+ become_root(True);
+ smb_pass = getsmbpwrid(user_rid);
+ unbecome_root(True);
+
+ if (smb_pass == NULL)
+ {
+ DEBUG(4,("User 0x%x not found\n", user_rid));
+ return False;
+ }
+
+ DEBUG(3,("User:[%s]\n", smb_pass->smb_name));
+
+ make_sam_user_info10(id10, smb_pass->acct_ctrl);
+
+ return True;
+}
+
+/*************************************************************************
+ get_user_info_21
+ *************************************************************************/
+static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
+{
+ NTTIME dummy_time;
+ struct sam_passwd *sam_pass;
+ LOGON_HRS hrs;
+ int i;
+
+ if (!pdb_rid_is_user(user_rid))
+ {
+ DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
+ return False;
+ }
+
+ become_root(True);
+ sam_pass = getsam21pwrid(user_rid);
+ unbecome_root(True);
+
+ if (sam_pass == NULL)
+ {
+ DEBUG(4,("User 0x%x not found\n", user_rid));
+ return False;
+ }
+
+ DEBUG(3,("User:[%s]\n", sam_pass->smb_name));
+
+ dummy_time.low = 0xffffffff;
+ dummy_time.high = 0x7fffffff;
+
+ DEBUG(0,("get_user_info_21 - TODO: convert unix times to NTTIMEs\n"));
+
+ /* create a LOGON_HRS structure */
+ hrs.len = sam_pass->hours_len;
+ SMB_ASSERT_ARRAY(hrs.hours, hrs.len);
+ for (i = 0; i < hrs.len; i++)
+ {
+ hrs.hours[i] = sam_pass->hours[i];
+ }
+
+ make_sam_user_info21(id21,
+
+ &dummy_time, /* logon_time */
+ &dummy_time, /* logoff_time */
+ &dummy_time, /* kickoff_time */
+ &dummy_time, /* pass_last_set_time */
+ &dummy_time, /* pass_can_change_time */
+ &dummy_time, /* pass_must_change_time */
+
+ sam_pass->smb_name, /* user_name */
+ sam_pass->full_name, /* full_name */
+ sam_pass->home_dir, /* home_dir */
+ sam_pass->dir_drive, /* dir_drive */
+ sam_pass->logon_script, /* logon_script */
+ sam_pass->profile_path, /* profile_path */
+ sam_pass->acct_desc, /* description */
+ sam_pass->workstations, /* workstations user can log in from */
+ sam_pass->unknown_str, /* don't know, yet */
+ sam_pass->munged_dial, /* dialin info. contains dialin path and tel no */
+
+ sam_pass->user_rid, /* RID user_id */
+ sam_pass->group_rid, /* RID group_id */
+ sam_pass->acct_ctrl,
+
+ sam_pass->unknown_3, /* unknown_3 */
+ sam_pass->logon_divs, /* divisions per week */
+ &hrs, /* logon hours */
+ sam_pass->unknown_5,
+ sam_pass->unknown_6);
+
+ return True;
+}
+
+/*******************************************************************
+ samr_reply_query_userinfo
+ ********************************************************************/
+static void samr_reply_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
+ prs_struct *rdata)
+{
+ SAMR_R_QUERY_USERINFO r_u;
+#if 0
+ SAM_USER_INFO_11 id11;
+#endif
+ SAM_USER_INFO_10 id10;
+ SAM_USER_INFO_21 id21;
+ void *info = NULL;
+
+ uint32 status = 0x0;
+ uint32 rid = 0x0;
+
+ DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
+
+ /* search for the handle */
+ if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
+ {
+ status = NT_STATUS_INVALID_HANDLE;
+ }
+
+ /* find the user's rid */
+ if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
+ {
+ status = NT_STATUS_OBJECT_TYPE_MISMATCH;
+ }
+
+ DEBUG(5,("samr_reply_query_userinfo: rid:0x%x\n", rid));
+
+ /* ok! user info levels (there are lots: see MSDEV help), off we go... */
+ if (status == 0x0)
+ {
+ switch (q_u->switch_value)
+ {
+ case 0x10:
+ {
+ info = (void*)&id10;
+ status = get_user_info_10(&id10, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
+ break;
+ }
+#if 0
+/* whoops - got this wrong. i think. or don't understand what's happening. */
+ case 0x11:
+ {
+ NTTIME expire;
+ info = (void*)&id11;
+
+ expire.low = 0xffffffff;
+ expire.high = 0x7fffffff;
+
+ make_sam_user_info11(&id11, &expire, "BROOKFIELDS$", 0x03ef, 0x201, 0x0080);
+
+ break;
+ }
+#endif
+ case 21:
+ {
+ info = (void*)&id21;
+ status = get_user_info_21(&id21, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
+ break;
+ }
+
+ default:
+ {
+ status = NT_STATUS_INVALID_INFO_CLASS;
+
+ break;
+ }
+ }
+ }
+
+ make_samr_r_query_userinfo(&r_u, q_u->switch_value, info, status);
+
+ /* store the response in the SMB stream */
+ samr_io_r_query_userinfo("", &r_u, rdata, 0);
+
+ DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
+
+}
+
+/*******************************************************************
+ api_samr_query_userinfo
+ ********************************************************************/
+static void api_samr_query_userinfo( uint16 vuid, prs_struct *data, prs_struct *rdata)
+{
+ SAMR_Q_QUERY_USERINFO q_u;
+
+ /* grab the samr unknown 24 */
+ samr_io_q_query_userinfo("", &q_u, data, 0);
+
+ /* construct reply. always indicate success */
+ samr_reply_query_userinfo(&q_u, rdata);
+}
+
+
+/*******************************************************************
+ samr_reply_query_usergroups
+ ********************************************************************/
+static void samr_reply_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
+ prs_struct *rdata)
+{
+ SAMR_R_QUERY_USERGROUPS r_u;
+ uint32 status = 0x0;
+
+ struct sam_passwd *sam_pass;
+ DOM_GID *gids = NULL;
+ int num_groups = 0;
+ uint32 rid;
+
+ DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
+
+ /* find the policy handle. open a policy on it. */
+ if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
+ {
+ status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+ }
+
+ /* find the user's rid */
+ if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
+ {
+ status = NT_STATUS_OBJECT_TYPE_MISMATCH;
+ }
+
+ if (status == 0x0)
+ {
+ become_root(True);
+ sam_pass = getsam21pwrid(rid);
+ unbecome_root(True);
+
+ if (sam_pass == NULL)
+ {
+ status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
+ }
+ }
+
+ if (status == 0x0)
+ {
+ pstring groups;
+ get_domain_user_groups(groups, sam_pass->smb_name);
+ gids = NULL;
+ num_groups = make_dom_gids(groups, &gids);
+ }
+
+ /* construct the response. lkclXXXX: gids are not copied! */
+ make_samr_r_query_usergroups(&r_u, num_groups, gids, status);
+
+ /* store the response in the SMB stream */
+ samr_io_r_query_usergroups("", &r_u, rdata, 0);
+
+ if (gids)
+ {
+ free((char *)gids);
+ }
+
+ DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
+
+}
+
+/*******************************************************************
+ api_samr_query_usergroups
+ ********************************************************************/
+static void api_samr_query_usergroups( uint16 vuid, prs_struct *data, prs_struct *rdata)
+{
+ SAMR_Q_QUERY_USERGROUPS q_u;
+ /* grab the samr unknown 32 */
+ samr_io_q_query_usergroups("", &q_u, data, 0);
+
+ /* construct reply. */
+ samr_reply_query_usergroups(&q_u, rdata);
+}
+
+
+/*******************************************************************
+ samr_reply_query_dom_info
+ ********************************************************************/
+static void samr_reply_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u,
+ prs_struct *rdata)
+{
+ SAMR_R_QUERY_DOMAIN_INFO r_u;
+ SAM_UNK_CTR ctr;
+ uint16 switch_value = 0x0;
+ uint32 status = 0x0;
+
+ ZERO_STRUCT(r_u);
+ ZERO_STRUCT(ctr);
+
+ r_u.ctr = &ctr;
+
+ DEBUG(5,("samr_reply_query_dom_info: %d\n", __LINE__));
+
+ /* find the policy handle. open a policy on it. */
+ if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->domain_pol)) == -1))
+ {
+ r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+ DEBUG(5,("samr_reply_query_dom_info: invalid handle\n"));
+ }
+
+ if (status == 0x0)
+ {
+ switch (q_u->switch_value)
+ {
+ case 0x02:
+ {
+ switch_value = 0x2;
+ make_unk_info2(&ctr.info.inf2, global_myworkgroup, global_myname);
+
+ break;
+ }
+ default:
+ {
+ status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
+ break;
+ }
+ }
+ }
+
+ make_samr_r_query_dom_info(&r_u, switch_value, &ctr, status);
+
+ /* store the response in the SMB stream */
+ samr_io_r_query_dom_info("", &r_u, rdata, 0);
+
+ DEBUG(5,("samr_query_dom_info: %d\n", __LINE__));
+
+}
+
+/*******************************************************************
+ api_samr_query_dom_info
+ ********************************************************************/
+static void api_samr_query_dom_info( uint16 vuid, prs_struct *data, prs_struct *rdata)
+{
+ SAMR_Q_QUERY_DOMAIN_INFO q_e;
+
+ /* grab the samr unknown 8 command */
+ samr_io_q_query_dom_info("", &q_e, data, 0);
+
+ /* construct reply. */
+ samr_reply_query_dom_info(&q_e, rdata);
+}
+
+
+
+/*******************************************************************
+ samr_reply_unknown_32
+ ********************************************************************/
+static void samr_reply_unknown_32(SAMR_Q_UNKNOWN_32 *q_u,
+ prs_struct *rdata,
+ int status)
+{
+ int i;
+ SAMR_R_UNKNOWN_32 r_u;
+
+ /* set up the SAMR unknown_32 response */
+ memset((char *)r_u.pol.data, '\0', POL_HND_SIZE);
+ if (status == 0)
+ {
+ for (i = 4; i < POL_HND_SIZE; i++)
+ {
+ r_u.pol.data[i] = i+1;
+ }
+ }
+
+ make_dom_rid4(&(r_u.rid4), 0x0030, 0, 0);
+ r_u.status = status;
+
+ DEBUG(5,("samr_unknown_32: %d\n", __LINE__));
+
+ /* store the response in the SMB stream */
+ samr_io_r_unknown_32("", &r_u, rdata, 0);
+
+ DEBUG(5,("samr_unknown_32: %d\n", __LINE__));
+
+}
+
+/*******************************************************************
+ api_samr_unknown_32
+ ********************************************************************/
+static void api_samr_unknown_32( uint16 vuid, prs_struct *data, prs_struct *rdata)
+{
+ uint32 status = 0;
+ struct sam_passwd *sam_pass;
+ fstring mach_acct;
+
+ SAMR_Q_UNKNOWN_32 q_u;
+
+ /* grab the samr unknown 32 */
+ samr_io_q_unknown_32("", &q_u, data, 0);
+
+ /* find the machine account: tell the caller if it exists.
+ lkclXXXX i have *no* idea if this is a problem or not
+ or even if you are supposed to construct a different
+ reply if the account already exists...
+ */
+
+ fstrcpy(mach_acct, unistrn2(q_u.uni_mach_acct.buffer,
+ q_u.uni_mach_acct.uni_str_len));
+
+ become_root(True);
+ sam_pass = getsam21pwnam(mach_acct);
+ unbecome_root(True);
+
+ if (sam_pass != NULL)
+ {
+ /* machine account exists: say so */
+ status = 0xC0000000 | NT_STATUS_USER_EXISTS;
+ }
+ else
+ {
+ /* this could cause trouble... */
+ DEBUG(0,("trouble!\n"));
+ status = 0;
+ }
+
+ /* construct reply. */
+ samr_reply_unknown_32(&q_u, rdata, status);
+}
+
+
+/*******************************************************************
+ samr_reply_connect_anon
+ ********************************************************************/
+static void samr_reply_connect_anon(SAMR_Q_CONNECT_ANON *q_u,
+ prs_struct *rdata)
+{
+ SAMR_R_CONNECT_ANON r_u;
+ BOOL pol_open = False;
+
+ /* set up the SAMR connect_anon response */
+
+ r_u.status = 0x0;
+ /* get a (unique) handle. open a policy on it. */
+ if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
+ {
+ r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+
+ /* associate the domain SID with the (unique) handle. */
+ if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
+ {
+ /* oh, whoops. don't know what error message to return, here */
+ r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+
+ if (r_u.status != 0 && pol_open)
+ {
+ close_lsa_policy_hnd(&(r_u.connect_pol));
+ }
+
+ DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
+
+ /* store the response in the SMB stream */
+ samr_io_r_connect_anon("", &r_u, rdata, 0);
+
+ DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
+
+}
+
+/*******************************************************************
+ api_samr_connect_anon
+ ********************************************************************/
+static void api_samr_connect_anon( uint16 vuid, prs_struct *data, prs_struct *rdata)
+{
+ SAMR_Q_CONNECT_ANON q_u;
+
+ /* grab the samr open policy */
+ samr_io_q_connect_anon("", &q_u, data, 0);
+
+ /* construct reply. always indicate success */
+ samr_reply_connect_anon(&q_u, rdata);
+}
+
+/*******************************************************************
+ samr_reply_connect
+ ********************************************************************/
+static void samr_reply_connect(SAMR_Q_CONNECT *q_u,
+ prs_struct *rdata)
+{
+ SAMR_R_CONNECT r_u;
+ BOOL pol_open = False;
+
+ /* set up the SAMR connect response */
+
+ r_u.status = 0x0;
+ /* get a (unique) handle. open a policy on it. */
+ if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
+ {
+ r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+
+ /* associate the domain SID with the (unique) handle. */
+ if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
+ {
+ /* oh, whoops. don't know what error message to return, here */
+ r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+
+ if (r_u.status != 0 && pol_open)
+ {
+ close_lsa_policy_hnd(&(r_u.connect_pol));
+ }
+
+ DEBUG(5,("samr_connect: %d\n", __LINE__));
+
+ /* store the response in the SMB stream */
+ samr_io_r_connect("", &r_u, rdata, 0);
+
+ DEBUG(5,("samr_connect: %d\n", __LINE__));
+
+}
+
+/*******************************************************************
+ api_samr_connect
+ ********************************************************************/
+static void api_samr_connect( uint16 vuid, prs_struct *data, prs_struct *rdata)
+{
+ SAMR_Q_CONNECT q_u;
+
+ /* grab the samr open policy */
+ samr_io_q_connect("", &q_u, data, 0);
+
+ /* construct reply. always indicate success */
+ samr_reply_connect(&q_u, rdata);
+}
+
+/*******************************************************************
+ samr_reply_open_alias
+ ********************************************************************/
+static void samr_reply_open_alias(SAMR_Q_OPEN_ALIAS *q_u,
+ prs_struct *rdata)
+{
+ SAMR_R_OPEN_ALIAS r_u;
+ BOOL pol_open = False;
+
+ /* set up the SAMR open_alias response */
+
+ r_u.status = 0x0;
+ /* get a (unique) handle. open a policy on it. */
+ if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.pol))))
+ {
+ r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+
+ /* associate a RID with the (unique) handle. */
+ if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.pol), q_u->rid_alias))
+ {
+ /* oh, whoops. don't know what error message to return, here */
+ r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+
+ if (r_u.status != 0 && pol_open)
+ {
+ close_lsa_policy_hnd(&(r_u.pol));
+ }
+
+ DEBUG(5,("samr_open_alias: %d\n", __LINE__));
+
+ /* store the response in the SMB stream */
+ samr_io_r_open_alias("", &r_u, rdata, 0);
+
+ DEBUG(5,("samr_open_alias: %d\n", __LINE__));
+
+}
+
+/*******************************************************************
+ api_samr_open_alias
+ ********************************************************************/
+static void api_samr_open_alias( uint16 vuid, prs_struct *data, prs_struct *rdata)
+
+{
+ SAMR_Q_OPEN_ALIAS q_u;
+
+ /* grab the samr open policy */
+ samr_io_q_open_alias("", &q_u, data, 0);
+
+ /* construct reply. always indicate success */
+ samr_reply_open_alias(&q_u, rdata);
+}
+
+/*******************************************************************
+ array of \PIPE\samr operations
+ ********************************************************************/
+static struct api_struct api_samr_cmds [] =
+{
+ { "SAMR_CLOSE_HND" , SAMR_CLOSE_HND , api_samr_close_hnd },
+ { "SAMR_CONNECT" , SAMR_CONNECT , api_samr_connect },
+ { "SAMR_CONNECT_ANON" , SAMR_CONNECT_ANON , api_samr_connect_anon },
+ { "SAMR_ENUM_DOM_USERS" , SAMR_ENUM_DOM_USERS , api_samr_enum_dom_users },
+ { "SAMR_ENUM_DOM_GROUPS" , SAMR_ENUM_DOM_GROUPS , api_samr_enum_dom_groups },
+ { "SAMR_ENUM_DOM_ALIASES" , SAMR_ENUM_DOM_ALIASES , api_samr_enum_dom_aliases },
+ { "SAMR_LOOKUP_IDS" , SAMR_LOOKUP_IDS , api_samr_lookup_ids },
+ { "SAMR_LOOKUP_NAMES" , SAMR_LOOKUP_NAMES , api_samr_lookup_names },
+ { "SAMR_OPEN_USER" , SAMR_OPEN_USER , api_samr_open_user },
+ { "SAMR_QUERY_USERINFO" , SAMR_QUERY_USERINFO , api_samr_query_userinfo },
+ { "SAMR_QUERY_DOMAIN_INFO", SAMR_QUERY_DOMAIN_INFO, api_samr_query_dom_info },
+ { "SAMR_QUERY_USERGROUPS" , SAMR_QUERY_USERGROUPS , api_samr_query_usergroups },
+ { "SAMR_QUERY_DISPINFO" , SAMR_QUERY_DISPINFO , api_samr_query_dispinfo },
+ { "SAMR_QUERY_ALIASINFO" , SAMR_QUERY_ALIASINFO , api_samr_query_aliasinfo },
+ { "SAMR_0x32" , 0x32 , api_samr_unknown_32 },
+ { "SAMR_UNKNOWN_12" , SAMR_UNKNOWN_12 , api_samr_unknown_12 },
+ { "SAMR_UNKNOWN_38" , SAMR_UNKNOWN_38 , api_samr_unknown_38 },
+ { "SAMR_CHGPASSWD_USER" , SAMR_CHGPASSWD_USER , api_samr_chgpasswd_user },
+ { "SAMR_OPEN_ALIAS" , SAMR_OPEN_ALIAS , api_samr_open_alias },
+ { "SAMR_OPEN_DOMAIN" , SAMR_OPEN_DOMAIN , api_samr_open_domain },
+ { "SAMR_UNKNOWN_3" , SAMR_UNKNOWN_3 , api_samr_unknown_3 },
+ { "SAMR_UNKNOWN_2C" , SAMR_UNKNOWN_2C , api_samr_unknown_2c },
+ { NULL , 0 , NULL }
+};
+
+/*******************************************************************
+ receives a samr pipe and responds.
+ ********************************************************************/
+BOOL api_samr_rpc(pipes_struct *p, prs_struct *data)
+{
+ return api_rpcTNP(p, "api_samr_rpc", api_samr_cmds, data);
+}
+
DEBUG(5,("srv_net_share_enum: %d\n", __LINE__));
}
+/*******************************************************************
+ fill in a sess info level 1 structure.
+
+ this function breaks the rule that i'd like to be in place, namely
+ it doesn't receive its data as arguments: it has to call lp_xxxx()
+ functions itself. yuck.
+
+ ********************************************************************/
+static void make_srv_sess_0_info(SESS_INFO_0 *se0, SESS_INFO_0_STR *str0,
+ char *name)
+{
+ make_srv_sess_info0 (se0 , name);
+ make_srv_sess_info0_str(str0, name);
+}
+
+/*******************************************************************
+ fill in a sess info level 0 structure.
+
+ this function breaks the rule that i'd like to be in place, namely
+ it doesn't receive its data as arguments: it has to call lp_xxxx()
+ functions itself. yuck.
+
+ ********************************************************************/
+static void make_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *stot)
+{
+ uint32 num_entries = 0;
+ (*stot) = 1;
+
+ if (ss0 == NULL)
+ {
+ (*snum) = 0;
+ return;
+ }
+
+ DEBUG(5,("make_srv_sess_0_ss0\n"));
+
+ if (snum)
+ {
+ for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++)
+ {
+ make_srv_sess_0_info(&(ss0->info_0 [num_entries]),
+ &(ss0->info_0_str[num_entries]), "MACHINE");
+
+ /* move on to creating next session */
+ /* move on to creating next sess */
+ num_entries++;
+ }
+
+ ss0->num_entries_read = num_entries;
+ ss0->ptr_sess_info = num_entries > 0 ? 1 : 0;
+ ss0->num_entries_read2 = num_entries;
+
+ if ((*snum) >= (*stot))
+ {
+ (*snum) = 0;
+ }
+ }
+ else
+ {
+ ss0->num_entries_read = 0;
+ ss0->ptr_sess_info = 0;
+ ss0->num_entries_read2 = 0;
+ }
+}
+
+/*******************************************************************
+ fill in a sess info level 1 structure.
+
+ this function breaks the rule that i'd like to be in place, namely
+ it doesn't receive its data as arguments: it has to call lp_xxxx()
+ functions itself. yuck.
+
+ ********************************************************************/
+static void make_srv_sess_1_info(SESS_INFO_1 *se1, SESS_INFO_1_STR *str1,
+ char *name, char *user,
+ uint32 num_opens,
+ uint32 open_time, uint32 idle_time,
+ uint32 usr_flgs)
+{
+ make_srv_sess_info1 (se1 , name, user, num_opens, open_time, idle_time, usr_flgs);
+ make_srv_sess_info1_str(str1, name, user);
+}
+
+/*******************************************************************
+ fill in a sess info level 1 structure.
+
+ this function breaks the rule that i'd like to be in place, namely
+ it doesn't receive its data as arguments: it has to call lp_xxxx()
+ functions itself. yuck.
+
+ ********************************************************************/
+static void make_srv_sess_info_1(SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *stot)
+{
+ uint32 num_entries = 0;
+ (*stot) = 1;
+
+ if (ss1 == NULL)
+ {
+ (*snum) = 0;
+ return;
+ }
+
+ DEBUG(5,("make_srv_sess_1_ss1\n"));
+
+ if (snum)
+ {
+ for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++)
+ {
+ make_srv_sess_1_info(&(ss1->info_1 [num_entries]),
+ &(ss1->info_1_str[num_entries]),
+ "MACHINE", "dummy_user", 1, 10, 5, 0);
+
+ /* move on to creating next session */
+ /* move on to creating next sess */
+ num_entries++;
+ }
+
+ ss1->num_entries_read = num_entries;
+ ss1->ptr_sess_info = num_entries > 0 ? 1 : 0;
+ ss1->num_entries_read2 = num_entries;
+
+ if ((*snum) >= (*stot))
+ {
+ (*snum) = 0;
+ }
+ }
+ else
+ {
+ ss1->num_entries_read = 0;
+ ss1->ptr_sess_info = 0;
+ ss1->num_entries_read2 = 0;
+
+ (*stot) = 0;
+ }
+}
+
+/*******************************************************************
+ makes a SRV_R_NET_SESS_ENUM structure.
+********************************************************************/
+static uint32 make_srv_sess_info_ctr(SRV_SESS_INFO_CTR *ctr,
+ int switch_value, uint32 *resume_hnd, uint32 *total_entries)
+{
+ uint32 status = 0x0;
+ DEBUG(5,("make_srv_sess_info_ctr: %d\n", __LINE__));
+
+ ctr->switch_value = switch_value;
+
+ switch (switch_value)
+ {
+ case 0:
+ {
+ make_srv_sess_info_0(&(ctr->sess.info0), resume_hnd, total_entries);
+ ctr->ptr_sess_ctr = 1;
+ break;
+ }
+ case 1:
+ {
+ make_srv_sess_info_1(&(ctr->sess.info1), resume_hnd, total_entries);
+ ctr->ptr_sess_ctr = 1;
+ break;
+ }
+ default:
+ {
+ DEBUG(5,("make_srv_sess_info_ctr: unsupported switch value %d\n",
+ switch_value));
+ (*resume_hnd) = 0;
+ (*total_entries) = 0;
+ ctr->ptr_sess_ctr = 0;
+ status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
+ break;
+ }
+ }
+
+ return status;
+}
+
+/*******************************************************************
+ makes a SRV_R_NET_SESS_ENUM structure.
+********************************************************************/
+static void make_srv_r_net_sess_enum(SRV_R_NET_SESS_ENUM *r_n,
+ uint32 resume_hnd, int sess_level, int switch_value)
+{
+ DEBUG(5,("make_srv_r_net_sess_enum: %d\n", __LINE__));
+
+ r_n->sess_level = sess_level;
+ if (sess_level == -1)
+ {
+ r_n->status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
+ }
+ else
+ {
+ r_n->status = make_srv_sess_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
+ }
+ if (r_n->status != 0x0)
+ {
+ resume_hnd = 0;
+ }
+ make_enum_hnd(&(r_n->enum_hnd), resume_hnd);
+}
+
+/*******************************************************************
+net sess enum
+********************************************************************/
+static void srv_reply_net_sess_enum(SRV_Q_NET_SESS_ENUM *q_n,
+ prs_struct *rdata)
+{
+ SRV_R_NET_SESS_ENUM r_n;
+ SRV_SESS_INFO_CTR ctr;
+
+ r_n.ctr = &ctr;
+
+ DEBUG(5,("srv_net_sess_enum: %d\n", __LINE__));
+
+ /* set up the */
+ make_srv_r_net_sess_enum(&r_n,
+ get_enum_hnd(&q_n->enum_hnd),
+ q_n->sess_level,
+ q_n->ctr->switch_value);
+
+ /* store the response in the SMB stream */
+ srv_io_r_net_sess_enum("", &r_n, rdata, 0);
+
+ DEBUG(5,("srv_net_sess_enum: %d\n", __LINE__));
+}
+
+/*******************************************************************
+ fill in a conn info level 0 structure.
+
+ this function breaks the rule that i'd like to be in place, namely
+ it doesn't receive its data as arguments: it has to call lp_xxxx()
+ functions itself. yuck.
+
+ ********************************************************************/
+static void make_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *stot)
+{
+ uint32 num_entries = 0;
+ (*stot) = 1;
+
+ if (ss0 == NULL)
+ {
+ (*snum) = 0;
+ return;
+ }
+
+ DEBUG(5,("make_srv_conn_0_ss0\n"));
+
+ if (snum)
+ {
+ for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++)
+ {
+ make_srv_conn_info0(&(ss0->info_0 [num_entries]), (*stot));
+
+ /* move on to creating next connection */
+ /* move on to creating next conn */
+ num_entries++;
+ }
+
+ ss0->num_entries_read = num_entries;
+ ss0->ptr_conn_info = num_entries > 0 ? 1 : 0;
+ ss0->num_entries_read2 = num_entries;
+
+
+
+ if ((*snum) >= (*stot))
+ {
+ (*snum) = 0;
+ }
+ }
+ else
+ {
+ ss0->num_entries_read = 0;
+ ss0->ptr_conn_info = 0;
+ ss0->num_entries_read2 = 0;
+
+ (*stot) = 0;
+ }
+}
+
+/*******************************************************************
+ fill in a conn info level 1 structure.
+
+ this function breaks the rule that i'd like to be in place, namely
+ it doesn't receive its data as arguments: it has to call lp_xxxx()
+ functions itself. yuck.
+
+ ********************************************************************/
+static void make_srv_conn_1_info(CONN_INFO_1 *se1, CONN_INFO_1_STR *str1,
+ uint32 id, uint32 type,
+ uint32 num_opens, uint32 num_users, uint32 open_time,
+ char *usr_name, char *net_name)
+{
+ make_srv_conn_info1 (se1 , id, type, num_opens, num_users, open_time, usr_name, net_name);
+ make_srv_conn_info1_str(str1, usr_name, net_name);
+}
+
+/*******************************************************************
+ fill in a conn info level 1 structure.
+
+ this function breaks the rule that i'd like to be in place, namely
+ it doesn't receive its data as arguments: it has to call lp_xxxx()
+ functions itself. yuck.
+
+ ********************************************************************/
+static void make_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *stot)
+{
+ uint32 num_entries = 0;
+ (*stot) = 1;
+
+ if (ss1 == NULL)
+ {
+ (*snum) = 0;
+ return;
+ }
+
+ DEBUG(5,("make_srv_conn_1_ss1\n"));
+
+ if (snum)
+ {
+ for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++)
+ {
+ make_srv_conn_1_info(&(ss1->info_1 [num_entries]),
+ &(ss1->info_1_str[num_entries]),
+ (*stot), 0x3, 1, 1, 3,"dummy_user", "IPC$");
+
+ /* move on to creating next connection */
+ /* move on to creating next conn */
+ num_entries++;
+ }
+
+ ss1->num_entries_read = num_entries;
+ ss1->ptr_conn_info = num_entries > 0 ? 1 : 0;
+ ss1->num_entries_read2 = num_entries;
+
+
+ if ((*snum) >= (*stot))
+ {
+ (*snum) = 0;
+ }
+ }
+ else
+ {
+ ss1->num_entries_read = 0;
+ ss1->ptr_conn_info = 0;
+ ss1->num_entries_read2 = 0;
+
+ (*stot) = 0;
+ }
+}
+
+/*******************************************************************
+ makes a SRV_R_NET_CONN_ENUM structure.
+********************************************************************/
+static uint32 make_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr,
+ int switch_value, uint32 *resume_hnd, uint32 *total_entries)
+{
+ uint32 status = 0x0;
+ DEBUG(5,("make_srv_conn_info_ctr: %d\n", __LINE__));
+
+ ctr->switch_value = switch_value;
+
+ switch (switch_value)
+ {
+ case 0:
+ {
+ make_srv_conn_info_0(&(ctr->conn.info0), resume_hnd, total_entries);
+ ctr->ptr_conn_ctr = 1;
+ break;
+ }
+ case 1:
+ {
+ make_srv_conn_info_1(&(ctr->conn.info1), resume_hnd, total_entries);
+ ctr->ptr_conn_ctr = 1;
+ break;
+ }
+ default:
+ {
+ DEBUG(5,("make_srv_conn_info_ctr: unsupported switch value %d\n",
+ switch_value));
+ (*resume_hnd = 0);
+ (*total_entries) = 0;
+ ctr->ptr_conn_ctr = 0;
+ status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
+ break;
+ }
+ }
+
+ return status;
+}
+
+/*******************************************************************
+ makes a SRV_R_NET_CONN_ENUM structure.
+********************************************************************/
+static void make_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n,
+ uint32 resume_hnd, int conn_level, int switch_value)
+{
+ DEBUG(5,("make_srv_r_net_conn_enum: %d\n", __LINE__));
+
+ r_n->conn_level = conn_level;
+ if (conn_level == -1)
+ {
+ r_n->status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
+ }
+ else
+ {
+ r_n->status = make_srv_conn_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
+ }
+ if (r_n->status != 0x0)
+ {
+ resume_hnd = 0;
+ }
+ make_enum_hnd(&(r_n->enum_hnd), resume_hnd);
+}
+
+/*******************************************************************
+net conn enum
+********************************************************************/
+static void srv_reply_net_conn_enum(SRV_Q_NET_CONN_ENUM *q_n,
+ prs_struct *rdata)
+{
+ SRV_R_NET_CONN_ENUM r_n;
+ SRV_CONN_INFO_CTR ctr;
+
+ r_n.ctr = &ctr;
+
+ DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
+
+ /* set up the */
+ make_srv_r_net_conn_enum(&r_n,
+ get_enum_hnd(&q_n->enum_hnd),
+ q_n->conn_level,
+ q_n->ctr->switch_value);
+
+ /* store the response in the SMB stream */
+ srv_io_r_net_conn_enum("", &r_n, rdata, 0);
+
+ DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
+}
+
+/*******************************************************************
+ fill in a file info level 3 structure.
+ ********************************************************************/
+static void make_srv_file_3_info(FILE_INFO_3 *fl3, FILE_INFO_3_STR *str3,
+ uint32 fnum, uint32 perms, uint32 num_locks,
+ char *path_name, char *user_name)
+{
+ make_srv_file_info3 (fl3 , fnum, perms, num_locks, path_name, user_name);
+ make_srv_file_info3_str(str3, path_name, user_name);
+}
+
+/*******************************************************************
+ fill in a file info level 3 structure.
+
+ this function breaks the rule that i'd like to be in place, namely
+ it doesn't receive its data as arguments: it has to call lp_xxxx()
+ functions itself. yuck.
+
+ ********************************************************************/
+static void make_srv_file_info_3(SRV_FILE_INFO_3 *fl3, uint32 *fnum, uint32 *ftot)
+{
+ uint32 num_entries = 0;
+ (*ftot) = 1;
+
+ if (fl3 == NULL)
+ {
+ (*fnum) = 0;
+ return;
+ }
+
+ DEBUG(5,("make_srv_file_3_fl3\n"));
+
+ for (; (*fnum) < (*ftot) && num_entries < MAX_FILE_ENTRIES; (*fnum)++)
+ {
+ make_srv_file_3_info(&(fl3->info_3 [num_entries]),
+ &(fl3->info_3_str[num_entries]),
+ (*fnum), 0x35, 0, "\\PIPE\\samr", "dummy user");
+
+ /* move on to creating next file */
+ num_entries++;
+ }
+
+ fl3->num_entries_read = num_entries;
+ fl3->ptr_file_info = num_entries > 0 ? 1 : 0;
+ fl3->num_entries_read2 = num_entries;
+
+ if ((*fnum) >= (*ftot))
+ {
+ (*fnum) = 0;
+ }
+}
+
+/*******************************************************************
+ makes a SRV_R_NET_FILE_ENUM structure.
+********************************************************************/
+static uint32 make_srv_file_info_ctr(SRV_FILE_INFO_CTR *ctr,
+ int switch_value, uint32 *resume_hnd, uint32 *total_entries)
+{
+ uint32 status = 0x0;
+ DEBUG(5,("make_srv_file_info_ctr: %d\n", __LINE__));
+
+ ctr->switch_value = switch_value;
+
+ switch (switch_value)
+ {
+ case 3:
+ {
+ make_srv_file_info_3(&(ctr->file.info3), resume_hnd, total_entries);
+ ctr->ptr_file_ctr = 1;
+ break;
+ }
+ default:
+ {
+ DEBUG(5,("make_srv_file_info_ctr: unsupported switch value %d\n",
+ switch_value));
+ (*resume_hnd = 0);
+ (*total_entries) = 0;
+ ctr->ptr_file_ctr = 0;
+ status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
+ break;
+ }
+ }
+
+ return status;
+}
+
+/*******************************************************************
+ makes a SRV_R_NET_FILE_ENUM structure.
+********************************************************************/
+static void make_srv_r_net_file_enum(SRV_R_NET_FILE_ENUM *r_n,
+ uint32 resume_hnd, int file_level, int switch_value)
+{
+ DEBUG(5,("make_srv_r_net_file_enum: %d\n", __LINE__));
+
+ r_n->file_level = file_level;
+ if (file_level == 0)
+ {
+ r_n->status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
+ }
+ else
+ {
+ r_n->status = make_srv_file_info_ctr(r_n->ctr, switch_value, &resume_hnd, &(r_n->total_entries));
+ }
+ if (r_n->status != 0x0)
+ {
+ resume_hnd = 0;
+ }
+ make_enum_hnd(&(r_n->enum_hnd), resume_hnd);
+}
+
+/*******************************************************************
+net file enum
+********************************************************************/
+static void srv_reply_net_file_enum(SRV_Q_NET_FILE_ENUM *q_n,
+ prs_struct *rdata)
+{
+ SRV_R_NET_FILE_ENUM r_n;
+ SRV_FILE_INFO_CTR ctr;
+
+ r_n.ctr = &ctr;
+
+ DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
+
+ /* set up the */
+ make_srv_r_net_file_enum(&r_n,
+ get_enum_hnd(&q_n->enum_hnd),
+ q_n->file_level,
+ q_n->ctr->switch_value);
+
+ /* store the response in the SMB stream */
+ srv_io_r_net_file_enum("", &r_n, rdata, 0);
+
+ DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
+}
+
/*******************************************************************
net server get info
********************************************************************/
}
+/*******************************************************************
+********************************************************************/
+static void api_srv_net_file_enum( uint16 vuid, prs_struct *data,
+ prs_struct *rdata )
+{
+ SRV_Q_NET_FILE_ENUM q_n;
+ SRV_FILE_INFO_CTR ctr;
+
+ q_n.ctr = &ctr;
+
+ /* grab the net file enum */
+ srv_io_q_net_file_enum("", &q_n, data, 0);
+
+ /* construct reply. always indicate success */
+ srv_reply_net_file_enum(&q_n, rdata);
+}
+
+
+/*******************************************************************
+********************************************************************/
+static void api_srv_net_conn_enum( uint16 vuid, prs_struct *data,
+ prs_struct *rdata )
+{
+ SRV_Q_NET_CONN_ENUM q_n;
+ SRV_CONN_INFO_CTR ctr;
+
+ q_n.ctr = &ctr;
+
+ /* grab the net server get enum */
+ srv_io_q_net_conn_enum("", &q_n, data, 0);
+
+ /* construct reply. always indicate success */
+ srv_reply_net_conn_enum(&q_n, rdata);
+}
+
+
+/*******************************************************************
+********************************************************************/
+static void api_srv_net_sess_enum( uint16 vuid, prs_struct *data,
+ prs_struct *rdata )
+{
+ SRV_Q_NET_SESS_ENUM q_n;
+ SRV_SESS_INFO_CTR ctr;
+
+ q_n.ctr = &ctr;
+
+ /* grab the net server get enum */
+ srv_io_q_net_sess_enum("", &q_n, data, 0);
+
+ /* construct reply. always indicate success */
+ srv_reply_net_sess_enum(&q_n, rdata);
+}
+
/*******************************************************************
********************************************************************/
********************************************************************/
struct api_struct api_srv_cmds[] =
{
+ { "SRV_NETCONNENUM" , SRV_NETCONNENUM , api_srv_net_conn_enum },
+ { "SRV_NETSESSENUM" , SRV_NETSESSENUM , api_srv_net_sess_enum },
{ "SRV_NETSHAREENUM" , SRV_NETSHAREENUM , api_srv_net_share_enum },
+ { "SRV_NETFILEENUM" , SRV_NETFILEENUM , api_srv_net_file_enum },
{ "SRV_NET_SRV_GET_INFO", SRV_NET_SRV_GET_INFO, api_srv_net_srv_get_info },
{ "SRV_NET_REMOTE_TOD" , SRV_NET_REMOTE_TOD , api_srv_net_remote_tod },
{ NULL , 0 , NULL }
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* removed in SAMBA_2_0 branch */
+
+
+#ifdef SYSLOG
+#undef SYSLOG
+#endif
+
+#include "includes.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+
+#define DEBUG_TESTING
+
+extern struct cli_state *smb_cli;
+extern int smb_tidx;
+
+extern FILE* out_hnd;
+
+
+/****************************************************************************
+nt lsa query
+****************************************************************************/
+void cmd_lsa_query_info(struct client_info *info)
+{
+ fstring srv_name;
+
+ BOOL res = True;
+
+ fstrcpy(info->dom.level3_dom, "");
+ fstrcpy(info->dom.level5_dom, "");
+ ZERO_STRUCT(info->dom.level3_sid);
+ ZERO_STRUCT(info->dom.level5_sid);
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->myhostname);
+ strupper(srv_name);
+
+ DEBUG(4,("cmd_lsa_query_info: server:%s\n", srv_name));
+
+ DEBUG(5, ("cmd_lsa_query_info: smb_cli->fd:%d\n", smb_cli->fd));
+
+ /* open LSARPC session. */
+ res = res ? cli_nt_session_open(smb_cli, PIPE_LSARPC) : False;
+
+ /* lookup domain controller; receive a policy handle */
+ res = res ? do_lsa_open_policy(smb_cli,
+ srv_name,
+ &info->dom.lsa_info_pol, False) : False;
+
+ /* send client info query, level 3. receive domain name and sid */
+ res = res ? do_lsa_query_info_pol(smb_cli,
+ &info->dom.lsa_info_pol, 0x03,
+ info->dom.level3_dom,
+ &info->dom.level3_sid) : False;
+
+ /* send client info query, level 5. receive domain name and sid */
+ res = res ? do_lsa_query_info_pol(smb_cli,
+ &info->dom.lsa_info_pol, 0x05,
+ info->dom.level5_dom,
+ &info->dom.level5_sid) : False;
+
+ res = res ? do_lsa_close(smb_cli, &info->dom.lsa_info_pol) : False;
+
+ /* close the session */
+ cli_nt_session_close(smb_cli);
+
+ if (res)
+ {
+ BOOL domain_something = False;
+ fstring sid;
+ DEBUG(5,("cmd_lsa_query_info: query succeeded\n"));
+
+ fprintf(out_hnd, "LSA Query Info Policy\n");
+
+ if (info->dom.level3_dom[0] != 0)
+ {
+ sid_to_string(sid, &info->dom.level3_sid);
+ fprintf(out_hnd, "Domain Member - Domain: %s SID: %s\n",
+ info->dom.level3_dom, sid);
+ domain_something = True;
+ }
+ if (info->dom.level5_dom[0] != 0)
+ {
+ sid_to_string(sid, &info->dom.level5_sid);
+ fprintf(out_hnd, "Domain Controller - Domain: %s SID: %s\n",
+ info->dom.level5_dom, sid);
+ domain_something = True;
+ }
+ if (!domain_something)
+ {
+ fprintf(out_hnd, "%s is not a Domain Member or Controller\n",
+ info->dest_host);
+ }
+ }
+ else
+ {
+ DEBUG(5,("cmd_lsa_query_info: query failed\n"));
+ }
+}
+
+/****************************************************************************
+nt lsa query
+****************************************************************************/
+void cmd_lsa_lookup_sids(struct client_info *info)
+{
+ fstring temp;
+ int i;
+ pstring sid_name;
+ fstring srv_name;
+ DOM_SID sid[10];
+ DOM_SID *sids[10];
+ int num_sids = 0;
+ char **names = NULL;
+ int num_names = 0;
+
+ BOOL res = True;
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->myhostname);
+ strupper(srv_name);
+
+ DEBUG(4,("cmd_lsa_lookup_sids: server: %s\n", srv_name));
+
+ while (num_sids < 10 && next_token(NULL, temp, NULL, sizeof(temp)))
+ {
+ if (strnequal("S-", temp, 2))
+ {
+ fstrcpy(sid_name, temp);
+ }
+ else
+ {
+ sid_to_string(sid_name, &info->dom.level5_sid);
+
+ if (sid_name[0] == 0)
+ {
+ fprintf(out_hnd, "please use lsaquery first or specify a complete SID\n");
+ return;
+ }
+
+ fstrcat(sid_name, "-");
+ fstrcat(sid_name, temp);
+ }
+ make_dom_sid(&sid[num_sids], sid_name);
+ sids[num_sids] = &sid[num_sids];
+ num_sids++;
+ }
+
+ if (num_sids == 0)
+ {
+ fprintf(out_hnd, "lookupsid RID or SID\n");
+ return;
+ }
+
+ /* open LSARPC session. */
+ res = res ? cli_nt_session_open(smb_cli, PIPE_LSARPC) : False;
+
+ /* lookup domain controller; receive a policy handle */
+ res = res ? do_lsa_open_policy(smb_cli,
+ srv_name,
+ &info->dom.lsa_info_pol, True) : False;
+
+ /* send lsa lookup sids call */
+ res = res ? do_lsa_lookup_sids(smb_cli,
+ &info->dom.lsa_info_pol,
+ num_sids, sids,
+ &names, &num_names) : False;
+
+ res = res ? do_lsa_close(smb_cli, &info->dom.lsa_info_pol) : False;
+
+ /* close the session */
+ cli_nt_session_close(smb_cli);
+
+ if (res)
+ {
+ DEBUG(5,("cmd_lsa_lookup_sids: query succeeded\n"));
+ }
+ else
+ {
+ DEBUG(5,("cmd_lsa_lookup_sids: query failed\n"));
+ }
+ if (names != NULL)
+ {
+ fprintf(out_hnd,"Lookup SIDS:\n");
+ for (i = 0; i < num_names; i++)
+ {
+ sid_to_string(temp, sids[i]);
+ fprintf(out_hnd, "SID: %s -> %s\n", temp, names[i]);
+ if (names[i] != NULL)
+ {
+ free(names[i]);
+ }
+ }
+ free(names);
+ }
+}
+
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* removed in SAMBA_2_0 branch. */
+
+
+#ifdef SYSLOG
+#undef SYSLOG
+#endif
+
+#include "includes.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+
+#define DEBUG_TESTING
+
+extern struct cli_state *smb_cli;
+
+extern FILE* out_hnd;
+
+
+/****************************************************************************
+experimental nt login.
+****************************************************************************/
+void cmd_netlogon_login_test(struct client_info *info)
+{
+ extern BOOL global_machine_password_needs_changing;
+
+ fstring nt_user_name;
+ fstring password;
+ BOOL res = True;
+ char *nt_password;
+ unsigned char trust_passwd[16];
+
+#if 0
+ /* machine account passwords */
+ pstring new_mach_pwd;
+
+ /* initialisation */
+ new_mach_pwd[0] = 0;
+#endif
+
+ if (!next_token(NULL, nt_user_name, NULL, sizeof(nt_user_name)))
+ {
+ fstrcpy(nt_user_name, smb_cli->user_name);
+ if (nt_user_name[0] == 0)
+ {
+ fprintf(out_hnd,"ntlogin: must specify username with anonymous connection\n");
+ return;
+ }
+ }
+
+ if (next_token(NULL, password, NULL, sizeof(password)))
+ {
+ nt_password = password;
+ }
+ else
+ {
+ nt_password = getpass("Enter NT Login password:");
+ }
+
+ DEBUG(5,("do_nt_login_test: username %s\n", nt_user_name));
+
+ res = res ? trust_get_passwd(trust_passwd, smb_cli->domain, info->myhostname) : False;
+
+#if 0
+ /* check whether the user wants to change their machine password */
+ res = res ? trust_account_check(info->dest_ip, info->dest_host,
+ info->myhostname, smb_cli->domain,
+ info->mach_acct, new_mach_pwd) : False;
+#endif
+ /* open NETLOGON session. negotiate credentials */
+ res = res ? cli_nt_session_open(smb_cli, PIPE_NETLOGON) : False;
+
+ res = res ? cli_nt_setup_creds(smb_cli, trust_passwd) : False;
+
+ /* change the machine password? */
+ if (global_machine_password_needs_changing)
+ {
+ unsigned char new_trust_passwd[16];
+ generate_random_buffer(new_trust_passwd, 16, True);
+ res = res ? cli_nt_srv_pwset(smb_cli, new_trust_passwd) : False;
+
+ if (res)
+ {
+ global_machine_password_needs_changing = !set_trust_account_password(new_trust_passwd);
+ }
+
+ memset(new_trust_passwd, 0, 16);
+ }
+
+ memset(trust_passwd, 0, 16);
+
+ /* do an NT login */
+ res = res ? cli_nt_login_interactive(smb_cli,
+ smb_cli->domain, nt_user_name,
+ getuid(), nt_password,
+ &info->dom.ctr, &info->dom.user_info3) : False;
+
+ /*** clear out the password ***/
+ memset(password, 0, sizeof(password));
+
+ /* ok! you're logged in! do anything you like, then... */
+
+ /* do an NT logout */
+ res = res ? cli_nt_logoff(smb_cli, &info->dom.ctr) : False;
+
+ /* close the session */
+ cli_nt_session_close(smb_cli);
+
+ fprintf(out_hnd,"cmd_nt_login: login (%s) test succeeded: %s\n",
+ nt_user_name, BOOLSTR(res));
+}
+
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* removed in SAMBA_2_0 branch. */
+
+
+#ifdef SYSLOG
+#undef SYSLOG
+#endif
+
+#include "includes.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+
+extern struct cli_state *smb_cli;
+extern int smb_tidx;
+
+extern FILE* out_hnd;
+
+/*
+ * keys. of the form:
+ * ----
+ *
+ * [HKLM]|[HKU]\[parent_keyname_components]\[subkey]|[value]
+ *
+ * reg_getsubkey() splits this down into:
+ * [HKLM]|[HKU]\[parent_keyname_components] and [subkey]|[value]
+ *
+ * do_reg_connect() splits the left side down further into:
+ * [HKLM]|[HKU] and [parent_keyname_components].
+ *
+ * HKLM is short for HKEY_LOCAL_MACHINE
+ * HKU is short for HKEY_USERS
+ *
+ * oh, and HKEY stands for "Hive Key".
+ *
+ */
+
+/****************************************************************************
+nt registry enum
+****************************************************************************/
+void cmd_reg_enum(struct client_info *info)
+{
+ BOOL res = True;
+ BOOL res1 = True;
+ BOOL res2 = True;
+ int i;
+
+ POLICY_HND key_pol;
+ fstring full_keyname;
+ fstring key_name;
+
+ /*
+ * query key info
+ */
+
+ fstring key_class;
+ uint32 max_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;
+
+ /*
+ * unknown 0x1a request
+ */
+
+ uint32 unk_1a_response;
+
+ DEBUG(5, ("cmd_reg_enum: smb_cli->fd:%d\n", smb_cli->fd));
+
+ if (!next_token(NULL, full_keyname, NULL, sizeof(full_keyname)))
+ {
+ fprintf(out_hnd, "regenum <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_connect(smb_cli, full_keyname, key_name,
+ &info->dom.reg_pol_connect) : False;
+
+ if ((*key_name) != 0)
+ {
+ /* open an entry */
+ res1 = res ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
+ key_name, 0x02000000, &key_pol) : False;
+ }
+ else
+ {
+ memcpy(&key_pol, &info->dom.reg_pol_connect, sizeof(key_pol));
+ }
+
+ res1 = 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;
+
+ if (res1 && num_subkeys > 0)
+ {
+ fprintf(out_hnd,"Subkeys\n");
+ fprintf(out_hnd,"-------\n");
+ }
+
+ for (i = 0; i < num_subkeys; i++)
+ {
+ /*
+ * enumerate key
+ */
+
+ fstring enum_name;
+ uint32 enum_unk1;
+ uint32 enum_unk2;
+ time_t key_mod_time;
+
+ /* unknown 1a it */
+ res2 = res1 ? do_reg_unknown_1a(smb_cli, &key_pol,
+ &unk_1a_response) : False;
+
+ if (res2 && unk_1a_response != 5)
+ {
+ fprintf(out_hnd,"Unknown 1a response: %x\n", unk_1a_response);
+ }
+
+ /* enum key */
+ res2 = res2 ? do_reg_enum_key(smb_cli, &key_pol,
+ i, enum_name,
+ &enum_unk1, &enum_unk2,
+ &key_mod_time) : False;
+
+ if (res2)
+ {
+ display_reg_key_info(out_hnd, ACTION_HEADER , enum_name, key_mod_time);
+ display_reg_key_info(out_hnd, ACTION_ENUMERATE, enum_name, key_mod_time);
+ display_reg_key_info(out_hnd, ACTION_FOOTER , enum_name, key_mod_time);
+ }
+
+ }
+
+ if (num_values > 0)
+ {
+ fprintf(out_hnd,"Key Values\n");
+ fprintf(out_hnd,"----------\n");
+ }
+
+ for (i = 0; i < num_values; i++)
+ {
+ /*
+ * enumerate key
+ */
+
+ uint32 val_type;
+ BUFFER2 value;
+ fstring val_name;
+
+ /* unknown 1a it */
+ res2 = res1 ? do_reg_unknown_1a(smb_cli, &key_pol,
+ &unk_1a_response) : False;
+
+ if (res2 && unk_1a_response != 5)
+ {
+ fprintf(out_hnd,"Unknown 1a response: %x\n", unk_1a_response);
+ }
+
+ /* enum key */
+ res2 = res2 ? do_reg_enum_val(smb_cli, &key_pol,
+ i, max_valnamelen, max_valbufsize,
+ val_name, &val_type, &value) : False;
+
+ if (res2)
+ {
+ display_reg_value_info(out_hnd, ACTION_HEADER , val_name, val_type, &value);
+ display_reg_value_info(out_hnd, ACTION_ENUMERATE, val_name, val_type, &value);
+ display_reg_value_info(out_hnd, ACTION_FOOTER , val_name, val_type, &value);
+ }
+ }
+
+ /* close the handles */
+ if ((*key_name) != 0)
+ {
+ 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 && res2)
+ {
+ DEBUG(5,("cmd_reg_enum: query succeeded\n"));
+ }
+ else
+ {
+ DEBUG(5,("cmd_reg_enum: query failed\n"));
+ }
+}
+
+/****************************************************************************
+nt registry query key
+****************************************************************************/
+void cmd_reg_query_key(struct client_info *info)
+{
+ BOOL res = True;
+ BOOL res1 = True;
+
+ POLICY_HND key_pol;
+ fstring full_keyname;
+ 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, full_keyname, NULL, sizeof(full_keyname)))
+ {
+ 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_connect(smb_cli, full_keyname, key_name,
+ &info->dom.reg_pol_connect) : False;
+
+ if ((*key_name) != 0)
+ {
+ /* open an entry */
+ res1 = res ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
+ key_name, 0x02000000, &key_pol) : False;
+ }
+ else
+ {
+ memcpy(&key_pol, &info->dom.reg_pol_connect, sizeof(key_pol));
+ }
+
+ 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 */
+ if ((*key_name) != 0)
+ {
+ 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 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 full_keyname;
+ fstring keyname;
+ 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_create_val: smb_cli->fd:%d\n", smb_cli->fd));
+
+ if (!next_token(NULL, full_keyname, NULL, sizeof(full_keyname)))
+ {
+ fprintf(out_hnd, "regcreate <val_name> <val_type> <val>\n");
+ return;
+ }
+
+ reg_get_subkey(full_keyname, keyname, val_name);
+
+ if (keyname[0] == 0 || val_name[0] == 0)
+ {
+ fprintf(out_hnd, "invalid key name\n");
+ return;
+ }
+
+ if (!next_token(NULL, tmp, NULL, sizeof(tmp)))
+ {
+ fprintf(out_hnd, "regcreate <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 <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, (char *)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_connect(smb_cli, keyname, parent_name,
+ &info->dom.reg_pol_connect) : False;
+
+ if ((*val_name) != 0)
+ {
+ /* open an entry */
+ res3 = res ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
+ parent_name, 0x02000000, &parent_pol) : False;
+ }
+ else
+ {
+ memcpy(&parent_pol, &info->dom.reg_pol_connect, sizeof(parent_pol));
+ }
+
+ /* create an entry */
+ res4 = res3 ? do_reg_create_val(smb_cli, &parent_pol,
+ val_name, val_type, &value) : False;
+
+ /* flush the modified key */
+ res4 = res4 ? do_reg_flush_key(smb_cli, &parent_pol) : False;
+
+ /* close the val handle */
+ if ((*val_name) != 0)
+ {
+ 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 delete value
+****************************************************************************/
+void cmd_reg_delete_val(struct client_info *info)
+{
+ BOOL res = True;
+ BOOL res3 = True;
+ BOOL res4 = True;
+
+ POLICY_HND parent_pol;
+ fstring full_keyname;
+ fstring keyname;
+ fstring parent_name;
+ fstring val_name;
+
+ DEBUG(5, ("cmd_reg_delete_val: smb_cli->fd:%d\n", smb_cli->fd));
+
+ if (!next_token(NULL, full_keyname, NULL, sizeof(full_keyname)))
+ {
+ fprintf(out_hnd, "regdelete <val_name>\n");
+ return;
+ }
+
+ reg_get_subkey(full_keyname, keyname, val_name);
+
+ if (keyname[0] == 0 || val_name[0] == 0)
+ {
+ fprintf(out_hnd, "invalid 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_connect(smb_cli, keyname, parent_name,
+ &info->dom.reg_pol_connect) : False;
+
+ if ((*val_name) != 0)
+ {
+ /* open an entry */
+ res3 = res ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
+ parent_name, 0x02000000, &parent_pol) : False;
+ }
+ else
+ {
+ memcpy(&parent_pol, &info->dom.reg_pol_connect, sizeof(parent_pol));
+ }
+
+ /* delete an entry */
+ res4 = res3 ? do_reg_delete_val(smb_cli, &parent_pol, val_name) : False;
+
+ /* flush the modified key */
+ res4 = res4 ? do_reg_flush_key(smb_cli, &parent_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_delete_val: query succeeded\n"));
+ fprintf(out_hnd,"OK\n");
+ }
+ else
+ {
+ DEBUG(5,("cmd_reg_delete_val: query failed\n"));
+ }
+}
+
+/****************************************************************************
+nt registry delete key
+****************************************************************************/
+void cmd_reg_delete_key(struct client_info *info)
+{
+ BOOL res = True;
+ BOOL res3 = True;
+ BOOL res4 = True;
+
+ POLICY_HND parent_pol;
+ fstring full_keyname;
+ fstring parent_name;
+ fstring key_name;
+ fstring subkey_name;
+
+ DEBUG(5, ("cmd_reg_delete_key: smb_cli->fd:%d\n", smb_cli->fd));
+
+ if (!next_token(NULL, full_keyname, NULL, sizeof(full_keyname)))
+ {
+ fprintf(out_hnd, "regdeletekey <key_name>\n");
+ return;
+ }
+
+ reg_get_subkey(full_keyname, parent_name, subkey_name);
+
+ if (parent_name[0] == 0 || subkey_name[0] == 0)
+ {
+ fprintf(out_hnd, "invalid 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_connect(smb_cli, parent_name, key_name,
+ &info->dom.reg_pol_connect) : False;
+
+ if ((*key_name) != 0)
+ {
+ /* open an entry */
+ res3 = res ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
+ key_name, 0x02000000, &parent_pol) : False;
+ }
+ else
+ {
+ memcpy(&parent_pol, &info->dom.reg_pol_connect, sizeof(parent_pol));
+ }
+
+ /* create an entry */
+ res4 = res3 ? do_reg_delete_key(smb_cli, &parent_pol, subkey_name) : False;
+
+ /* flush the modified key */
+ res4 = res4 ? do_reg_flush_key(smb_cli, &parent_pol) : False;
+
+ /* close the key handle */
+ if ((*key_name) != 0)
+ {
+ 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_delete_key: query succeeded\n"));
+ fprintf(out_hnd,"OK\n");
+ }
+ else
+ {
+ DEBUG(5,("cmd_reg_delete_key: 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 full_keyname;
+ fstring parent_key;
+ fstring parent_name;
+ fstring key_name;
+ fstring key_class;
+ SEC_ACCESS sam_access;
+
+ DEBUG(5, ("cmd_reg_create_key: smb_cli->fd:%d\n", smb_cli->fd));
+
+ if (!next_token(NULL, full_keyname, NULL, sizeof(full_keyname)))
+ {
+ fprintf(out_hnd, "regcreate <key_name> [key_class]\n");
+ return;
+ }
+
+ reg_get_subkey(full_keyname, parent_key, key_name);
+
+ if (parent_key[0] == 0 || key_name[0] == 0)
+ {
+ fprintf(out_hnd, "invalid key name\n");
+ return;
+ }
+
+ if (!next_token(NULL, key_class, NULL, sizeof(key_class)))
+ {
+ memset(key_class, 0, sizeof(key_class));
+ }
+
+ /* set access permissions */
+ sam_access.mask = 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_connect(smb_cli, parent_key, parent_name,
+ &info->dom.reg_pol_connect) : False;
+
+ if ((*parent_name) != 0)
+ {
+ /* open an entry */
+ res3 = res ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
+ parent_name, 0x02000000, &parent_pol) : False;
+ }
+ else
+ {
+ memcpy(&parent_pol, &info->dom.reg_pol_connect, sizeof(parent_pol));
+ }
+
+ /* create an entry */
+ res4 = res3 ? do_reg_create_key(smb_cli, &parent_pol,
+ key_name, key_class, &sam_access, &key_pol) : False;
+
+ /* flush the modified key */
+ res4 = res4 ? do_reg_flush_key(smb_cli, &parent_pol) : False;
+
+ /* close the key handle */
+ res4 = res4 ? do_reg_close(smb_cli, &key_pol) : False;
+
+ /* close the key handle */
+ if ((*parent_name) != 0)
+ {
+ 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
+****************************************************************************/
+void cmd_reg_test_key_sec(struct client_info *info)
+{
+ BOOL res = True;
+ BOOL res3 = True;
+ BOOL res4 = True;
+
+ POLICY_HND key_pol;
+ fstring full_keyname;
+ fstring key_name;
+
+ /*
+ * security info
+ */
+
+ uint32 sec_buf_size;
+ SEC_DESC_BUF *psdb;
+
+ DEBUG(5, ("cmd_reg_get_key_sec: smb_cli->fd:%d\n", smb_cli->fd));
+
+ if (!next_token(NULL, full_keyname, NULL, sizeof(full_keyname)))
+ {
+ fprintf(out_hnd, "reggetsec <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_connect(smb_cli, full_keyname, key_name,
+ &info->dom.reg_pol_connect) : False;
+
+ if ((*key_name) != 0)
+ {
+ /* open an entry */
+ res3 = res ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
+ key_name, 0x02000000, &key_pol) : False;
+ }
+ else
+ {
+ memcpy(&key_pol, &info->dom.reg_pol_connect, sizeof(key_pol));
+ }
+
+ /* open an entry */
+ res3 = res ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
+ key_name, 0x02000000, &key_pol) : False;
+
+ /* query key sec info. first call sets sec_buf_size. */
+
+ sec_buf_size = 0;
+ res4 = res3 ? do_reg_get_key_sec(smb_cli, &key_pol,
+ &sec_buf_size, &psdb) : False;
+
+ free_sec_desc_buf(&psdb);
+
+ res4 = res4 ? do_reg_get_key_sec(smb_cli, &key_pol,
+ &sec_buf_size, &psdb) : False;
+
+ if (res4 && psdb->len > 0 && psdb->sec != NULL)
+ {
+ display_sec_desc(out_hnd, ACTION_HEADER , psdb->sec);
+ display_sec_desc(out_hnd, ACTION_ENUMERATE, psdb->sec);
+ display_sec_desc(out_hnd, ACTION_FOOTER , psdb->sec);
+
+ res4 = res4 ? do_reg_set_key_sec(smb_cli, &key_pol, psdb) : False;
+ }
+
+ free_sec_desc_buf(&psdb);
+
+ /* close the key handle */
+ if ((*key_name) != 0)
+ {
+ res3 = res3 ? do_reg_close(smb_cli, &key_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_test2: query succeeded\n"));
+ fprintf(out_hnd,"Registry Test2\n");
+ }
+ else
+ {
+ DEBUG(5,("cmd_reg_test2: query failed\n"));
+ }
+}
+
+/****************************************************************************
+nt registry security info
+****************************************************************************/
+void cmd_reg_get_key_sec(struct client_info *info)
+{
+ BOOL res = True;
+ BOOL res3 = True;
+ BOOL res4 = True;
+
+ POLICY_HND key_pol;
+ fstring full_keyname;
+ fstring key_name;
+
+ /*
+ * security info
+ */
+
+ uint32 sec_buf_size;
+ SEC_DESC_BUF *psdb;
+
+ DEBUG(5, ("cmd_reg_get_key_sec: smb_cli->fd:%d\n", smb_cli->fd));
+
+ if (!next_token(NULL, full_keyname, NULL, sizeof(full_keyname)))
+ {
+ fprintf(out_hnd, "reggetsec <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_connect(smb_cli, full_keyname, key_name,
+ &info->dom.reg_pol_connect) : False;
+
+ if ((*key_name) != 0)
+ {
+ /* open an entry */
+ res3 = res ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
+ key_name, 0x02000000, &key_pol) : False;
+ }
+ else
+ {
+ memcpy(&key_pol, &info->dom.reg_pol_connect, sizeof(key_pol));
+ }
+
+ /* open an entry */
+ res3 = res ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
+ key_name, 0x02000000, &key_pol) : False;
+
+ /* Get the size. */
+ sec_buf_size = 0;
+ res4 = res3 ? do_reg_get_key_sec(smb_cli, &key_pol,
+ &sec_buf_size, &psdb) : False;
+
+ free_sec_desc_buf(&psdb);
+
+ res4 = res4 ? do_reg_get_key_sec(smb_cli, &key_pol,
+ &sec_buf_size, &psdb) : False;
+
+ if (res4 && psdb->len > 0 && psdb->sec != NULL)
+ {
+ display_sec_desc(out_hnd, ACTION_HEADER , psdb->sec);
+ display_sec_desc(out_hnd, ACTION_ENUMERATE, psdb->sec);
+ display_sec_desc(out_hnd, ACTION_FOOTER , psdb->sec);
+ }
+
+ free_sec_desc_buf(&psdb);
+
+ /* close the key handle */
+ if ((*key_name) != 0)
+ {
+ res3 = res3 ? do_reg_close(smb_cli, &key_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_get_key_sec: query succeeded\n"));
+ }
+ else
+ {
+ DEBUG(5,("cmd_reg_get_key_sec: query failed\n"));
+ }
+}
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* removed in SAMBA_2_0 branch. */
+
+
+#ifdef SYSLOG
+#undef SYSLOG
+#endif
+
+#include "includes.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+
+#define DEBUG_TESTING
+
+extern struct cli_state *smb_cli;
+
+extern FILE* out_hnd;
+
+
+/****************************************************************************
+SAM password change
+****************************************************************************/
+void cmd_sam_ntchange_pwd(struct client_info *info)
+{
+ fstring srv_name;
+ fstring domain;
+ fstring sid;
+ char *new_passwd;
+ BOOL res = True;
+ char nt_newpass[516];
+ uchar nt_hshhash[16];
+ uchar nt_newhash[16];
+ uchar nt_oldhash[16];
+ char lm_newpass[516];
+ uchar lm_newhash[16];
+ uchar lm_hshhash[16];
+ uchar lm_oldhash[16];
+
+ sid_to_string(sid, &info->dom.level5_sid);
+ fstrcpy(domain, info->dom.level5_dom);
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ fprintf(out_hnd, "SAM NT Password Change\n");
+
+#if 0
+ struct pwd_info new_pwd;
+ pwd_read(&new_pwd, "New Password (ONCE: this is test code!):", True);
+#endif
+ new_passwd = (char*)getpass("New Password (ONCE ONLY - get it right :-)");
+
+ nt_lm_owf_gen(new_passwd, lm_newhash, nt_newhash);
+ pwd_get_lm_nt_16(&(smb_cli->pwd), lm_oldhash, nt_oldhash );
+ make_oem_passwd_hash(nt_newpass, new_passwd, nt_oldhash, True);
+ make_oem_passwd_hash(lm_newpass, new_passwd, lm_oldhash, True);
+ E_old_pw_hash(lm_newhash, lm_oldhash, lm_hshhash);
+ E_old_pw_hash(lm_newhash, nt_oldhash, nt_hshhash);
+
+ cli_nt_set_ntlmssp_flgs(smb_cli,
+ NTLMSSP_NEGOTIATE_UNICODE |
+ NTLMSSP_NEGOTIATE_OEM |
+ NTLMSSP_NEGOTIATE_SIGN |
+ NTLMSSP_NEGOTIATE_SEAL |
+ NTLMSSP_NEGOTIATE_LM_KEY |
+ NTLMSSP_NEGOTIATE_NTLM |
+ NTLMSSP_NEGOTIATE_ALWAYS_SIGN |
+ NTLMSSP_NEGOTIATE_00001000 |
+ NTLMSSP_NEGOTIATE_00002000);
+
+ /* open SAMR session. */
+ res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
+
+ /* establish a connection. */
+ res = res ? do_samr_unknown_38(smb_cli, srv_name) : False;
+
+ /* establish a connection. */
+ res = res ? do_samr_chgpasswd_user(smb_cli,
+ srv_name, smb_cli->user_name,
+ nt_newpass, nt_hshhash,
+ lm_newpass, lm_hshhash) : False;
+ /* close the session */
+ cli_nt_session_close(smb_cli);
+
+ if (res)
+ {
+ fprintf(out_hnd, "NT Password changed OK\n");
+ }
+ else
+ {
+ fprintf(out_hnd, "NT Password change FAILED\n");
+ }
+}
+
+
+/****************************************************************************
+experimental SAM encryted rpc test connection
+****************************************************************************/
+void cmd_sam_test(struct client_info *info)
+{
+ fstring srv_name;
+ fstring domain;
+ fstring sid;
+ BOOL res = True;
+
+ sid_to_string(sid, &info->dom.level5_sid);
+ fstrcpy(domain, info->dom.level5_dom);
+
+/*
+ if (strlen(sid) == 0)
+ {
+ fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+ return;
+ }
+*/
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ fprintf(out_hnd, "SAM Encryption Test\n");
+
+ cli_nt_set_ntlmssp_flgs(smb_cli,
+ NTLMSSP_NEGOTIATE_UNICODE |
+ NTLMSSP_NEGOTIATE_OEM |
+ NTLMSSP_NEGOTIATE_SIGN |
+ NTLMSSP_NEGOTIATE_SEAL |
+ NTLMSSP_NEGOTIATE_LM_KEY |
+ NTLMSSP_NEGOTIATE_NTLM |
+ NTLMSSP_NEGOTIATE_ALWAYS_SIGN |
+ NTLMSSP_NEGOTIATE_00001000 |
+ NTLMSSP_NEGOTIATE_00002000);
+
+ /* open SAMR session. */
+ res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
+
+ /* establish a connection. */
+ res = res ? do_samr_unknown_38(smb_cli, srv_name) : False;
+
+ /* close the session */
+ cli_nt_session_close(smb_cli);
+
+ if (res)
+ {
+ DEBUG(5,("cmd_sam_test: succeeded\n"));
+ }
+ else
+ {
+ DEBUG(5,("cmd_sam_test: failed\n"));
+ }
+}
+
+
+/****************************************************************************
+experimental SAM users enum.
+****************************************************************************/
+void cmd_sam_enum_users(struct client_info *info)
+{
+ fstring srv_name;
+ fstring domain;
+ fstring sid;
+ DOM_SID sid1;
+ int user_idx;
+ BOOL res = True;
+ BOOL request_user_info = False;
+ BOOL request_group_info = False;
+ uint16 num_entries = 0;
+ uint16 unk_0 = 0x0;
+ uint16 acb_mask = 0;
+ uint16 unk_1 = 0x0;
+ uint32 admin_rid = 0x304; /* absolutely no idea. */
+ fstring tmp;
+
+ sid_to_string(sid, &info->dom.level5_sid);
+ fstrcpy(domain, info->dom.level5_dom);
+
+ if (strlen(sid) == 0)
+ {
+ fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+ return;
+ }
+
+ make_dom_sid(&sid1, sid);
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ /* a bad way to do token parsing... */
+ if (next_token(NULL, tmp, NULL, sizeof(tmp)))
+ {
+ request_user_info |= strequal(tmp, "-u");
+ request_group_info |= strequal(tmp, "-g");
+ }
+
+ if (next_token(NULL, tmp, NULL, sizeof(tmp)))
+ {
+ request_user_info |= strequal(tmp, "-u");
+ request_group_info |= strequal(tmp, "-g");
+ }
+
+#ifdef DEBUG_TESTING
+ if (next_token(NULL, tmp, NULL, sizeof(tmp)))
+ {
+ num_entries = (uint16)strtol(tmp, (char**)NULL, 16);
+ }
+
+ if (next_token(NULL, tmp, NULL, sizeof(tmp)))
+ {
+ unk_0 = (uint16)strtol(tmp, (char**)NULL, 16);
+ }
+
+ if (next_token(NULL, tmp, NULL, sizeof(tmp)))
+ {
+ acb_mask = (uint16)strtol(tmp, (char**)NULL, 16);
+ }
+
+ if (next_token(NULL, tmp, NULL, sizeof(tmp)))
+ {
+ unk_1 = (uint16)strtol(tmp, (char**)NULL, 16);
+ }
+#endif
+
+ fprintf(out_hnd, "SAM Enumerate Users\n");
+ fprintf(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
+ info->myhostname, srv_name, domain, sid);
+
+#ifdef DEBUG_TESTING
+ DEBUG(5,("Number of entries:%d unk_0:%04x acb_mask:%04x unk_1:%04x\n",
+ num_entries, unk_0, acb_mask, unk_1));
+#endif
+
+ /* open SAMR session. negotiate credentials */
+ res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
+
+ /* establish a connection. */
+ res = res ? do_samr_connect(smb_cli,
+ srv_name, 0x00000020,
+ &info->dom.samr_pol_connect) : False;
+
+ /* connect to the domain */
+ res = res ? do_samr_open_domain(smb_cli,
+ &info->dom.samr_pol_connect, admin_rid, &sid1,
+ &info->dom.samr_pol_open_domain) : False;
+
+ /* read some users */
+ res = res ? do_samr_enum_dom_users(smb_cli,
+ &info->dom.samr_pol_open_domain,
+ num_entries, unk_0, acb_mask, unk_1, 0xffff,
+ &info->dom.sam, &info->dom.num_sam_entries) : False;
+
+ if (res && info->dom.num_sam_entries == 0)
+ {
+ fprintf(out_hnd, "No users\n");
+ }
+
+ if (request_user_info || request_group_info)
+ {
+ /* query all the users */
+ user_idx = 0;
+
+ while (res && user_idx < info->dom.num_sam_entries)
+ {
+ uint32 user_rid = info->dom.sam[user_idx].smb_userid;
+ SAM_USER_INFO_21 usr;
+
+ fprintf(out_hnd, "User RID: %8x User Name: %s\n",
+ user_rid,
+ info->dom.sam[user_idx].acct_name);
+
+ if (request_user_info)
+ {
+ /* send user info query, level 0x15 */
+ if (get_samr_query_userinfo(smb_cli,
+ &info->dom.samr_pol_open_domain,
+ 0x15, user_rid, &usr))
+ {
+ display_sam_user_info_21(out_hnd, ACTION_HEADER , &usr);
+ display_sam_user_info_21(out_hnd, ACTION_ENUMERATE, &usr);
+ display_sam_user_info_21(out_hnd, ACTION_FOOTER , &usr);
+ }
+ }
+
+ if (request_group_info)
+ {
+ uint32 num_groups;
+ DOM_GID gid[LSA_MAX_GROUPS];
+
+ /* send user group query */
+ if (get_samr_query_usergroups(smb_cli,
+ &info->dom.samr_pol_open_domain,
+ user_rid, &num_groups, gid))
+ {
+ display_group_rid_info(out_hnd, ACTION_HEADER , num_groups, gid);
+ display_group_rid_info(out_hnd, ACTION_ENUMERATE, num_groups, gid);
+ display_group_rid_info(out_hnd, ACTION_FOOTER , num_groups, gid);
+ }
+ }
+
+ user_idx++;
+ }
+ }
+
+ res = res ? do_samr_close(smb_cli,
+ &info->dom.samr_pol_open_domain) : False;
+
+ res = res ? do_samr_close(smb_cli,
+ &info->dom.samr_pol_connect) : False;
+
+ /* close the session */
+ cli_nt_session_close(smb_cli);
+
+ if (info->dom.sam != NULL)
+ {
+ free(info->dom.sam);
+ }
+
+ if (res)
+ {
+ DEBUG(5,("cmd_sam_enum_users: succeeded\n"));
+ }
+ else
+ {
+ DEBUG(5,("cmd_sam_enum_users: failed\n"));
+ }
+}
+
+
+/****************************************************************************
+experimental SAM user query.
+****************************************************************************/
+void cmd_sam_query_user(struct client_info *info)
+{
+ fstring srv_name;
+ fstring domain;
+ fstring sid;
+ DOM_SID sid1;
+ int user_idx = 0; /* FIXME maybe ... */
+ BOOL res = True;
+ uint32 admin_rid = 0x304; /* absolutely no idea. */
+ fstring rid_str ;
+ fstring info_str;
+ uint32 user_rid = 0;
+ uint32 info_level = 0x15;
+
+ SAM_USER_INFO_21 usr;
+
+ sid_to_string(sid, &info->dom.level5_sid);
+ fstrcpy(domain, info->dom.level5_dom);
+
+ if (strlen(sid) == 0)
+ {
+ fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+ return;
+ }
+
+ make_dom_sid(&sid1, sid);
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ if (next_token(NULL, rid_str , NULL, sizeof(rid_str )) &&
+ next_token(NULL, info_str, NULL, sizeof(info_str)))
+ {
+ user_rid = (uint32)strtol(rid_str , (char**)NULL, 16);
+ info_level = (uint32)strtol(info_str, (char**)NULL, 10);
+ }
+
+ fprintf(out_hnd, "SAM Query User: rid %x info level %d\n",
+ user_rid, info_level);
+ fprintf(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
+ info->myhostname, srv_name, domain, sid);
+
+ /* open SAMR session. negotiate credentials */
+ res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
+
+ /* establish a connection. */
+ res = res ? do_samr_connect(smb_cli,
+ srv_name, 0x00000020,
+ &info->dom.samr_pol_connect) : False;
+
+ /* connect to the domain */
+ res = res ? do_samr_open_domain(smb_cli,
+ &info->dom.samr_pol_connect, admin_rid, &sid1,
+ &info->dom.samr_pol_open_domain) : False;
+
+ fprintf(out_hnd, "User RID: %8x User Name: %s\n",
+ user_rid,
+ info->dom.sam[user_idx].acct_name);
+
+ /* send user info query, level */
+ if (get_samr_query_userinfo(smb_cli,
+ &info->dom.samr_pol_open_domain,
+ info_level, user_rid, &usr))
+ {
+ if (info_level == 0x15)
+ {
+ display_sam_user_info_21(out_hnd, ACTION_HEADER , &usr);
+ display_sam_user_info_21(out_hnd, ACTION_ENUMERATE, &usr);
+ display_sam_user_info_21(out_hnd, ACTION_FOOTER , &usr);
+ }
+ }
+
+ res = res ? do_samr_close(smb_cli,
+ &info->dom.samr_pol_connect) : False;
+
+ res = res ? do_samr_close(smb_cli,
+ &info->dom.samr_pol_open_domain) : False;
+
+ /* close the session */
+ cli_nt_session_close(smb_cli);
+
+ if (res)
+ {
+ DEBUG(5,("cmd_sam_query_user: succeeded\n"));
+ }
+ else
+ {
+ DEBUG(5,("cmd_sam_query_user: failed\n"));
+ }
+}
+
+
+/****************************************************************************
+experimental SAM groups query.
+****************************************************************************/
+void cmd_sam_query_groups(struct client_info *info)
+{
+ fstring srv_name;
+ fstring domain;
+ fstring sid;
+ DOM_SID sid1;
+ BOOL res = True;
+ fstring info_str;
+ uint32 switch_value = 2;
+ uint32 admin_rid = 0x304; /* absolutely no idea. */
+
+ sid_to_string(sid, &info->dom.level5_sid);
+ fstrcpy(domain, info->dom.level5_dom);
+
+ if (strlen(sid) == 0)
+ {
+ fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+ return;
+ }
+
+ make_dom_sid(&sid1, sid);
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ if (next_token(NULL, info_str, NULL, sizeof(info_str)))
+ {
+ switch_value = (uint32)strtol(info_str, (char**)NULL, 10);
+ }
+
+ fprintf(out_hnd, "SAM Query Groups: info level %d\n", switch_value);
+ fprintf(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
+ info->myhostname, srv_name, domain, sid);
+
+ /* open SAMR session. negotiate credentials */
+ res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
+
+ /* establish a connection. */
+ res = res ? do_samr_connect(smb_cli,
+ srv_name, 0x00000020,
+ &info->dom.samr_pol_connect) : False;
+
+ /* connect to the domain */
+ res = res ? do_samr_open_domain(smb_cli,
+ &info->dom.samr_pol_connect, admin_rid, &sid1,
+ &info->dom.samr_pol_open_domain) : False;
+
+ /* send a samr 0x8 command */
+ res = res ? do_samr_query_dom_info(smb_cli,
+ &info->dom.samr_pol_open_domain, switch_value) : False;
+
+ res = res ? do_samr_close(smb_cli,
+ &info->dom.samr_pol_connect) : False;
+
+ res = res ? do_samr_close(smb_cli,
+ &info->dom.samr_pol_open_domain) : False;
+
+ /* close the session */
+ cli_nt_session_close(smb_cli);
+
+ if (res)
+ {
+ DEBUG(5,("cmd_sam_query_groups: succeeded\n"));
+ }
+ else
+ {
+ DEBUG(5,("cmd_sam_query_groups: failed\n"));
+ }
+}
+
+
+/****************************************************************************
+experimental SAM aliases query.
+****************************************************************************/
+void cmd_sam_enum_aliases(struct client_info *info)
+{
+ fstring srv_name;
+ fstring domain;
+ fstring sid;
+ DOM_SID sid1;
+ BOOL res = True;
+ BOOL request_user_info = False;
+ BOOL request_alias_info = False;
+ uint32 admin_rid = 0x304; /* absolutely no idea. */
+ fstring tmp;
+
+ uint32 num_aliases = 3;
+ uint32 alias_rid[3] = { DOMAIN_GROUP_RID_ADMINS, DOMAIN_GROUP_RID_USERS, DOMAIN_GROUP_RID_GUESTS };
+ fstring alias_names [3];
+ uint32 num_als_usrs[3];
+
+ sid_to_string(sid, &info->dom.level3_sid);
+ fstrcpy(domain, info->dom.level3_dom);
+#if 0
+ fstrcpy(sid , "S-1-5-20");
+#endif
+ if (strlen(sid) == 0)
+ {
+ fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+ return;
+ }
+
+ make_dom_sid(&sid1, sid);
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ /* a bad way to do token parsing... */
+ if (next_token(NULL, tmp, NULL, sizeof(tmp)))
+ {
+ request_user_info |= strequal(tmp, "-u");
+ request_alias_info |= strequal(tmp, "-g");
+ }
+
+ if (next_token(NULL, tmp, NULL, sizeof(tmp)))
+ {
+ request_user_info |= strequal(tmp, "-u");
+ request_alias_info |= strequal(tmp, "-g");
+ }
+
+ fprintf(out_hnd, "SAM Enumerate Aliases\n");
+ fprintf(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
+ info->myhostname, srv_name, domain, sid);
+
+ /* open SAMR session. negotiate credentials */
+ res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
+
+ /* establish a connection. */
+ res = res ? do_samr_connect(smb_cli,
+ srv_name, 0x00000020,
+ &info->dom.samr_pol_connect) : False;
+
+ /* connect to the domain */
+ res = res ? do_samr_open_domain(smb_cli,
+ &info->dom.samr_pol_connect, admin_rid, &sid1,
+ &info->dom.samr_pol_open_domain) : False;
+
+ /* send a query on the aliase */
+ res = res ? do_samr_query_unknown_12(smb_cli,
+ &info->dom.samr_pol_open_domain, admin_rid, num_aliases, alias_rid,
+ &num_aliases, alias_names, num_als_usrs) : False;
+
+ if (res)
+ {
+ display_alias_name_info(out_hnd, ACTION_HEADER , num_aliases, alias_names, num_als_usrs);
+ display_alias_name_info(out_hnd, ACTION_ENUMERATE, num_aliases, alias_names, num_als_usrs);
+ display_alias_name_info(out_hnd, ACTION_FOOTER , num_aliases, alias_names, num_als_usrs);
+ }
+
+#if 0
+
+ /* read some users */
+ res = res ? do_samr_enum_dom_users(smb_cli,
+ &info->dom.samr_pol_open_domain,
+ num_entries, unk_0, acb_mask, unk_1, 0xffff,
+ info->dom.sam, &info->dom.num_sam_entries) : False;
+
+ if (res && info->dom.num_sam_entries == 0)
+ {
+ fprintf(out_hnd, "No users\n");
+ }
+
+ if (request_user_info || request_alias_info)
+ {
+ /* query all the users */
+ user_idx = 0;
+
+ while (res && user_idx < info->dom.num_sam_entries)
+ {
+ uint32 user_rid = info->dom.sam[user_idx].smb_userid;
+ SAM_USER_INFO_21 usr;
+
+ fprintf(out_hnd, "User RID: %8x User Name: %s\n",
+ user_rid,
+ info->dom.sam[user_idx].acct_name);
+
+ if (request_user_info)
+ {
+ /* send user info query, level 0x15 */
+ if (get_samr_query_userinfo(smb_cli,
+ &info->dom.samr_pol_open_domain,
+ 0x15, user_rid, &usr))
+ {
+ display_sam_user_info_21(out_hnd, ACTION_HEADER , &usr);
+ display_sam_user_info_21(out_hnd, ACTION_ENUMERATE, &usr);
+ display_sam_user_info_21(out_hnd, ACTION_FOOTER , &usr);
+ }
+ }
+
+ if (request_alias_info)
+ {
+ uint32 num_aliases;
+ DOM_GID gid[LSA_MAX_GROUPS];
+
+ /* send user aliase query */
+ if (get_samr_query_useraliases(smb_cli,
+ &info->dom.samr_pol_open_domain,
+ user_rid, &num_aliases, gid))
+ {
+ display_alias_info(out_hnd, ACTION_HEADER , num_aliases, gid);
+ display_alias_info(out_hnd, ACTION_ENUMERATE, num_aliases, gid);
+ display_alias_info(out_hnd, ACTION_FOOTER , num_aliases, gid);
+ }
+ }
+
+ user_idx++;
+ }
+ }
+#endif
+
+ res = res ? do_samr_close(smb_cli,
+ &info->dom.samr_pol_connect) : False;
+
+ res = res ? do_samr_close(smb_cli,
+ &info->dom.samr_pol_open_domain) : False;
+
+ /* close the session */
+ cli_nt_session_close(smb_cli);
+
+ if (res)
+ {
+ DEBUG(5,("cmd_sam_enum_users: succeeded\n"));
+ }
+ else
+ {
+ DEBUG(5,("cmd_sam_enum_users: failed\n"));
+ }
+}
+
+
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* removed in SAMBA_2_0 branch. */
+
+
+#ifdef SYSLOG
+#undef SYSLOG
+#endif
+
+#include "includes.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+
+#define DEBUG_TESTING
+
+extern struct cli_state *smb_cli;
+
+extern FILE* out_hnd;
+
+
+/****************************************************************************
+server get info query
+****************************************************************************/
+void cmd_srv_query_info(struct client_info *info)
+{
+ fstring dest_srv;
+ fstring tmp;
+ SRV_INFO_CTR ctr;
+ uint32 info_level = 101;
+
+ BOOL res = True;
+
+ memset((char *)&ctr, '\0', sizeof(ctr));
+
+ fstrcpy(dest_srv, "\\\\");
+ fstrcat(dest_srv, info->dest_host);
+ strupper(dest_srv);
+
+ if (next_token(NULL, tmp, NULL, sizeof(tmp)-1))
+ {
+ info_level = (uint32)strtol(tmp, (char**)NULL, 10);
+ }
+
+ DEBUG(4,("cmd_srv_query_info: server:%s info level: %d\n",
+ dest_srv, (int)info_level));
+
+ DEBUG(5, ("cmd_srv_query_info: smb_cli->fd:%d\n", smb_cli->fd));
+
+ /* open LSARPC session. */
+ res = res ? cli_nt_session_open(smb_cli, PIPE_SRVSVC) : False;
+
+ /* send info level: receive requested info. hopefully. */
+ res = res ? do_srv_net_srv_get_info(smb_cli,
+ dest_srv, info_level, &ctr) : False;
+
+ /* close the session */
+ cli_nt_session_close(smb_cli);
+
+ if (res)
+ {
+ DEBUG(5,("cmd_srv_query_info: query succeeded\n"));
+
+ display_srv_info_ctr(out_hnd, ACTION_HEADER , &ctr);
+ display_srv_info_ctr(out_hnd, ACTION_ENUMERATE, &ctr);
+ display_srv_info_ctr(out_hnd, ACTION_FOOTER , &ctr);
+ }
+ else
+ {
+ DEBUG(5,("cmd_srv_query_info: query failed\n"));
+ }
+}
+
+/****************************************************************************
+server enum connections
+****************************************************************************/
+void cmd_srv_enum_conn(struct client_info *info)
+{
+ fstring dest_srv;
+ fstring qual_srv;
+ fstring tmp;
+ SRV_CONN_INFO_CTR ctr;
+ ENUM_HND hnd;
+ uint32 info_level = 0;
+
+ BOOL res = True;
+
+ memset((char *)&ctr, '\0', sizeof(ctr));
+
+ fstrcpy(qual_srv, "\\\\");
+ fstrcat(qual_srv, info->myhostname);
+ strupper(qual_srv);
+
+ fstrcpy(dest_srv, "\\\\");
+ fstrcat(dest_srv, info->dest_host);
+ strupper(dest_srv);
+
+ if (next_token(NULL, tmp, NULL, sizeof(tmp)-1))
+ {
+ info_level = (uint32)strtol(tmp, (char**)NULL, 10);
+ }
+
+ DEBUG(4,("cmd_srv_enum_conn: server:%s info level: %d\n",
+ dest_srv, (int)info_level));
+
+ DEBUG(5, ("cmd_srv_enum_conn: smb_cli->fd:%d\n", smb_cli->fd));
+
+ /* open srvsvc session. */
+ res = res ? cli_nt_session_open(smb_cli, PIPE_SRVSVC) : False;
+
+ hnd.ptr_hnd = 1;
+ hnd.handle = 0;
+
+ /* enumerate connections on server */
+ res = res ? do_srv_net_srv_conn_enum(smb_cli,
+ dest_srv, qual_srv,
+ info_level, &ctr, 0xffffffff, &hnd) : False;
+
+ if (res)
+ {
+ display_srv_conn_info_ctr(out_hnd, ACTION_HEADER , &ctr);
+ display_srv_conn_info_ctr(out_hnd, ACTION_ENUMERATE, &ctr);
+ display_srv_conn_info_ctr(out_hnd, ACTION_FOOTER , &ctr);
+ }
+
+ /* close the session */
+ cli_nt_session_close(smb_cli);
+
+ if (res)
+ {
+ DEBUG(5,("cmd_srv_enum_conn: query succeeded\n"));
+ }
+ else
+ {
+ DEBUG(5,("cmd_srv_enum_conn: query failed\n"));
+ }
+}
+
+/****************************************************************************
+server enum shares
+****************************************************************************/
+void cmd_srv_enum_shares(struct client_info *info)
+{
+ fstring dest_srv;
+ fstring tmp;
+ SRV_SHARE_INFO_CTR ctr;
+ ENUM_HND hnd;
+ uint32 info_level = 1;
+
+ BOOL res = True;
+
+ memset((char *)&ctr, '\0', sizeof(ctr));
+
+ fstrcpy(dest_srv, "\\\\");
+ fstrcat(dest_srv, info->dest_host);
+ strupper(dest_srv);
+
+ if (next_token(NULL, tmp, NULL, sizeof(tmp)-1))
+ {
+ info_level = (uint32)strtol(tmp, (char**)NULL, 10);
+ }
+
+ DEBUG(4,("cmd_srv_enum_shares: server:%s info level: %d\n",
+ dest_srv, (int)info_level));
+
+ DEBUG(5, ("cmd_srv_enum_shares: smb_cli->fd:%d\n", smb_cli->fd));
+
+ /* open srvsvc session. */
+ res = res ? cli_nt_session_open(smb_cli, PIPE_SRVSVC) : False;
+
+ hnd.ptr_hnd = 0;
+ hnd.handle = 0;
+
+ /* enumerate shares_files on server */
+ res = res ? do_srv_net_srv_share_enum(smb_cli,
+ dest_srv,
+ info_level, &ctr, 0xffffffff, &hnd) : False;
+
+ if (res)
+ {
+ display_srv_share_info_ctr(out_hnd, ACTION_HEADER , &ctr);
+ display_srv_share_info_ctr(out_hnd, ACTION_ENUMERATE, &ctr);
+ display_srv_share_info_ctr(out_hnd, ACTION_FOOTER , &ctr);
+ }
+
+ /* close the session */
+ cli_nt_session_close(smb_cli);
+
+ if (res)
+ {
+ DEBUG(5,("cmd_srv_enum_shares: query succeeded\n"));
+ }
+ else
+ {
+ DEBUG(5,("cmd_srv_enum_shares: query failed\n"));
+ }
+}
+
+/****************************************************************************
+server enum sessions
+****************************************************************************/
+void cmd_srv_enum_sess(struct client_info *info)
+{
+ fstring dest_srv;
+ fstring tmp;
+ SRV_SESS_INFO_CTR ctr;
+ ENUM_HND hnd;
+ uint32 info_level = 0;
+
+ BOOL res = True;
+
+ memset((char *)&ctr, '\0', sizeof(ctr));
+
+ fstrcpy(dest_srv, "\\\\");
+ fstrcat(dest_srv, info->dest_host);
+ strupper(dest_srv);
+
+ if (next_token(NULL, tmp, NULL, sizeof(tmp)-1))
+ {
+ info_level = (uint32)strtol(tmp, (char**)NULL, 10);
+ }
+
+ DEBUG(4,("cmd_srv_enum_sess: server:%s info level: %d\n",
+ dest_srv, (int)info_level));
+
+ DEBUG(5, ("cmd_srv_enum_sess: smb_cli->fd:%d\n", smb_cli->fd));
+
+ /* open srvsvc session. */
+ res = res ? cli_nt_session_open(smb_cli, PIPE_SRVSVC) : False;
+
+ hnd.ptr_hnd = 1;
+ hnd.handle = 0;
+
+ /* enumerate sessions on server */
+ res = res ? do_srv_net_srv_sess_enum(smb_cli,
+ dest_srv, NULL, info_level, &ctr, 0x1000, &hnd) : False;
+
+ /* close the session */
+ cli_nt_session_close(smb_cli);
+
+ if (res)
+ {
+ DEBUG(5,("cmd_srv_enum_sess: query succeeded\n"));
+ }
+ else
+ {
+ DEBUG(5,("cmd_srv_enum_sess: query failed\n"));
+ }
+}
+
+/****************************************************************************
+server enum files
+****************************************************************************/
+void cmd_srv_enum_files(struct client_info *info)
+{
+ fstring dest_srv;
+ fstring tmp;
+ SRV_FILE_INFO_CTR ctr;
+ ENUM_HND hnd;
+ uint32 info_level = 3;
+
+ BOOL res = True;
+
+ memset((char *)&ctr, '\0', sizeof(ctr));
+
+ fstrcpy(dest_srv, "\\\\");
+ fstrcat(dest_srv, info->dest_host);
+ strupper(dest_srv);
+
+ if (next_token(NULL, tmp, NULL, sizeof(tmp)-1))
+ {
+ info_level = (uint32)strtol(tmp, (char**)NULL, 10);
+ }
+
+ DEBUG(4,("cmd_srv_enum_files: server:%s info level: %d\n",
+ dest_srv, (int)info_level));
+
+ DEBUG(5, ("cmd_srv_enum_files: smb_cli->fd:%d\n", smb_cli->fd));
+
+ /* open srvsvc session. */
+ res = res ? cli_nt_session_open(smb_cli, PIPE_SRVSVC) : False;
+
+ hnd.ptr_hnd = 1;
+ hnd.handle = 0;
+
+ /* enumerate files on server */
+ res = res ? do_srv_net_srv_file_enum(smb_cli,
+ dest_srv, NULL, info_level, &ctr, 0x1000, &hnd) : False;
+
+ if (res)
+ {
+ display_srv_file_info_ctr(out_hnd, ACTION_HEADER , &ctr);
+ display_srv_file_info_ctr(out_hnd, ACTION_ENUMERATE, &ctr);
+ display_srv_file_info_ctr(out_hnd, ACTION_FOOTER , &ctr);
+ }
+
+ /* close the session */
+ cli_nt_session_close(smb_cli);
+
+ if (res)
+ {
+ DEBUG(5,("cmd_srv_enum_files: query succeeded\n"));
+ }
+ else
+ {
+ DEBUG(5,("cmd_srv_enum_files: query failed\n"));
+ }
+}
+
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* removed in SAMBA_2_0 branch. */
+
+
+#ifdef SYSLOG
+#undef SYSLOG
+#endif
+
+#include "includes.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+
+#define DEBUG_TESTING
+
+extern struct cli_state *smb_cli;
+
+extern FILE* out_hnd;
+
+
+/****************************************************************************
+workstation get info query
+****************************************************************************/
+void cmd_wks_query_info(struct client_info *info)
+{
+ fstring dest_wks;
+ fstring tmp;
+ WKS_INFO_100 ctr;
+ uint32 info_level = 100;
+
+ BOOL res = True;
+
+ memset((char *)&ctr, '\0', sizeof(ctr));
+
+ fstrcpy(dest_wks, "\\\\");
+ fstrcat(dest_wks, info->dest_host);
+ strupper(dest_wks);
+
+ if (next_token(NULL, tmp, NULL, sizeof(tmp)))
+ {
+ info_level = (uint32)strtol(tmp, (char**)NULL, 10);
+ }
+
+ DEBUG(4,("cmd_wks_query_info: server:%s info level: %d\n",
+ dest_wks, info_level));
+
+ DEBUG(5, ("cmd_wks_query_info: smb_cli->fd:%d\n", smb_cli->fd));
+
+ /* open LSARPC session. */
+ res = res ? cli_nt_session_open(smb_cli, PIPE_WKSSVC) : False;
+
+ /* send info level: receive requested info. hopefully. */
+ res = res ? do_wks_query_info(smb_cli,
+ dest_wks, info_level, &ctr) : False;
+
+ /* close the session */
+ cli_nt_session_close(smb_cli);
+
+ if (res)
+ {
+ DEBUG(5,("cmd_wks_query_info: query succeeded\n"));
+
+#if 0
+ display_wks_info_100(out_hnd, ACTION_HEADER , &ctr);
+ display_wks_info_100(out_hnd, ACTION_ENUMERATE, &ctr);
+ display_wks_info_100(out_hnd, ACTION_FOOTER , &ctr);
+#endif
+
+ }
+ else
+ {
+ DEBUG(5,("cmd_wks_query_info: query failed\n"));
+ }
+}
+
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* removed in SAMBA_2_0 branch. */
+#include "includes.h"
+
+
+/****************************************************************************
+convert a share mode to a string
+****************************************************************************/
+char *get_file_mode_str(uint32 share_mode)
+{
+ static fstring mode;
+
+ switch ((share_mode>>4)&0xF)
+ {
+ case DENY_NONE : fstrcpy(mode, "DENY_NONE "); break;
+ case DENY_ALL : fstrcpy(mode, "DENY_ALL "); break;
+ case DENY_DOS : fstrcpy(mode, "DENY_DOS "); break;
+ case DENY_READ : fstrcpy(mode, "DENY_READ "); break;
+ case DENY_WRITE: fstrcpy(mode, "DENY_WRITE "); break;
+ default : fstrcpy(mode, "DENY_???? "); break;
+ }
+
+ switch (share_mode & 0xF)
+ {
+ case 0 : fstrcat(mode, "RDONLY"); break;
+ case 1 : fstrcat(mode, "WRONLY"); break;
+ case 2 : fstrcat(mode, "RDWR "); break;
+ default: fstrcat(mode, "R??W??"); break;
+ }
+
+ return mode;
+}
+
+/****************************************************************************
+convert an oplock mode to a string
+****************************************************************************/
+char *get_file_oplock_str(uint32 op_type)
+{
+ static fstring oplock;
+ BOOL excl = IS_BITS_SET_ALL(op_type, EXCLUSIVE_OPLOCK);
+ BOOL batch = IS_BITS_SET_ALL(op_type, BATCH_OPLOCK );
+
+ oplock[0] = 0;
+
+ if (excl ) fstrcat(oplock, "EXCLUSIVE");
+ if (excl && batch) fstrcat(oplock, "+");
+ if ( batch) fstrcat(oplock, "BATCH");
+ if (!excl && !batch) fstrcat(oplock, "NONE");
+
+ return oplock;
+}
+
+/****************************************************************************
+convert a share type enum to a string
+****************************************************************************/
+char *get_share_type_str(uint32 type)
+{
+ static fstring typestr;
+
+ switch (type)
+ {
+ case STYPE_DISKTREE: fstrcpy(typestr, "Disk" ); break;
+ case STYPE_PRINTQ : fstrcpy(typestr, "Printer"); break;
+ case STYPE_DEVICE : fstrcpy(typestr, "Device" ); break;
+ case STYPE_IPC : fstrcpy(typestr, "IPC" ); break;
+ default : fstrcpy(typestr, "????" ); break;
+ }
+ return typestr;
+}
+
+/****************************************************************************
+convert a server type enum to a string
+****************************************************************************/
+char *get_server_type_str(uint32 type)
+{
+ static fstring typestr;
+
+ if (type == SV_TYPE_ALL)
+ {
+ fstrcpy(typestr, "All");
+ }
+ else
+ {
+ int i;
+ typestr[0] = 0;
+ for (i = 0; i < 32; i++)
+ {
+ if (IS_BITS_SET_ALL(type, 1 << i))
+ {
+ switch (1 << i)
+ {
+ case SV_TYPE_WORKSTATION : fstrcat(typestr, "Wk " ); break;
+ case SV_TYPE_SERVER : fstrcat(typestr, "Sv " ); break;
+ case SV_TYPE_SQLSERVER : fstrcat(typestr, "Sql "); break;
+ case SV_TYPE_DOMAIN_CTRL : fstrcat(typestr, "PDC "); break;
+ case SV_TYPE_DOMAIN_BAKCTRL : fstrcat(typestr, "BDC "); break;
+ case SV_TYPE_TIME_SOURCE : fstrcat(typestr, "Tim "); break;
+ case SV_TYPE_AFP : fstrcat(typestr, "AFP "); break;
+ case SV_TYPE_NOVELL : fstrcat(typestr, "Nov "); break;
+ case SV_TYPE_DOMAIN_MEMBER : fstrcat(typestr, "Dom "); break;
+ case SV_TYPE_PRINTQ_SERVER : fstrcat(typestr, "PrQ "); break;
+ case SV_TYPE_DIALIN_SERVER : fstrcat(typestr, "Din "); break;
+ case SV_TYPE_SERVER_UNIX : fstrcat(typestr, "Unx "); break;
+ case SV_TYPE_NT : fstrcat(typestr, "NT " ); break;
+ case SV_TYPE_WFW : fstrcat(typestr, "Wfw "); break;
+ case SV_TYPE_SERVER_MFPN : fstrcat(typestr, "Mfp "); break;
+ case SV_TYPE_SERVER_NT : fstrcat(typestr, "SNT "); break;
+ case SV_TYPE_POTENTIAL_BROWSER: fstrcat(typestr, "PtB "); break;
+ case SV_TYPE_BACKUP_BROWSER : fstrcat(typestr, "BMB "); break;
+ case SV_TYPE_MASTER_BROWSER : fstrcat(typestr, "LMB "); break;
+ case SV_TYPE_DOMAIN_MASTER : fstrcat(typestr, "DMB "); break;
+ case SV_TYPE_SERVER_OSF : fstrcat(typestr, "OSF "); break;
+ case SV_TYPE_SERVER_VMS : fstrcat(typestr, "VMS "); break;
+ case SV_TYPE_WIN95_PLUS : fstrcat(typestr, "W95 "); break;
+ case SV_TYPE_ALTERNATE_XPORT : fstrcat(typestr, "Xpt "); break;
+ case SV_TYPE_LOCAL_LIST_ONLY : fstrcat(typestr, "Dom "); break;
+ case SV_TYPE_DOMAIN_ENUM : fstrcat(typestr, "Loc "); break;
+ }
+ }
+ }
+ i = strlen(typestr)-1;
+ if (typestr[i] == ' ') typestr[i] = 0;
+
+ }
+ return typestr;
+}
+
+/****************************************************************************
+server info level 101 display function
+****************************************************************************/
+void display_srv_info_101(FILE *out_hnd, enum action_type action,
+ SRV_INFO_101 *sv101)
+{
+ if (sv101 == NULL)
+ {
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ fprintf(out_hnd, "Server Info Level 101:\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring name;
+ fstring comment;
+
+ fstrcpy(name , unistrn2(sv101->uni_name .buffer, sv101->uni_name .uni_str_len));
+ fstrcpy(comment , unistrn2(sv101->uni_comment .buffer, sv101->uni_comment .uni_str_len));
+
+ display_server(out_hnd, action, name, sv101->srv_type, comment);
+
+ fprintf(out_hnd, "\tplatform_id : %d\n" , sv101->platform_id);
+ fprintf(out_hnd, "\tos version : %d.%d\n" , sv101->ver_major, sv101->ver_minor);
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+
+}
+
+/****************************************************************************
+server info level 102 display function
+****************************************************************************/
+void display_srv_info_102(FILE *out_hnd, enum action_type action,SRV_INFO_102 *sv102)
+{
+ if (sv102 == NULL)
+ {
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ fprintf(out_hnd, "Server Info Level 102:\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring name;
+ fstring comment;
+ fstring usr_path;
+
+ fstrcpy(name , unistrn2(sv102->uni_name .buffer, sv102->uni_name .uni_str_len));
+ fstrcpy(comment , unistrn2(sv102->uni_comment .buffer, sv102->uni_comment .uni_str_len));
+ fstrcpy(usr_path, unistrn2(sv102->uni_usr_path.buffer, sv102->uni_usr_path.uni_str_len));
+
+ display_server(out_hnd, action, name, sv102->srv_type, comment);
+
+ fprintf(out_hnd, "\tplatform_id : %d\n" , sv102->platform_id);
+ fprintf(out_hnd, "\tos version : %d.%d\n" , sv102->ver_major, sv102->ver_minor);
+
+ fprintf(out_hnd, "\tusers : %x\n" , sv102->users );
+ fprintf(out_hnd, "\tdisc, hidden : %x,%x\n" , sv102->disc , sv102->hidden );
+ fprintf(out_hnd, "\tannounce, delta : %d, %d\n", sv102->announce , sv102->ann_delta);
+ fprintf(out_hnd, "\tlicenses : %d\n" , sv102->licenses );
+ fprintf(out_hnd, "\tuser path : %s\n" , usr_path);
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+server info container display function
+****************************************************************************/
+void display_srv_info_ctr(FILE *out_hnd, enum action_type action,SRV_INFO_CTR *ctr)
+{
+ if (ctr == NULL || ctr->ptr_srv_ctr == 0)
+ {
+ fprintf(out_hnd, "Server Information: unavailable due to an error\n");
+ return;
+ }
+
+ switch (ctr->switch_value)
+ {
+ case 101:
+ {
+ display_srv_info_101(out_hnd, action, &(ctr->srv.sv101));
+ break;
+ }
+ case 102:
+ {
+ display_srv_info_102(out_hnd, action, &(ctr->srv.sv102));
+ break;
+ }
+ default:
+ {
+ fprintf(out_hnd, "Server Information: Unknown Info Level\n");
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+connection info level 0 display function
+****************************************************************************/
+void display_conn_info_0(FILE *out_hnd, enum action_type action,
+ CONN_INFO_0 *info0)
+{
+ if (info0 == NULL)
+ {
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ fprintf(out_hnd, "Connection Info Level 0:\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fprintf(out_hnd, "\tid: %d\n", info0->id);
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ fprintf(out_hnd, "\n");
+ break;
+ }
+ }
+
+}
+
+/****************************************************************************
+connection info level 1 display function
+****************************************************************************/
+void display_conn_info_1(FILE *out_hnd, enum action_type action,
+ CONN_INFO_1 *info1, CONN_INFO_1_STR *str1)
+{
+ if (info1 == NULL || str1 == NULL)
+ {
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ fprintf(out_hnd, "Connection Info Level 1:\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring usr_name;
+ fstring net_name;
+
+ fstrcpy(usr_name, unistrn2(str1->uni_usr_name.buffer, str1->uni_usr_name.uni_str_len));
+ fstrcpy(net_name, unistrn2(str1->uni_net_name.buffer, str1->uni_net_name.uni_str_len));
+
+ fprintf(out_hnd, "\tid : %d\n", info1->id);
+ fprintf(out_hnd, "\ttype : %s\n", get_share_type_str(info1->type));
+ fprintf(out_hnd, "\tnum_opens: %d\n", info1->num_opens);
+ fprintf(out_hnd, "\tnum_users: %d\n", info1->num_users);
+ fprintf(out_hnd, "\topen_time: %d\n", info1->open_time);
+
+ fprintf(out_hnd, "\tuser name: %s\n", usr_name);
+ fprintf(out_hnd, "\tnet name: %s\n", net_name);
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ fprintf(out_hnd, "\n");
+ break;
+ }
+ }
+
+}
+
+/****************************************************************************
+connection info level 0 container display function
+****************************************************************************/
+void display_srv_conn_info_0_ctr(FILE *out_hnd, enum action_type action,
+ SRV_CONN_INFO_0 *ctr)
+{
+ if (ctr == NULL)
+ {
+ fprintf(out_hnd, "display_srv_conn_info_0_ctr: unavailable due to an internal error\n");
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ int i;
+
+ for (i = 0; i < ctr->num_entries_read; i++)
+ {
+ display_conn_info_0(out_hnd, ACTION_HEADER , &(ctr->info_0[i]));
+ display_conn_info_0(out_hnd, ACTION_ENUMERATE, &(ctr->info_0[i]));
+ display_conn_info_0(out_hnd, ACTION_FOOTER , &(ctr->info_0[i]));
+ }
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+connection info level 1 container display function
+****************************************************************************/
+void display_srv_conn_info_1_ctr(FILE *out_hnd, enum action_type action,
+ SRV_CONN_INFO_1 *ctr)
+{
+ if (ctr == NULL)
+ {
+ fprintf(out_hnd, "display_srv_conn_info_1_ctr: unavailable due to an internal error\n");
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ int i;
+
+ for (i = 0; i < ctr->num_entries_read; i++)
+ {
+ display_conn_info_1(out_hnd, ACTION_HEADER , &(ctr->info_1[i]), &(ctr->info_1_str[i]));
+ display_conn_info_1(out_hnd, ACTION_ENUMERATE, &(ctr->info_1[i]), &(ctr->info_1_str[i]));
+ display_conn_info_1(out_hnd, ACTION_FOOTER , &(ctr->info_1[i]), &(ctr->info_1_str[i]));
+ }
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+connection info container display function
+****************************************************************************/
+void display_srv_conn_info_ctr(FILE *out_hnd, enum action_type action,
+ SRV_CONN_INFO_CTR *ctr)
+{
+ if (ctr == NULL || ctr->ptr_conn_ctr == 0)
+ {
+ fprintf(out_hnd, "display_srv_conn_info_ctr: unavailable due to an internal error\n");
+ return;
+ }
+
+ switch (ctr->switch_value)
+ {
+ case 0:
+ {
+ display_srv_conn_info_0_ctr(out_hnd, action,
+ &(ctr->conn.info0));
+ break;
+ }
+ case 1:
+ {
+ display_srv_conn_info_1_ctr(out_hnd, action,
+ &(ctr->conn.info1));
+ break;
+ }
+ default:
+ {
+ fprintf(out_hnd, "display_srv_conn_info_ctr: Unknown Info Level\n");
+ break;
+ }
+ }
+}
+
+
+/****************************************************************************
+share info level 1 display function
+****************************************************************************/
+void display_share_info_1(FILE *out_hnd, enum action_type action,
+ SH_INFO_1 *info1, SH_INFO_1_STR *str1)
+{
+ if (info1 == NULL || str1 == NULL)
+ {
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ fprintf(out_hnd, "Share Info Level 1:\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring remark ;
+ fstring net_name;
+
+ fstrcpy(net_name, unistrn2(str1->uni_netname.buffer, str1->uni_netname.uni_str_len));
+ fstrcpy(remark , unistrn2(str1->uni_remark .buffer, str1->uni_remark .uni_str_len));
+
+ display_share(out_hnd, action, net_name, info1->type, remark);
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ fprintf(out_hnd, "\n");
+ break;
+ }
+ }
+
+}
+
+/****************************************************************************
+share info level 2 display function
+****************************************************************************/
+void display_share_info_2(FILE *out_hnd, enum action_type action,
+ SH_INFO_2 *info2, SH_INFO_2_STR *str2)
+{
+ if (info2 == NULL || str2 == NULL)
+ {
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ fprintf(out_hnd, "Share Info Level 2:\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring remark ;
+ fstring net_name;
+ fstring path ;
+ fstring passwd ;
+
+ fstrcpy(net_name, unistrn2(str2->uni_netname.buffer, str2->uni_netname.uni_str_len));
+ fstrcpy(remark , unistrn2(str2->uni_remark .buffer, str2->uni_remark .uni_str_len));
+ fstrcpy(path , unistrn2(str2->uni_path .buffer, str2->uni_path .uni_str_len));
+ fstrcpy(passwd , unistrn2(str2->uni_passwd .buffer, str2->uni_passwd .uni_str_len));
+
+ display_share2(out_hnd, action, net_name, info2->type, remark,
+ info2->perms, info2->max_uses, info2->num_uses,
+ path, passwd);
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ fprintf(out_hnd, "\n");
+ break;
+ }
+ }
+
+}
+
+/****************************************************************************
+share info level 1 container display function
+****************************************************************************/
+void display_srv_share_info_1_ctr(FILE *out_hnd, enum action_type action,
+ SRV_SHARE_INFO_1 *ctr)
+{
+ if (ctr == NULL)
+ {
+ fprintf(out_hnd, "display_srv_share_info_1_ctr: unavailable due to an internal error\n");
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ int i;
+
+ for (i = 0; i < ctr->num_entries_read; i++)
+ {
+ display_share_info_1(out_hnd, ACTION_HEADER , &(ctr->info_1[i]), &(ctr->info_1_str[i]));
+ display_share_info_1(out_hnd, ACTION_ENUMERATE, &(ctr->info_1[i]), &(ctr->info_1_str[i]));
+ display_share_info_1(out_hnd, ACTION_FOOTER , &(ctr->info_1[i]), &(ctr->info_1_str[i]));
+ }
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+share info level 2 container display function
+****************************************************************************/
+void display_srv_share_info_2_ctr(FILE *out_hnd, enum action_type action,
+ SRV_SHARE_INFO_2 *ctr)
+{
+ if (ctr == NULL)
+ {
+ fprintf(out_hnd, "display_srv_share_info_2_ctr: unavailable due to an internal error\n");
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ int i;
+
+ for (i = 0; i < ctr->num_entries_read; i++)
+ {
+ display_share_info_2(out_hnd, ACTION_HEADER , &(ctr->info_2[i]), &(ctr->info_2_str[i]));
+ display_share_info_2(out_hnd, ACTION_ENUMERATE, &(ctr->info_2[i]), &(ctr->info_2_str[i]));
+ display_share_info_2(out_hnd, ACTION_FOOTER , &(ctr->info_2[i]), &(ctr->info_2_str[i]));
+ }
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+share info container display function
+****************************************************************************/
+void display_srv_share_info_ctr(FILE *out_hnd, enum action_type action,
+ SRV_SHARE_INFO_CTR *ctr)
+{
+ if (ctr == NULL || ctr->ptr_share_ctr == 0)
+ {
+ fprintf(out_hnd, "display_srv_share_info_ctr: unavailable due to an internal error\n");
+ return;
+ }
+
+ switch (ctr->switch_value)
+ {
+ case 1:
+ {
+ display_srv_share_info_1_ctr(out_hnd, action,
+ &(ctr->share.info1));
+ break;
+ }
+ case 2:
+ {
+ display_srv_share_info_2_ctr(out_hnd, action,
+ &(ctr->share.info2));
+ break;
+ }
+ default:
+ {
+ fprintf(out_hnd, "display_srv_share_info_ctr: Unknown Info Level\n");
+ break;
+ }
+ }
+}
+
+
+/****************************************************************************
+file info level 3 display function
+****************************************************************************/
+void display_file_info_3(FILE *out_hnd, enum action_type action,
+ FILE_INFO_3 *info3, FILE_INFO_3_STR *str3)
+{
+ if (info3 == NULL || str3 == NULL)
+ {
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ fprintf(out_hnd, "File Info Level 3:\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring path_name;
+ fstring user_name;
+
+ fstrcpy(path_name, unistrn2(str3->uni_path_name.buffer, str3->uni_path_name.uni_str_len));
+ fstrcpy(user_name, unistrn2(str3->uni_user_name.buffer, str3->uni_user_name.uni_str_len));
+
+ fprintf(out_hnd, "\tid : %d\n", info3->id);
+ fprintf(out_hnd, "\tperms : %s\n", get_file_mode_str(info3->perms));
+ fprintf(out_hnd, "\tnum_locks: %d\n", info3->num_locks);
+
+ fprintf(out_hnd, "\tpath name: %s\n", path_name);
+ fprintf(out_hnd, "\tuser name: %s\n", user_name);
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ fprintf(out_hnd, "\n");
+ break;
+ }
+ }
+
+}
+
+/****************************************************************************
+file info level 3 container display function
+****************************************************************************/
+void display_srv_file_info_3_ctr(FILE *out_hnd, enum action_type action,
+ SRV_FILE_INFO_3 *ctr)
+{
+ if (ctr == NULL)
+ {
+ fprintf(out_hnd, "display_srv_file_info_3_ctr: unavailable due to an internal error\n");
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ int i;
+
+ for (i = 0; i < ctr->num_entries_read; i++)
+ {
+ display_file_info_3(out_hnd, ACTION_HEADER , &(ctr->info_3[i]), &(ctr->info_3_str[i]));
+ display_file_info_3(out_hnd, ACTION_ENUMERATE, &(ctr->info_3[i]), &(ctr->info_3_str[i]));
+ display_file_info_3(out_hnd, ACTION_FOOTER , &(ctr->info_3[i]), &(ctr->info_3_str[i]));
+ }
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+file info container display function
+****************************************************************************/
+void display_srv_file_info_ctr(FILE *out_hnd, enum action_type action,
+ SRV_FILE_INFO_CTR *ctr)
+{
+ if (ctr == NULL || ctr->ptr_file_ctr == 0)
+ {
+ fprintf(out_hnd, "display_srv_file_info_ctr: unavailable due to an internal error\n");
+ return;
+ }
+
+ switch (ctr->switch_value)
+ {
+ case 3:
+ {
+ display_srv_file_info_3_ctr(out_hnd, action,
+ &(ctr->file.info3));
+ break;
+ }
+ default:
+ {
+ fprintf(out_hnd, "display_srv_file_info_ctr: Unknown Info Level\n");
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+ print browse connection on a host
+ ****************************************************************************/
+void display_server(FILE *out_hnd, enum action_type action,
+ char *sname, uint32 type, char *comment)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fprintf(out_hnd, "\t%-15.15s%-20s %s\n",
+ sname, get_server_type_str(type), comment);
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+print shares on a host
+****************************************************************************/
+void display_share(FILE *out_hnd, enum action_type action,
+ char *sname, uint32 type, char *comment)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fprintf(out_hnd, "\t%-15.15s%-10.10s%s\n",
+ sname, get_share_type_str(type), comment);
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+
+/****************************************************************************
+print shares on a host, level 2
+****************************************************************************/
+void display_share2(FILE *out_hnd, enum action_type action,
+ char *sname, uint32 type, char *comment,
+ uint32 perms, uint32 max_uses, uint32 num_uses,
+ char *path, char *passwd)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fprintf(out_hnd, "\t%-15.15s%-10.10s%s %x %x %x %s %s\n",
+ sname, get_share_type_str(type), comment,
+ perms, max_uses, num_uses, path, passwd);
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+
+/****************************************************************************
+print name info
+****************************************************************************/
+void display_name(FILE *out_hnd, enum action_type action,
+ char *sname)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fprintf(out_hnd, "\t%-21.21s\n", sname);
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+
+/****************************************************************************
+ display group rid info
+ ****************************************************************************/
+void display_group_rid_info(FILE *out_hnd, enum action_type action,
+ uint32 num_gids, DOM_GID *gid)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ if (num_gids == 0)
+ {
+ fprintf(out_hnd, "\tNo Groups\n");
+ }
+ else
+ {
+ fprintf(out_hnd, "\tGroup Info\n");
+ fprintf(out_hnd, "\t----------\n");
+ }
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ int i;
+
+ for (i = 0; i < num_gids; i++)
+ {
+ fprintf(out_hnd, "\tGroup RID: %8x attr: %x\n",
+ gid[i].g_rid, gid[i].attr);
+ }
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ fprintf(out_hnd, "\n");
+ break;
+ }
+ }
+}
+
+
+/****************************************************************************
+ display alias name info
+ ****************************************************************************/
+void display_alias_name_info(FILE *out_hnd, enum action_type action,
+ uint32 num_aliases, fstring *alias_name, uint32 *num_als_usrs)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ if (num_aliases == 0)
+ {
+ fprintf(out_hnd, "\tNo Aliases\n");
+ }
+ else
+ {
+ fprintf(out_hnd, "\tAlias Names\n");
+ fprintf(out_hnd, "\t----------- \n");
+ }
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ int i;
+
+ for (i = 0; i < num_aliases; i++)
+ {
+ fprintf(out_hnd, "\tAlias Name: %s Attributes: %3d\n",
+ alias_name[i], num_als_usrs[i]);
+ }
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ fprintf(out_hnd, "\n");
+ break;
+ }
+ }
+}
+
+
+/****************************************************************************
+ display sam_user_info_21 structure
+ ****************************************************************************/
+void display_sam_user_info_21(FILE *out_hnd, enum action_type action, SAM_USER_INFO_21 *usr)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ fprintf(out_hnd, "\tUser Info, Level 0x15\n");
+ fprintf(out_hnd, "\t---------------------\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fprintf(out_hnd, "\t\tUser Name : %s\n", unistrn2(usr->uni_user_name .buffer, usr->uni_user_name .uni_str_len)); /* username unicode string */
+ fprintf(out_hnd, "\t\tFull Name : %s\n", unistrn2(usr->uni_full_name .buffer, usr->uni_full_name .uni_str_len)); /* user's full name unicode string */
+ fprintf(out_hnd, "\t\tHome Drive : %s\n", unistrn2(usr->uni_home_dir .buffer, usr->uni_home_dir .uni_str_len)); /* home directory unicode string */
+ fprintf(out_hnd, "\t\tDir Drive : %s\n", unistrn2(usr->uni_dir_drive .buffer, usr->uni_dir_drive .uni_str_len)); /* home directory drive unicode string */
+ fprintf(out_hnd, "\t\tProfile Path: %s\n", unistrn2(usr->uni_profile_path.buffer, usr->uni_profile_path.uni_str_len)); /* profile path unicode string */
+ fprintf(out_hnd, "\t\tLogon Script: %s\n", unistrn2(usr->uni_logon_script.buffer, usr->uni_logon_script.uni_str_len)); /* logon script unicode string */
+ fprintf(out_hnd, "\t\tDescription : %s\n", unistrn2(usr->uni_acct_desc .buffer, usr->uni_acct_desc .uni_str_len)); /* user description unicode string */
+ fprintf(out_hnd, "\t\tWorkstations: %s\n", unistrn2(usr->uni_workstations.buffer, usr->uni_workstations.uni_str_len)); /* workstaions unicode string */
+ 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(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? */
+
+ fprintf(out_hnd, "\t\tuser_rid : %x\n" , usr->user_rid ); /* User ID */
+ fprintf(out_hnd, "\t\tgroup_rid: %x\n" , usr->group_rid); /* Group ID */
+ fprintf(out_hnd, "\t\tacb_info : %04x\n", usr->acb_info ); /* Account Control Info */
+
+ fprintf(out_hnd, "\t\tunknown_3: %08x\n", usr->unknown_3); /* 0x00ff ffff */
+ fprintf(out_hnd, "\t\tlogon_divs: %d\n", usr->logon_divs); /* 0x0000 00a8 which is 168 which is num hrs in a week */
+ fprintf(out_hnd, "\t\tunknown_5: %08x\n", usr->unknown_5); /* 0x0002 0000 */
+
+ fprintf(out_hnd, "\t\tpadding1[0..7]...\n");
+
+ if (usr->ptr_logon_hrs)
+ {
+ fprintf(out_hnd, "\t\tlogon_hrs[0..%d]...\n", usr->logon_hrs.len);
+ }
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ fprintf(out_hnd, "\n");
+ break;
+ }
+ }
+}
+
+
+/****************************************************************************
+convert a security permissions into a string
+****************************************************************************/
+char *get_sec_mask_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;
+ slprintf(tmp, sizeof(tmp)-1, "[%08x]", type);
+ fstrcat(typestr, tmp);
+ }
+
+ /* remove last space */
+ i = strlen(typestr)-1;
+ if (typestr[i] == ' ') typestr[i] = 0;
+
+ return typestr;
+}
+
+/****************************************************************************
+ display sec_access structure
+ ****************************************************************************/
+void display_sec_access(FILE *out_hnd, enum action_type action, SEC_ACCESS *info)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fprintf(out_hnd, "\t\tPermissions: %s\n",
+ get_sec_mask_str(info->mask));
+ }
+ 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_access(out_hnd, ACTION_HEADER , &ace->info);
+ display_sec_access(out_hnd, ACTION_ENUMERATE, &ace->info);
+ display_sec_access(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 *sec_acl)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ fprintf(out_hnd, "\tACL\tNum ACEs:\t%d\trevision:\t%x\n",
+ sec_acl->num_aces, sec_acl->revision);
+ fprintf(out_hnd, "\t---\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ if (sec_acl->size != 0 && sec_acl->num_aces != 0)
+ {
+ int i;
+ for (i = 0; i < sec_acl->num_aces; i++)
+ {
+ display_sec_ace(out_hnd, ACTION_HEADER , &sec_acl->ace_list[i]);
+ display_sec_ace(out_hnd, ACTION_ENUMERATE, &sec_acl->ace_list[i]);
+ display_sec_ace(out_hnd, ACTION_FOOTER , &sec_acl->ace_list[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\trevision:\t%x\ttype:\t%x\n",
+ sec->revision, sec->type);
+ fprintf(out_hnd, "\t-------------------\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring sid_str;
+
+ if (sec->off_sacl != 0)
+ {
+ display_sec_acl(out_hnd, ACTION_HEADER , sec->sacl);
+ display_sec_acl(out_hnd, ACTION_ENUMERATE, sec->sacl);
+ display_sec_acl(out_hnd, ACTION_FOOTER , sec->sacl);
+ }
+ if (sec->off_dacl != 0)
+ {
+ display_sec_acl(out_hnd, ACTION_HEADER , sec->dacl);
+ display_sec_acl(out_hnd, ACTION_ENUMERATE, sec->dacl);
+ display_sec_acl(out_hnd, ACTION_FOOTER , sec->dacl);
+ }
+ if (sec->off_owner_sid != 0)
+ {
+ sid_to_string(sid_str, sec->owner_sid);
+ fprintf(out_hnd, "\tOwner SID:\t%s\n", sid_str);
+ }
+ if (sec->off_grp_sid != 0)
+ {
+ sid_to_string(sid_str, sec->grp_sid);
+ fprintf(out_hnd, "\tParent SID:\t%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:
+ {
+ break;
+ }
+ }
+ slprintf(typestr, sizeof(typestr)-1, "[%d]", type);
+ 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
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* removed in SAMBA_2_0 branch. */
+#ifdef SYSLOG
+#undef SYSLOG
+#endif
+
+#include "includes.h"
+
+#ifndef REGISTER
+#define REGISTER 0
+#endif
+
+extern pstring debugf;
+extern pstring scope;
+extern pstring global_myname;
+
+extern pstring user_socket_options;
+
+
+extern int DEBUGLEVEL;
+
+
+extern file_info def_finfo;
+
+#define CNV_LANG(s) dos2unix_format(s,False)
+#define CNV_INPUT(s) unix2dos_format(s,True)
+
+static int process_tok(fstring tok);
+static void cmd_help(struct client_info *info);
+static void cmd_quit(struct client_info *info);
+
+static struct cli_state smbcli;
+struct cli_state *smb_cli = &smbcli;
+
+FILE *out_hnd;
+
+/****************************************************************************
+initialise smb client structure
+****************************************************************************/
+void rpcclient_init(void)
+{
+ memset((char *)smb_cli, '\0', sizeof(smb_cli));
+ cli_initialise(smb_cli);
+ smb_cli->capabilities |= CAP_NT_SMBS | CAP_STATUS32;
+}
+
+/****************************************************************************
+make smb client connection
+****************************************************************************/
+static BOOL rpcclient_connect(struct client_info *info)
+{
+ struct nmb_name calling;
+ struct nmb_name called;
+
+ make_nmb_name(&called , dns_to_netbios_name(info->dest_host ), info->name_type, scope);
+ make_nmb_name(&calling, dns_to_netbios_name(info->myhostname), 0x0 , scope);
+
+ if (!cli_establish_connection(smb_cli,
+ info->dest_host, &info->dest_ip,
+ &calling, &called,
+ info->share, info->svc_type,
+ False, True))
+ {
+ DEBUG(0,("rpcclient_connect: connection failed\n"));
+ cli_shutdown(smb_cli);
+ return False;
+ }
+
+ return True;
+}
+
+/****************************************************************************
+stop the smb connection(s?)
+****************************************************************************/
+static void rpcclient_stop(void)
+{
+ cli_shutdown(smb_cli);
+}
+/****************************************************************************
+ This defines the commands supported by this client
+ ****************************************************************************/
+struct
+{
+ char *name;
+ void (*fn)(struct client_info*);
+ char *description;
+} commands[] =
+{
+ {"regenum", cmd_reg_enum, "<keyname> Registry Enumeration (keys, values)"},
+ {"regdeletekey",cmd_reg_delete_key, "<keyname> Registry Key Delete"},
+ {"regcreatekey",cmd_reg_create_key, "<keyname> [keyclass] Registry Key Create"},
+ {"regquerykey",cmd_reg_query_key, "<keyname> Registry Key Query"},
+ {"regdeleteval",cmd_reg_delete_val, "<valname> Registry Value Delete"},
+ {"regcreateval",cmd_reg_create_val, "<valname> <valtype> <value> Registry Key Create"},
+ {"reggetsec", cmd_reg_get_key_sec, "<keyname> Registry Key Security"},
+ {"regtestsec", cmd_reg_test_key_sec, "<keyname> Test 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"},
+ {"srvsessions",cmd_srv_enum_sess, "List sessions on a server"},
+ {"srvshares", cmd_srv_enum_shares, "List shares on a server"},
+ {"srvconnections",cmd_srv_enum_conn, "List connections on a server"},
+ {"srvfiles", cmd_srv_enum_files, "List files on a server"},
+ {"lsaquery", cmd_lsa_query_info, "Query Info Policy (domain member or server)"},
+ {"lookupsids", cmd_lsa_lookup_sids, "Resolve names from SIDs"},
+ {"enumusers", cmd_sam_enum_users, "SAM User Database Query (experimental!)"},
+ {"ntpass", cmd_sam_ntchange_pwd, "NT SAM Password Change"},
+ {"samuser", cmd_sam_query_user, "<username> SAM User Query (experimental!)"},
+ {"samtest", cmd_sam_test , "SAM User Encrypted RPC test (experimental!)"},
+ {"enumaliases",cmd_sam_enum_aliases, "SAM Aliases Database Query (experimental!)"},
+#if 0
+ {"enumgroups", cmd_sam_enum_groups, "SAM Group Database Query (experimental!)"},
+#endif
+ {"samgroups", cmd_sam_query_groups, "SAM Group Database Query (experimental!)"},
+ {"quit", cmd_quit, "logoff the server"},
+ {"q", cmd_quit, "logoff the server"},
+ {"exit", cmd_quit, "logoff the server"},
+ {"bye", cmd_quit, "logoff the server"},
+ {"help", cmd_help, "[command] give help on a command"},
+ {"?", cmd_help, "[command] give help on a command"},
+ {"!", NULL, "run a shell command on the local system"},
+ {"", NULL, NULL}
+};
+
+
+/****************************************************************************
+do a (presumably graceful) quit...
+****************************************************************************/
+static void cmd_quit(struct client_info *info)
+{
+ rpcclient_stop();
+#ifdef MEM_MAN
+ {
+ extern FILE* dbf;
+ smb_mem_write_status(dbf);
+ smb_mem_write_errors(dbf);
+ smb_mem_write_verbose(dbf);
+ }
+#endif
+ exit(0);
+}
+
+/****************************************************************************
+help
+****************************************************************************/
+static void cmd_help(struct client_info *info)
+{
+ int i=0,j;
+ fstring buf;
+
+ if (next_token(NULL,buf,NULL, sizeof(buf)))
+ {
+ if ((i = process_tok(buf)) >= 0)
+ fprintf(out_hnd, "HELP %s:\n\t%s\n\n",commands[i].name,commands[i].description);
+ }
+ else
+ while (commands[i].description)
+ {
+ for (j=0; commands[i].description && (j<5); j++) {
+ fprintf(out_hnd, "%-15s",commands[i].name);
+ i++;
+ }
+ fprintf(out_hnd, "\n");
+ }
+}
+
+/*******************************************************************
+ lookup a command string in the list of commands, including
+ abbreviations
+ ******************************************************************/
+static int process_tok(fstring tok)
+{
+ int i = 0, matches = 0;
+ int cmd=0;
+ int tok_len = strlen(tok);
+
+ while (commands[i].fn != NULL)
+ {
+ if (strequal(commands[i].name,tok))
+ {
+ matches = 1;
+ cmd = i;
+ break;
+ }
+ else if (strnequal(commands[i].name, tok, tok_len))
+ {
+ matches++;
+ cmd = i;
+ }
+ i++;
+ }
+
+ if (matches == 0)
+ return(-1);
+ else if (matches == 1)
+ return(cmd);
+ else
+ return(-2);
+}
+
+/****************************************************************************
+wait for keyboard activity, swallowing network packets
+****************************************************************************/
+static void wait_keyboard(struct cli_state *cli)
+{
+ fd_set fds;
+ struct timeval timeout;
+
+ while (1)
+ {
+ FD_ZERO(&fds);
+ FD_SET(cli->fd,&fds);
+ FD_SET(fileno(stdin),&fds);
+
+ timeout.tv_sec = 20;
+ timeout.tv_usec = 0;
+ sys_select(MAX(cli->fd,fileno(stdin))+1,&fds,&timeout);
+
+ if (FD_ISSET(fileno(stdin),&fds))
+ return;
+
+ /* We deliberately use receive_smb instead of
+ client_receive_smb as we want to receive
+ session keepalives and then drop them here.
+ */
+ if (FD_ISSET(cli->fd,&fds))
+ receive_smb(cli->fd,cli->inbuf,0);
+ }
+}
+
+/****************************************************************************
+ process commands from the client
+****************************************************************************/
+static void do_command(struct client_info *info, char *tok, char *line)
+{
+ int i;
+
+ if ((i = process_tok(tok)) >= 0)
+ {
+ commands[i].fn(info);
+ }
+ else if (i == -2)
+ {
+ fprintf(out_hnd, "%s: command abbreviation ambiguous\n", CNV_LANG(tok));
+ }
+ else
+ {
+ fprintf(out_hnd, "%s: command not found\n", CNV_LANG(tok));
+ }
+}
+
+/****************************************************************************
+ process commands from the client
+****************************************************************************/
+static BOOL process( struct client_info *info, char *cmd_str)
+{
+ pstring line;
+ char *cmd = cmd_str;
+
+ if (cmd[0] != '\0') while (cmd[0] != '\0')
+ {
+ char *p;
+ fstring tok;
+
+ if ((p = strchr(cmd, ';')) == 0)
+ {
+ strncpy(line, cmd, 999);
+ line[1000] = '\0';
+ cmd += strlen(cmd);
+ }
+ else
+ {
+ if (p - cmd > 999) p = cmd + 999;
+ strncpy(line, cmd, p - cmd);
+ line[p - cmd] = '\0';
+ cmd = p + 1;
+ }
+
+ /* input language code to internal one */
+ CNV_INPUT (line);
+
+ /* get the first part of the command */
+ {
+ char *ptr = line;
+ if (!next_token(&ptr,tok,NULL, sizeof(tok))) continue;
+ }
+
+ do_command(info, tok, line);
+ }
+ else while (!feof(stdin))
+ {
+ fstring tok;
+
+ /* display a prompt */
+ fprintf(out_hnd, "smb: %s> ", CNV_LANG(info->cur_dir));
+ fflush(out_hnd);
+
+#ifdef CLIX
+ line[0] = wait_keyboard(smb_cli);
+ /* this might not be such a good idea... */
+ if ( line[0] == EOF)
+ {
+ break;
+ }
+#else
+ wait_keyboard(smb_cli);
+#endif
+
+ /* and get a response */
+#ifdef CLIX
+ fgets( &line[1],999, stdin);
+#else
+ if (!fgets(line,1000,stdin))
+ {
+ break;
+ }
+#endif
+
+ /* input language code to internal one */
+ CNV_INPUT (line);
+
+ /* special case - first char is ! */
+ if (*line == '!')
+ {
+ system(line + 1);
+ continue;
+ }
+
+ fprintf(out_hnd, "%s\n", line);
+
+ /* get the first part of the command */
+ {
+ char *ptr = line;
+ if (!next_token(&ptr,tok,NULL, sizeof(tok))) continue;
+ }
+
+ do_command(info, tok, line);
+ }
+
+ return(True);
+}
+
+/****************************************************************************
+usage on the program
+****************************************************************************/
+static void usage(char *pname)
+{
+ fprintf(out_hnd, "Usage: %s service <password> [-d debuglevel] [-l log] ",
+ pname);
+
+ fprintf(out_hnd, "\nVersion %s\n",VERSION);
+ fprintf(out_hnd, "\t-d debuglevel set the debuglevel\n");
+ fprintf(out_hnd, "\t-l log basename. Basename for log/debug files\n");
+ fprintf(out_hnd, "\t-n netbios name. Use this name as my netbios name\n");
+ fprintf(out_hnd, "\t-N don't ask for a password\n");
+ fprintf(out_hnd, "\t-m max protocol set the max protocol level\n");
+ fprintf(out_hnd, "\t-I dest IP use this IP to connect to\n");
+ fprintf(out_hnd, "\t-E write messages to stderr instead of stdout\n");
+ fprintf(out_hnd, "\t-U username set the network username\n");
+ fprintf(out_hnd, "\t-W workgroup set the workgroup name\n");
+ fprintf(out_hnd, "\t-c command string execute semicolon separated commands\n");
+ fprintf(out_hnd, "\t-t terminal code terminal i/o code {sjis|euc|jis7|jis8|junet|hex}\n");
+ fprintf(out_hnd, "\n");
+}
+
+enum client_action
+{
+ CLIENT_NONE,
+ CLIENT_IPC,
+ CLIENT_SVC
+};
+
+/****************************************************************************
+ main program
+****************************************************************************/
+ int main(int argc,char *argv[])
+{
+ BOOL interactive = True;
+
+ int opt;
+ extern FILE *dbf;
+ extern char *optarg;
+ extern int optind;
+ static pstring servicesf = CONFIGFILE;
+ pstring term_code;
+ char *p;
+ BOOL got_pass = False;
+ char *cmd_str="";
+ mode_t myumask = 0755;
+ enum client_action cli_action = CLIENT_NONE;
+
+ struct client_info cli_info;
+
+ pstring password; /* local copy only, if one is entered */
+
+ out_hnd = stdout;
+ fstrcpy(debugf, argv[0]);
+
+ rpcclient_init();
+
+#ifdef KANJI
+ pstrcpy(term_code, KANJI);
+#else /* KANJI */
+ *term_code = 0;
+#endif /* KANJI */
+
+ DEBUGLEVEL = 2;
+
+ cli_info.put_total_size = 0;
+ cli_info.put_total_time_ms = 0;
+ cli_info.get_total_size = 0;
+ cli_info.get_total_time_ms = 0;
+
+ cli_info.dir_total = 0;
+ cli_info.newer_than = 0;
+ cli_info.archive_level = 0;
+ cli_info.print_mode = 1;
+
+ cli_info.translation = False;
+ cli_info.recurse_dir = False;
+ cli_info.lowercase = False;
+ cli_info.prompt = True;
+ cli_info.abort_mget = True;
+
+ cli_info.dest_ip.s_addr = 0;
+ cli_info.name_type = 0x20;
+
+ pstrcpy(cli_info.cur_dir , "\\");
+ pstrcpy(cli_info.file_sel, "");
+ pstrcpy(cli_info.base_dir, "");
+ pstrcpy(smb_cli->domain, "");
+ pstrcpy(smb_cli->user_name, "");
+ pstrcpy(cli_info.myhostname, "");
+ pstrcpy(cli_info.dest_host, "");
+
+ pstrcpy(cli_info.svc_type, "A:");
+ pstrcpy(cli_info.share, "");
+ pstrcpy(cli_info.service, "");
+
+ 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;
+
+ TimeInit();
+ charset_initialise();
+
+ myumask = umask(0);
+ umask(myumask);
+
+ if (!get_myname(global_myname, NULL))
+ {
+ fprintf(stderr, "Failed to get my hostname.\n");
+ }
+
+ if (getenv("USER"))
+ {
+ pstrcpy(smb_cli->user_name,getenv("USER"));
+
+ /* modification to support userid%passwd syntax in the USER var
+ 25.Aug.97, jdblair@uab.edu */
+
+ if ((p=strchr(smb_cli->user_name,'%')))
+ {
+ *p = 0;
+ pstrcpy(password,p+1);
+ got_pass = True;
+ memset(strchr(getenv("USER"),'%')+1,'X',strlen(password));
+ }
+ strupper(smb_cli->user_name);
+ }
+
+ password[0] = 0;
+
+ /* modification to support PASSWD environmental var
+ 25.Aug.97, jdblair@uab.edu */
+ if (getenv("PASSWD"))
+ {
+ pstrcpy(password,getenv("PASSWD"));
+ }
+
+ if (*smb_cli->user_name == 0 && getenv("LOGNAME"))
+ {
+ pstrcpy(smb_cli->user_name,getenv("LOGNAME"));
+ strupper(smb_cli->user_name);
+ }
+
+ if (argc < 2)
+ {
+ usage(argv[0]);
+ exit(1);
+ }
+
+ if (*argv[1] != '-')
+ {
+
+ pstrcpy(cli_info.service, argv[1]);
+ /* Convert any '/' characters in the service name to '\' characters */
+ string_replace( cli_info.service, '/','\\');
+ argc--;
+ argv++;
+
+ fprintf(out_hnd, "service: %s\n", cli_info.service);
+
+ if (count_chars(cli_info.service,'\\') < 3)
+ {
+ usage(argv[0]);
+ printf("\n%s: Not enough '\\' characters in service\n", cli_info.service);
+ exit(1);
+ }
+
+ /*
+ if (count_chars(cli_info.service,'\\') > 3)
+ {
+ usage(pname);
+ printf("\n%s: Too many '\\' characters in service\n", cli_info.service);
+ exit(1);
+ }
+ */
+
+ if (argc > 1 && (*argv[1] != '-'))
+ {
+ got_pass = True;
+ pstrcpy(password,argv[1]);
+ memset(argv[1],'X',strlen(argv[1]));
+ argc--;
+ argv++;
+ }
+
+ cli_action = CLIENT_SVC;
+ }
+
+ while ((opt = getopt(argc, argv,"s:B:O:M:S:i:N:n:d:l:hI:EB:U:L:t:m:W:T:D:c:")) != EOF)
+ {
+ switch (opt)
+ {
+ case 'm':
+ {
+ /* FIXME ... max_protocol seems to be funny here */
+
+ int max_protocol = 0;
+ max_protocol = interpret_protocol(optarg,max_protocol);
+ fprintf(stderr, "max protocol not currently supported\n");
+ break;
+ }
+
+ case 'O':
+ {
+ pstrcpy(user_socket_options,optarg);
+ break;
+ }
+
+ case 'S':
+ {
+ pstrcpy(cli_info.dest_host,optarg);
+ strupper(cli_info.dest_host);
+ cli_action = CLIENT_IPC;
+ break;
+ }
+
+ case 'B':
+ {
+ iface_set_default(NULL,optarg,NULL);
+ break;
+ }
+
+ case 'i':
+ {
+ pstrcpy(scope, optarg);
+ break;
+ }
+
+ case 'U':
+ {
+ char *lp;
+ pstrcpy(smb_cli->user_name,optarg);
+ if ((lp=strchr(smb_cli->user_name,'%')))
+ {
+ *lp = 0;
+ pstrcpy(password,lp+1);
+ got_pass = True;
+ memset(strchr(optarg,'%')+1,'X',strlen(password));
+ }
+ break;
+ }
+
+ case 'W':
+ {
+ pstrcpy(smb_cli->domain,optarg);
+ break;
+ }
+
+ case 'E':
+ {
+ dbf = stderr;
+ break;
+ }
+
+ case 'I':
+ {
+ cli_info.dest_ip = *interpret_addr2(optarg);
+ if (zero_ip(cli_info.dest_ip))
+ {
+ exit(1);
+ }
+ break;
+ }
+
+ case 'n':
+ {
+ fstrcpy(global_myname, optarg);
+ break;
+ }
+
+ case 'N':
+ {
+ got_pass = True;
+ break;
+ }
+
+ case 'd':
+ {
+ if (*optarg == 'A')
+ DEBUGLEVEL = 10000;
+ else
+ DEBUGLEVEL = atoi(optarg);
+ break;
+ }
+
+ case 'l':
+ {
+ slprintf(debugf, sizeof(debugf)-1,
+ "%s.client", optarg);
+ interactive = False;
+ break;
+ }
+
+ case 'c':
+ {
+ cmd_str = optarg;
+ got_pass = True;
+ break;
+ }
+
+ case 'h':
+ {
+ usage(argv[0]);
+ exit(0);
+ break;
+ }
+
+ case 's':
+ {
+ pstrcpy(servicesf, optarg);
+ break;
+ }
+
+ case 't':
+ {
+ pstrcpy(term_code, optarg);
+ break;
+ }
+
+ default:
+ {
+ usage(argv[0]);
+ exit(1);
+ break;
+ }
+ }
+ }
+
+ setup_logging(debugf, interactive);
+
+ if (cli_action == CLIENT_NONE)
+ {
+ usage(argv[0]);
+ exit(1);
+ }
+
+ strupper(global_myname);
+ fstrcpy(cli_info.myhostname, global_myname);
+
+ DEBUG(3,("%s client started (version %s)\n",timestring(),VERSION));
+
+ if (!lp_load(servicesf,True, False, False))
+ {
+ fprintf(stderr, "Can't load %s - run testparm to debug it\n", servicesf);
+ }
+
+ codepage_initialise(lp_client_code_page());
+
+ if (*smb_cli->domain == 0) pstrcpy(smb_cli->domain,lp_workgroup());
+
+ load_interfaces();
+
+ if (cli_action == CLIENT_IPC)
+ {
+ pstrcpy(cli_info.share, "IPC$");
+ pstrcpy(cli_info.svc_type, "IPC");
+ }
+
+ fstrcpy(cli_info.mach_acct, cli_info.myhostname);
+ strupper(cli_info.mach_acct);
+ fstrcat(cli_info.mach_acct, "$");
+
+ /* set the password cache info */
+ if (got_pass)
+ {
+ if (password[0] == 0)
+ {
+ pwd_set_nullpwd(&(smb_cli->pwd));
+ }
+ else
+ {
+ pwd_make_lm_nt_16(&(smb_cli->pwd), password); /* generate 16 byte hashes */
+ }
+ }
+ else
+ {
+ pwd_read(&(smb_cli->pwd), "Enter Password:", True);
+ }
+
+ /* paranoia: destroy the local copy of the password */
+ memset((char *)password, '\0', sizeof(password));
+
+ /* establish connections. nothing to stop these being re-established. */
+ rpcclient_connect(&cli_info);
+
+ DEBUG(5,("rpcclient_connect: smb_cli->fd:%d\n", smb_cli->fd));
+ if (smb_cli->fd <= 0)
+ {
+ fprintf(stderr, "warning: connection could not be established to %s<%02x>\n",
+ cli_info.dest_host, cli_info.name_type);
+ fprintf(stderr, "this version of smbclient may crash if you proceed\n");
+ exit(-1);
+ }
+
+ switch (cli_action)
+ {
+ case CLIENT_IPC:
+ {
+ process(&cli_info, cmd_str);
+ break;
+ }
+
+ default:
+ {
+ fprintf(stderr, "unknown client action requested\n");
+ break;
+ }
+ }
+
+ rpcclient_stop();
+
+ return(0);
+}