summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/client/ntclient.c6
-rw-r--r--source3/include/ntdomain.h127
-rw-r--r--source3/include/nterr.h1
-rw-r--r--source3/include/proto.h960
-rw-r--r--source3/include/rpc_dce.h211
-rw-r--r--source3/include/rpc_lsa.h288
-rw-r--r--source3/include/rpc_misc.h272
-rw-r--r--source3/include/rpc_netlogon.h372
-rw-r--r--source3/include/rpc_reg.h141
-rw-r--r--source3/include/rpc_samr.h1023
-rw-r--r--source3/include/rpc_srvsvc.h540
-rw-r--r--source3/include/rpc_wkssvc.h73
-rw-r--r--source3/include/smb.h1114
-rw-r--r--source3/lib/membuffer.c370
-rw-r--r--source3/lib/util.c25
-rw-r--r--source3/lib/util_hnd.c316
-rw-r--r--source3/lsarpcd/srv_lsa.c444
-rw-r--r--source3/nmbd/nmbd_processlogon.c10
-rw-r--r--source3/nmbd/nmbd_subnetdb.c2
-rw-r--r--source3/nmbd/nmbd_winsserver.c7
-rw-r--r--source3/param/loadparm.c6
-rw-r--r--source3/passdb/smbpass.c1558
-rw-r--r--source3/rpc_client/cli_login.c395
-rw-r--r--source3/rpc_client/cli_lsarpc.c255
-rw-r--r--source3/rpc_client/cli_netlogon.c461
-rw-r--r--source3/rpc_client/cli_pipe.c683
-rw-r--r--source3/rpc_client/cli_samr.c695
-rw-r--r--source3/rpc_client/cli_srvsvc.c411
-rw-r--r--source3/rpc_client/cli_wkssvc.c90
-rw-r--r--source3/rpc_client/ntclienttrust.c167
-rw-r--r--source3/rpc_parse/parse_lsa.c567
-rw-r--r--source3/rpc_parse/parse_misc.c981
-rw-r--r--source3/rpc_parse/parse_net.c1147
-rw-r--r--source3/rpc_parse/parse_prs.c290
-rw-r--r--source3/rpc_parse/parse_reg.c335
-rw-r--r--source3/rpc_parse/parse_rpc.c528
-rw-r--r--source3/rpc_parse/parse_samr.c2796
-rw-r--r--source3/rpc_parse/parse_srv.c1528
-rw-r--r--source3/rpc_parse/parse_wks.c146
-rw-r--r--source3/rpc_server/srv_lsa.c444
-rw-r--r--source3/rpc_server/srv_lsa_hnd.c316
-rw-r--r--source3/rpc_server/srv_netlog.c832
-rw-r--r--source3/rpc_server/srv_pipe_hnd.c315
-rw-r--r--source3/rpc_server/srv_reg.c240
-rw-r--r--source3/rpc_server/srv_samr.c1352
-rw-r--r--source3/rpc_server/srv_srvsvc.c1015
-rw-r--r--source3/rpc_server/srv_util.c477
-rw-r--r--source3/rpc_server/srv_wkssvc.c113
-rw-r--r--source3/script/mkproto.awk2
-rw-r--r--source3/smbd/chgpasswd.c12
-rw-r--r--source3/smbd/ipc.c669
-rw-r--r--source3/smbd/password.c103
-rw-r--r--source3/smbd/pipes.c242
-rw-r--r--source3/smbd/reply.c116
-rw-r--r--source3/smbd/server.c4
-rw-r--r--source3/utils/smbpasswd.c2
56 files changed, 22969 insertions, 2626 deletions
diff --git a/source3/client/ntclient.c b/source3/client/ntclient.c
index 54ab49e3a6..bd0d0ccd5a 100644
--- a/source3/client/ntclient.c
+++ b/source3/client/ntclient.c
@@ -33,13 +33,10 @@ extern pstring workgroup;
#define CLIENT_TIMEOUT (30*1000)
-#ifdef NTDOMAIN
-
-
/****************************************************************************
experimental nt login.
****************************************************************************/
-BOOL do_nt_login(char *desthost, char *myhostname,
+BOOL client_do_nt_login(char *desthost, char *myhostname,
int Client, int cnum)
{
DOM_CHAL clnt_chal;
@@ -351,4 +348,3 @@ BOOL do_nt_login(char *desthost, char *myhostname,
return True;
}
-#endif /* NTDOMAIN */
diff --git a/source3/include/ntdomain.h b/source3/include/ntdomain.h
new file mode 100644
index 0000000000..32812aa8b1
--- /dev/null
+++ b/source3/include/ntdomain.h
@@ -0,0 +1,127 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB parameters and setup
+ Copyright (C) Andrew Tridgell 1992-1997
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1997
+ Copyright (C) Paul Ashton 1997
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _NT_DOMAIN_H /* _NT_DOMAIN_H */
+#define _NT_DOMAIN_H
+
+
+/* dce/rpc support */
+#include "lib/rpc/include/rpc_dce.h"
+
+/* miscellaneous structures / defines */
+#include "lib/rpc/include/rpc_misc.h"
+
+/* different dce/rpc pipes */
+#include "lib/rpc/include/rpc_lsa.h"
+#include "lib/rpc/include/rpc_netlogon.h"
+#include "lib/rpc/include/rpc_reg.h"
+#include "lib/rpc/include/rpc_samr.h"
+#include "lib/rpc/include/rpc_srvsvc.h"
+#include "lib/rpc/include/rpc_wkssvc.h"
+
+/*
+ * A bunch of stuff that was put into smb.h
+ * in the NTDOM branch - it didn't belong there.
+ */
+
+typedef struct
+{
+ struct mem_buf *data; /* memory buffer */
+ uint32 offset; /* offset currently being accessed in memory buffer */
+ uint8 align; /* data alignment */
+ BOOL io; /* parsing in or out of data stream */
+
+} prs_struct;
+
+typedef struct
+{
+ int cnum;
+ int uid;
+ BOOL open; /* open connection */
+ uint16 device_state;
+ fstring name;
+ fstring pipe_srv_name;
+
+ prs_struct rhdr; /* output header */
+ prs_struct rdata; /* output data */
+ prs_struct rauth; /* output authentication verifier */
+
+ RPC_HDR hdr;
+ RPC_HDR_BA hdr_ba;
+ RPC_HDR_RB hdr_rb;
+ RPC_HDR_RR hdr_rr;
+
+ RPC_AUTH_NTLMSSP_REQ ntlmssp_req;
+ RPC_AUTH_NTLMSSP_RESP ntlmssp_resp;
+
+ uint32 max_rdata_len;
+ uint32 hdr_offsets;
+
+} pipes_struct;
+
+struct acct_info
+{
+ fstring acct_name; /* account name */
+ uint32 smb_userid; /* domain-relative RID */
+};
+
+struct api_struct
+{
+ char *name;
+ uint8 opnum;
+ void (*fn) (int uid, prs_struct*, prs_struct*);
+};
+
+struct mem_desc
+{
+ /* array memory offsets */
+ uint32 start;
+ uint32 end;
+};
+
+struct mem_buf
+{
+ BOOL dynamic; /* True iff data has been dynamically allocated
+ (and therefore can be freed) */
+ char *data;
+ uint32 data_size;
+ uint32 data_used;
+
+ uint32 margin; /* safety margin when reallocing. */
+ /* this can be abused quite nicely */
+ uint8 align; /* alignment of data structures (smb, dce/rpc, udp etc) */
+
+ struct mem_desc offset;
+
+ struct mem_buf *next;
+};
+
+typedef struct
+{
+ uint32 rid;
+ char *name;
+
+} rid_name;
+
+#endif /* _NT_DOMAIN_H */
+
diff --git a/source3/include/nterr.h b/source3/include/nterr.h
index 92f02612db..643d93bc93 100644
--- a/source3/include/nterr.h
+++ b/source3/include/nterr.h
@@ -7,6 +7,7 @@
#define NT_STATUS_INVALID_INFO_CLASS (3)
#define NT_STATUS_INFO_LENGTH_MISMATCH (4)
#define NT_STATUS_ACCESS_VIOLATION (5)
+#define STATUS_BUFFER_OVERFLOW (5)
#define NT_STATUS_IN_PAGE_ERROR (6)
#define NT_STATUS_PAGEFILE_QUOTA (7)
#define NT_STATUS_INVALID_HANDLE (8)
diff --git a/source3/include/proto.h b/source3/include/proto.h
index f0591743c0..19274157c6 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -212,6 +212,651 @@ int reply_trans(char *inbuf,char *outbuf, int size, int bufsize);
void interpret_coding_system(char *str);
void initialize_multibyte_vectors( int client_codepage);
+/*The following definitions come from lib/rpc/parse/parse_lsa.c */
+
+void make_lsa_trans_name(LSA_TRANS_NAME *trn, uint32 sid_name_use, char *name, uint32 idx);
+void lsa_io_trans_name(char *desc, LSA_TRANS_NAME *trn, prs_struct *ps, int depth);
+void lsa_io_dom_r_ref(char *desc, DOM_R_REF *r_r, prs_struct *ps, int depth);
+void make_lsa_obj_attr(LSA_OBJ_ATTR *attr, uint32 attributes, uint32 sec_qos);
+void lsa_io_obj_attr(char *desc, LSA_OBJ_ATTR *attr, prs_struct *ps, int depth);
+void make_q_open_pol(LSA_Q_OPEN_POL *r_q, char *server_name,
+ uint32 attributes, uint32 sec_qos,
+ uint32 desired_access);
+void lsa_io_q_open_pol(char *desc, LSA_Q_OPEN_POL *r_q, prs_struct *ps, int depth);
+void lsa_io_r_open_pol(char *desc, LSA_R_OPEN_POL *r_p, prs_struct *ps, int depth);
+void make_q_query(LSA_Q_QUERY_INFO *q_q, POLICY_HND *hnd, uint16 info_class);
+void lsa_io_q_query(char *desc, LSA_Q_QUERY_INFO *q_q, prs_struct *ps, int depth);
+void lsa_io_q_enum_trust_dom(char *desc, LSA_Q_ENUM_TRUST_DOM *q_e, prs_struct *ps, int depth);
+void make_r_enum_trust_dom(LSA_R_ENUM_TRUST_DOM *r_e,
+ uint32 enum_context, char *domain_name, char *domain_sid,
+ uint32 status);
+void lsa_io_r_enum_trust_dom(char *desc, LSA_R_ENUM_TRUST_DOM *r_e, 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 make_lsa_r_close(LSA_R_CLOSE *q_r, POLICY_HND *hnd);
+void lsa_io_r_close(char *desc, LSA_R_CLOSE *r_c, prs_struct *ps, int depth);
+void lsa_io_r_query(char *desc, LSA_R_QUERY_INFO *r_q, prs_struct *ps, int depth);
+void lsa_io_sid_enum(char *desc, LSA_SID_ENUM *sen, prs_struct *ps, int depth);
+void lsa_io_q_lookup_sids(char *desc, LSA_Q_LOOKUP_SIDS *q_s, prs_struct *ps, int depth);
+void lsa_io_trans_names(char *desc, LSA_TRANS_NAME_ENUM *trn, 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);
+
+/*The following definitions come from lib/rpc/parse/parse_misc.c */
+
+void smb_io_utime(char *desc, UTIME *t, prs_struct *ps, int depth);
+void smb_io_time(char *desc, NTTIME *nttime, prs_struct *ps, int depth);
+void smb_io_lookup_level(char *desc, LOOKUP_LEVEL *level, prs_struct *ps, int depth);
+uint32 get_enum_hnd(ENUM_HND *enh);
+void make_enum_hnd(ENUM_HND *enh, uint32 hnd);
+void smb_io_enum_hnd(char *desc, ENUM_HND *hnd, prs_struct *ps, int depth);
+void make_dom_sid(DOM_SID *sid, char *str_sid);
+void smb_io_dom_sid(char *desc, DOM_SID *sid, prs_struct *ps, int depth);
+void make_dom_sid2(DOM_SID2 *sid, char *str_sid);
+void smb_io_dom_sid2(char *desc, DOM_SID2 *sid, prs_struct *ps, int depth);
+void make_str_hdr(STRHDR *hdr, int max_len, int len, uint32 buffer);
+void smb_io_strhdr(char *desc, STRHDR *hdr, prs_struct *ps, int depth);
+void make_uni_hdr(UNIHDR *hdr, int max_len, int len, uint32 buffer);
+void smb_io_unihdr(char *desc, UNIHDR *hdr, prs_struct *ps, int depth);
+void make_uni_hdr2(UNIHDR2 *hdr, int max_len, int len, uint16 terminate);
+void smb_io_unihdr2(char *desc, UNIHDR2 *hdr2, prs_struct *ps, int depth);
+void make_unistr(UNISTR *str, char *buf);
+void smb_io_unistr(char *desc, UNISTR *uni, prs_struct *ps, int depth);
+void make_uninotstr2(UNINOTSTR2 *str, char *buf, int len);
+void smb_io_uninotstr2(char *desc, UNINOTSTR2 *uni2, uint32 buffer, prs_struct *ps, int depth);
+void make_buf_unistr2(UNISTR2 *str, uint32 *ptr, char *buf);
+void copy_unistr2(UNISTR2 *str, UNISTR2 *from);
+void make_string2(STRING2 *str, char *buf, int len);
+void smb_io_string2(char *desc, STRING2 *str2, uint32 buffer, prs_struct *ps, int depth);
+void make_unistr2(UNISTR2 *str, char *buf, int len);
+void smb_io_unistr2(char *desc, UNISTR2 *uni2, uint32 buffer, prs_struct *ps, int depth);
+void make_dom_rid2(DOM_RID2 *rid2, uint32 rid);
+void smb_io_dom_rid2(char *desc, DOM_RID2 *rid2, prs_struct *ps, int depth);
+void make_dom_rid3(DOM_RID3 *rid3, uint32 rid);
+void smb_io_dom_rid3(char *desc, DOM_RID3 *rid3, prs_struct *ps, int depth);
+void make_dom_rid4(DOM_RID4 *rid4, uint16 unknown, uint16 attr, uint32 rid);
+void smb_io_dom_rid4(char *desc, DOM_RID4 *rid4, prs_struct *ps, int depth);
+void make_clnt_srv(DOM_CLNT_SRV *log, char *logon_srv, char *comp_name);
+void smb_io_clnt_srv(char *desc, DOM_CLNT_SRV *log, prs_struct *ps, int depth);
+void make_log_info(DOM_LOG_INFO *log, char *logon_srv, char *acct_name,
+ uint16 sec_chan, char *comp_name);
+void smb_io_log_info(char *desc, DOM_LOG_INFO *log, prs_struct *ps, int depth);
+void smb_io_chal(char *desc, DOM_CHAL *chal, prs_struct *ps, int depth);
+void smb_io_cred(char *desc, DOM_CRED *cred, prs_struct *ps, int depth);
+void make_clnt_info2(DOM_CLNT_INFO2 *clnt,
+ char *logon_srv, char *comp_name,
+ DOM_CRED *clnt_cred);
+void smb_io_clnt_info2(char *desc, DOM_CLNT_INFO2 *clnt, prs_struct *ps, int depth);
+void make_clnt_info(DOM_CLNT_INFO *clnt,
+ char *logon_srv, char *acct_name,
+ uint16 sec_chan, char *comp_name,
+ DOM_CRED *cred);
+void smb_io_clnt_info(char *desc, DOM_CLNT_INFO *clnt, prs_struct *ps, int depth);
+void make_logon_id(DOM_LOGON_ID *log, uint32 log_id_low, uint32 log_id_high);
+void smb_io_logon_id(char *desc, DOM_LOGON_ID *log, prs_struct *ps, int depth);
+void make_arc4_owf(ARC4_OWF *hash, uint8 data[16]);
+void smb_io_arc4_owf(char *desc, ARC4_OWF *hash, prs_struct *ps, int depth);
+void smb_io_gid(char *desc, DOM_GID *gid, prs_struct *ps, int depth);
+void smb_io_pol_hnd(char *desc, POLICY_HND *pol, prs_struct *ps, int depth);
+void smb_io_dom_query_3(char *desc, DOM_QUERY_3 *d_q, prs_struct *ps, int depth);
+void smb_io_dom_query_5(char *desc, DOM_QUERY_3 *d_q, prs_struct *ps, int depth);
+void smb_io_dom_query(char *desc, DOM_QUERY *d_q, prs_struct *ps, int depth);
+void smb_io_dom_name(char *desc, DOM_NAME *name, prs_struct *ps, int depth);
+
+/*The following definitions come from lib/rpc/parse/parse_net.c */
+
+void net_io_neg_flags(char *desc, NEG_FLAGS *neg, prs_struct *ps, int depth);
+void make_netinfo_3(NETLOGON_INFO_3 *info, uint32 flags, uint32 logon_attempts);
+void net_io_netinfo_3(char *desc, NETLOGON_INFO_3 *info, prs_struct *ps, int depth);
+void make_netinfo_1(NETLOGON_INFO_1 *info, uint32 flags, uint32 pdc_status);
+void net_io_netinfo_1(char *desc, NETLOGON_INFO_1 *info, prs_struct *ps, int depth);
+void make_netinfo_2(NETLOGON_INFO_2 *info, uint32 flags, uint32 pdc_status,
+ uint32 tc_status, char *trusted_dc_name);
+void net_io_netinfo_2(char *desc, NETLOGON_INFO_2 *info, prs_struct *ps, int depth);
+void make_q_logon_ctrl2(NET_Q_LOGON_CTRL2 *q_l, char *server_name,
+ uint32 function_code);
+void net_io_q_logon_ctrl2(char *desc, NET_Q_LOGON_CTRL2 *q_l, prs_struct *ps, int depth);
+void make_r_logon_ctrl2(NET_R_LOGON_CTRL2 *r_l, uint32 query_level,
+ uint32 flags, uint32 pdc_status, uint32 logon_attempts,
+ uint32 tc_status, char *trusted_domain_name);
+void net_io_r_logon_ctrl2(char *desc, NET_R_LOGON_CTRL2 *r_l, prs_struct *ps, int depth);
+void make_r_trust_dom(NET_R_TRUST_DOM_LIST *r_t,
+ uint32 num_doms, char *dom_name);
+void net_io_r_trust_dom(char *desc, NET_R_TRUST_DOM_LIST *r_t, prs_struct *ps, int depth);
+void make_q_trust_dom(NET_Q_TRUST_DOM_LIST *q_l, char *server_name,
+ uint32 function_code);
+void net_io_q_trust_dom(char *desc, NET_Q_TRUST_DOM_LIST *q_l, prs_struct *ps, int depth);
+void make_q_req_chal(NET_Q_REQ_CHAL *q_c,
+ char *logon_srv, char *logon_clnt,
+ DOM_CHAL *clnt_chal);
+void net_io_q_req_chal(char *desc, NET_Q_REQ_CHAL *q_c, prs_struct *ps, int depth);
+void net_io_r_req_chal(char *desc, NET_R_REQ_CHAL *r_c, prs_struct *ps, int depth);
+void make_q_auth_2(NET_Q_AUTH_2 *q_a,
+ char *logon_srv, char *acct_name, uint16 sec_chan, char *comp_name,
+ DOM_CHAL *clnt_chal, uint32 clnt_flgs);
+void net_io_q_auth_2(char *desc, NET_Q_AUTH_2 *q_a, prs_struct *ps, int depth);
+void net_io_r_auth_2(char *desc, NET_R_AUTH_2 *r_a, prs_struct *ps, int depth);
+void make_q_srv_pwset(NET_Q_SRV_PWSET *q_s, char sess_key[16],
+ char *logon_srv, char *acct_name, uint16 sec_chan, char *comp_name,
+ DOM_CRED *cred, char nt_cypher[16]);
+void net_io_q_srv_pwset(char *desc, NET_Q_SRV_PWSET *q_s, prs_struct *ps, int depth);
+void net_io_r_srv_pwset(char *desc, NET_R_SRV_PWSET *r_s, prs_struct *ps, int depth);
+void make_id_info1(NET_ID_INFO_1 *id, char *domain_name,
+ uint32 param_ctrl, uint32 log_id_low, uint32 log_id_high,
+ char *user_name, char *wksta_name,
+ char sess_key[16],
+ unsigned char lm_cypher[16], unsigned char nt_cypher[16]);
+void net_io_id_info1(char *desc, NET_ID_INFO_1 *id, prs_struct *ps, int depth);
+void make_id_info2(NET_ID_INFO_2 *id, char *domain_name,
+ uint32 param_ctrl, uint32 log_id_low, uint32 log_id_high,
+ char *user_name, char *wksta_name,
+ unsigned char lm_challenge[8],
+ unsigned char lm_chal_resp[24],
+ unsigned char nt_chal_resp[24]);
+void net_io_id_info2(char *desc, NET_ID_INFO_2 *id, prs_struct *ps, int depth);
+void make_sam_info(DOM_SAM_INFO *sam,
+ char *logon_srv, char *comp_name, DOM_CRED *clnt_cred,
+ DOM_CRED *rtn_cred, uint16 logon_level,
+ NET_ID_INFO_CTR *ctr, uint16 validation_level);
+void net_io_id_info_ctr(char *desc, NET_ID_INFO_CTR *ctr, prs_struct *ps, int depth);
+void smb_io_sam_info(char *desc, DOM_SAM_INFO *sam, prs_struct *ps, int depth);
+void make_net_user_info3(NET_USER_INFO_3 *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 *logon_script,
+ char *profile_path,
+ char *home_dir,
+ char *dir_drive,
+
+ uint16 logon_count,
+ uint16 bad_pw_count,
+
+ uint32 user_id,
+ uint32 group_id,
+ uint32 num_groups,
+ DOM_GID *gids,
+ uint32 user_flgs,
+
+ char sess_key[16],
+
+ char *logon_srv,
+ char *logon_dom,
+
+ char *dom_sid,
+ char *other_sids);
+void net_io_user_info3(char *desc, NET_USER_INFO_3 *usr, prs_struct *ps, int depth);
+void net_io_q_sam_logon(char *desc, NET_Q_SAM_LOGON *q_l, prs_struct *ps, int depth);
+void net_io_r_sam_logon(char *desc, NET_R_SAM_LOGON *r_l, prs_struct *ps, int depth);
+void net_io_q_sam_logoff(char *desc, NET_Q_SAM_LOGOFF *q_l, prs_struct *ps, int depth);
+void net_io_r_sam_logoff(char *desc, NET_R_SAM_LOGOFF *r_l, prs_struct *ps, int depth);
+
+/*The following definitions come from lib/rpc/parse/parse_prs.c */
+
+void prs_debug(prs_struct *ps, int depth, char *desc, char *fn_name);
+void prs_init(prs_struct *ps, uint32 size,
+ uint8 align, uint32 margin,
+ BOOL io);
+void prs_mem_free(prs_struct *ps);
+void prs_align(prs_struct *ps);
+BOOL prs_grow(prs_struct *ps);
+BOOL prs_uint8(char *name, prs_struct *ps, int depth, uint8 *data8);
+BOOL prs_uint16(char *name, prs_struct *ps, int depth, uint16 *data16);
+BOOL prs_uint32(char *name, prs_struct *ps, int depth, uint32 *data32);
+BOOL prs_uint8s(BOOL charmode, char *name, prs_struct *ps, int depth, uint8 *data8s, int len);
+BOOL prs_uint16s(BOOL charmode, char *name, prs_struct *ps, int depth, uint16 *data16s, int len);
+BOOL prs_uint32s(BOOL charmode, char *name, prs_struct *ps, int depth, uint32 *data32s, int len);
+BOOL prs_uninotstr2(BOOL charmode, char *name, prs_struct *ps, int depth, UNINOTSTR2 *str);
+BOOL prs_string2(BOOL charmode, char *name, prs_struct *ps, int depth, STRING2 *str);
+BOOL prs_unistr2(BOOL charmode, char *name, prs_struct *ps, int depth, UNISTR2 *str);
+BOOL prs_unistr(char *name, prs_struct *ps, int depth, UNISTR *str);
+BOOL prs_string(char *name, prs_struct *ps, int depth, char *str, uint16 len);
+
+/*The following definitions come from lib/rpc/parse/parse_reg.c */
+
+void make_reg_q_open_policy(REG_Q_OPEN_POLICY *r_q,
+ uint16 unknown_0, uint32 level, uint16 unknown_1);
+void reg_io_q_open_policy(char *desc, REG_Q_OPEN_POLICY *r_q, prs_struct *ps, int depth);
+void make_reg_r_open_policy(REG_R_OPEN_POLICY *r_r,
+ POLICY_HND *pol, uint32 status);
+void reg_io_r_open_policy(char *desc, REG_R_OPEN_POLICY *r_r, prs_struct *ps, int depth);
+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_info(REG_Q_INFO *r_q,
+ POLICY_HND *pol, char *product_type,
+ NTTIME *prod_time, uint8 major_version, uint8 minor_version,
+ uint32 unknown);
+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_open_entry(REG_Q_OPEN_ENTRY *r_q,
+ POLICY_HND *pol, char *name,
+ uint32 unknown_0, uint32 unknown_1, uint16 unknown_2);
+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 lib/rpc/parse/parse_rpc.c */
+
+void make_rpc_hdr(RPC_HDR *hdr, enum RPC_PKT_TYPE pkt_type, uint8 flags,
+ uint32 call_id, int data_len, int auth_len);
+void smb_io_rpc_hdr(char *desc, RPC_HDR *rpc, prs_struct *ps, int depth);
+void make_rpc_iface(RPC_IFACE *ifc, char data[16], uint32 version);
+void smb_io_rpc_iface(char *desc, RPC_IFACE *ifc, prs_struct *ps, int depth);
+void make_rpc_addr_str(RPC_ADDR_STR *str, char *name);
+void smb_io_rpc_addr_str(char *desc, RPC_ADDR_STR *str, prs_struct *ps, int depth);
+void make_rpc_hdr_bba(RPC_HDR_BBA *bba, uint16 max_tsize, uint16 max_rsize, uint32 assoc_gid);
+void smb_io_rpc_hdr_bba(char *desc, RPC_HDR_BBA *rpc, prs_struct *ps, int depth);
+void make_rpc_hdr_rb(RPC_HDR_RB *rpc,
+ uint16 max_tsize, uint16 max_rsize, uint32 assoc_gid,
+ uint32 num_elements, uint16 context_id, uint8 num_syntaxes,
+ RPC_IFACE *abstract, RPC_IFACE *transfer);
+void smb_io_rpc_hdr_rb(char *desc, RPC_HDR_RB *rpc, prs_struct *ps, int depth);
+void make_rpc_results(RPC_RESULTS *res,
+ uint8 num_results, uint16 result, uint16 reason);
+void smb_io_rpc_results(char *desc, RPC_RESULTS *res, prs_struct *ps, int depth);
+void make_rpc_hdr_ba(RPC_HDR_BA *rpc,
+ uint16 max_tsize, uint16 max_rsize, uint32 assoc_gid,
+ char *pipe_addr,
+ uint8 num_results, uint16 result, uint16 reason,
+ RPC_IFACE *transfer);
+void smb_io_rpc_hdr_ba(char *desc, RPC_HDR_BA *rpc, prs_struct *ps, int depth);
+void make_rpc_hdr_rr(RPC_HDR_RR *hdr, uint32 data_len, uint8 opnum);
+void smb_io_rpc_hdr_rr(char *desc, RPC_HDR_RR *rpc, prs_struct *ps, int depth);
+void make_rpc_auth_ntlmssp_req(RPC_AUTH_NTLMSSP_REQ *req,
+ fstring ntlmssp_str, uint32 ntlmssp_ver,
+ uint32 unknown_0, fstring myname, fstring domain);
+void smb_io_rpc_auth_ntlmssp_req(char *desc, RPC_AUTH_NTLMSSP_REQ *req, prs_struct *ps, int depth);
+void make_rpc_auth_ntlmssp_resp(RPC_AUTH_NTLMSSP_RESP *rsp,
+ uint8 auth_type, uint8 auth_level, uint8 stub_type_len,
+ fstring ntlmssp_str, uint32 ntlmssp_ver,
+ uint32 unknown_1, uint32 unknown_2, uint32 unknown_3,
+ uint8 data[16]);
+void smb_io_rpc_auth_ntlmssp_resp(char *desc, RPC_AUTH_NTLMSSP_RESP *rsp, prs_struct *ps, int depth);
+
+/*The following definitions come from lib/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, char *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_8(SAMR_Q_UNKNOWN_8 *q_u,
+ POLICY_HND *domain_pol, uint16 switch_value);
+void samr_io_q_unknown_8(char *desc, SAMR_Q_UNKNOWN_8 *q_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_dom_sid3(DOM_SID3 *sid3, uint16 unk_0, uint16 unk_1, char *sid);
+void sam_io_dom_sid3(char *desc, DOM_SID3 *sid3, prs_struct *ps, int depth);
+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]);
+void sam_io_sid_stuff(char *desc, SAM_SID_STUFF *stf, prs_struct *ps, int depth);
+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_sam_str1(SAM_STR1 *sam, char *sam_acct, char *sam_name, char *sam_desc);
+void sam_io_sam_str1(char *desc, SAM_STR1 *sam, uint32 acct_buf, uint32 name_buf, uint32 desc_buf, prs_struct *ps, int depth);
+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);
+void sam_io_sam_entry1(char *desc, SAM_ENTRY1 *sam, prs_struct *ps, int depth);
+void make_sam_str2(SAM_STR2 *sam, char *sam_acct, char *sam_desc);
+void sam_io_sam_str2(char *desc, SAM_STR2 *sam, uint32 acct_buf, uint32 desc_buf, prs_struct *ps, int depth);
+void make_sam_entry2(SAM_ENTRY2 *sam, uint32 user_idx,
+ uint32 len_sam_name, uint32 len_sam_desc,
+ uint32 rid_user, uint16 acb_info);
+void sam_io_sam_entry2(char *desc, SAM_ENTRY2 *sam, prs_struct *ps, int depth);
+void make_sam_str3(SAM_STR3 *sam, char *grp_acct, char *grp_desc);
+void sam_io_sam_str3(char *desc, SAM_STR3 *sam, uint32 acct_buf, uint32 desc_buf, prs_struct *ps, int depth);
+void make_sam_entry3(SAM_ENTRY3 *sam, uint32 grp_idx,
+ uint32 len_grp_name, uint32 len_grp_desc, uint32 rid_grp);
+void sam_io_sam_entry3(char *desc, SAM_ENTRY3 *sam, prs_struct *ps, int depth);
+void make_sam_entry(SAM_ENTRY *sam, uint32 len_sam_name, uint32 rid);
+void sam_io_sam_entry(char *desc, SAM_ENTRY *sam, 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 sam_io_sam_info_2(char *desc, SAM_INFO_2 *sam, prs_struct *ps, int depth);
+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 sam_io_sam_info_1(char *desc, SAM_INFO_1 *sam, prs_struct *ps, int depth);
+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 make_samr_q_unknown_12(SAMR_Q_UNKNOWN_12 *q_u,
+ POLICY_HND *pol, uint32 rid,
+ uint32 num_gids, uint32 *gid);
+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 sam_io_logon_hrs(char *desc, LOGON_HRS *hrs, 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 sam_io_user_info21(char *desc, SAM_USER_INFO_21 *usr, prs_struct *ps, int depth);
+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 make_samr_q_unknown_21(SAMR_Q_UNKNOWN_21 *q_c,
+ POLICY_HND *hnd, uint16 unk_1, uint16 unk_2);
+void samr_io_q_unknown_21(char *desc, SAMR_Q_UNKNOWN_21 *q_u, prs_struct *ps, int depth);
+void make_samr_q_unknown_13(SAMR_Q_UNKNOWN_13 *q_c,
+ POLICY_HND *hnd, uint16 unk_1, uint16 unk_2);
+void samr_io_q_unknown_13(char *desc, SAMR_Q_UNKNOWN_13 *q_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_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_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,
+ uint16 level, uint32 status);
+void samr_io_r_unknown_38(char *desc, SAMR_R_UNKNOWN_38 *r_u, prs_struct *ps, int depth);
+void samr_io_enc_passwd(char *desc, SAMR_ENC_PASSWD *pwd, prs_struct *ps, int depth);
+void samr_io_enc_hash(char *desc, SAMR_ENC_HASH *hsh, prs_struct *ps, int depth);
+
+/*The following definitions come from lib/rpc/parse/parse_srv.c */
+
+void make_srv_share_info1_str(SH_INFO_1_STR *sh1, char *net_name, char *remark);
+void srv_io_share_info1_str(char *desc, SH_INFO_1_STR *sh1, prs_struct *ps, int depth);
+void make_srv_share_info1(SH_INFO_1 *sh1, char *net_name, uint32 type, char *remark);
+void srv_io_share_info1(char *desc, SH_INFO_1 *sh1, prs_struct *ps, int depth);
+void srv_io_srv_share_info_1(char *desc, SRV_SHARE_INFO_1 *ctr, prs_struct *ps, int depth);
+void make_srv_share_info2_str(SH_INFO_2_STR *sh2,
+ char *net_name, char *remark,
+ char *path, char *passwd);
+void srv_io_share_info2_str(char *desc, SH_INFO_2_STR *sh2, prs_struct *ps, int depth);
+void make_srv_share_info2(SH_INFO_2 *sh2,
+ char *net_name, uint32 type, char *remark,
+ uint32 perms, uint32 max_uses, uint32 num_uses,
+ char *path, char *passwd);
+void srv_io_share_info2(char *desc, SH_INFO_2 *sh2, prs_struct *ps, int depth);
+void srv_io_srv_share_info_2(char *desc, SRV_SHARE_INFO_2 *ctr, prs_struct *ps, int depth);
+void srv_io_srv_share_ctr(char *desc, SRV_SHARE_INFO_CTR *ctr, prs_struct *ps, int depth);
+void make_srv_q_net_share_enum(SRV_Q_NET_SHARE_ENUM *q_n,
+ char *srv_name,
+ uint32 share_level, SRV_SHARE_INFO_CTR *ctr,
+ uint32 preferred_len,
+ 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 srv_io_sess_info0_str(char *desc, SESS_INFO_0_STR *ss0, prs_struct *ps, int depth);
+void make_srv_sess_info0(SESS_INFO_0 *ss0, char *name);
+void srv_io_sess_info0(char *desc, SESS_INFO_0 *ss0, prs_struct *ps, int depth);
+void srv_io_srv_sess_info_0(char *desc, SRV_SESS_INFO_0 *ss0, prs_struct *ps, int depth);
+void make_srv_sess_info1_str(SESS_INFO_1_STR *ss1, char *name, char *user);
+void srv_io_sess_info1_str(char *desc, SESS_INFO_1_STR *ss1, prs_struct *ps, int depth);
+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 srv_io_sess_info1(char *desc, SESS_INFO_1 *ss1, prs_struct *ps, int depth);
+void srv_io_srv_sess_info_1(char *desc, SRV_SESS_INFO_1 *ss1, prs_struct *ps, int depth);
+void srv_io_srv_sess_ctr(char *desc, SRV_SESS_INFO_CTR *ctr, prs_struct *ps, int depth);
+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 srv_io_conn_info0(char *desc, CONN_INFO_0 *ss0, prs_struct *ps, int depth);
+void srv_io_srv_conn_info_0(char *desc, SRV_CONN_INFO_0 *ss0, prs_struct *ps, int depth);
+void make_srv_conn_info1_str(CONN_INFO_1_STR *ss1, char *usr_name, char *net_name);
+void srv_io_conn_info1_str(char *desc, CONN_INFO_1_STR *ss1, prs_struct *ps, int depth);
+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 srv_io_conn_info1(char *desc, CONN_INFO_1 *ss1, prs_struct *ps, int depth);
+void srv_io_srv_conn_info_1(char *desc, SRV_CONN_INFO_1 *ss1, prs_struct *ps, int depth);
+void srv_io_srv_conn_ctr(char *desc, SRV_CONN_INFO_CTR *ctr, prs_struct *ps, int depth);
+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 srv_io_file_info3_str(char *desc, FILE_INFO_3_STR *sh1, prs_struct *ps, int depth);
+void make_srv_file_info3(FILE_INFO_3 *fl3,
+ uint32 id, uint32 perms, uint32 num_locks,
+ char *path_name, char *user_name);
+void srv_io_file_info3(char *desc, FILE_INFO_3 *fl3, prs_struct *ps, int depth);
+void srv_io_srv_file_info_3(char *desc, SRV_FILE_INFO_3 *fl3, prs_struct *ps, int depth);
+void srv_io_srv_file_ctr(char *desc, SRV_FILE_INFO_CTR *ctr, prs_struct *ps, int depth);
+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);
+void srv_io_info_101(char *desc, SRV_INFO_101 *sv101, prs_struct *ps, int depth);
+void make_srv_info_102(SRV_INFO_102 *sv102, uint32 platform_id, char *name,
+ char *comment, uint32 ver_major, uint32 ver_minor,
+ uint32 srv_type, uint32 users, uint32 disc, uint32 hidden,
+ uint32 announce, uint32 ann_delta, uint32 licenses,
+ char *usr_path);
+void srv_io_info_102(char *desc, SRV_INFO_102 *sv102, prs_struct *ps, int depth);
+void srv_io_info_ctr(char *desc, SRV_INFO_CTR *ctr, prs_struct *ps, int depth);
+void make_srv_q_net_srv_get_info(SRV_Q_NET_SRV_GET_INFO *srv,
+ char *server_name, uint32 switch_value);
+void srv_io_q_net_srv_get_info(char *desc, SRV_Q_NET_SRV_GET_INFO *q_n, prs_struct *ps, int depth);
+void make_srv_r_net_srv_get_info(SRV_R_NET_SRV_GET_INFO *srv,
+ uint32 switch_value, SRV_INFO_CTR *ctr, uint32 status);
+void srv_io_r_net_srv_get_info(char *desc, SRV_R_NET_SRV_GET_INFO *r_n, prs_struct *ps, int depth);
+void make_srv_q_net_srv_set_info(SRV_Q_NET_SRV_SET_INFO *srv,
+ uint32 switch_value, SRV_INFO_CTR *ctr);
+void srv_io_q_net_srv_set_info(char *desc, SRV_Q_NET_SRV_SET_INFO *q_n, prs_struct *ps, int depth);
+void make_srv_r_net_srv_set_info(SRV_R_NET_SRV_SET_INFO *srv,
+ uint32 switch_value, SRV_INFO_CTR *ctr, uint32 status);
+void srv_io_r_net_srv_set_info(char *desc, SRV_R_NET_SRV_SET_INFO *r_n, prs_struct *ps, int depth);
+
+/*The following definitions come from lib/rpc/parse/parse_wks.c */
+
+void make_wks_q_query_info(WKS_Q_QUERY_INFO *q_u,
+ char *server, uint16 switch_value) ;
+void wks_io_q_query_info(char *desc, WKS_Q_QUERY_INFO *q_u, prs_struct *ps, int depth);
+void make_wks_info_100(WKS_INFO_100 *inf,
+ uint32 platform_id, uint32 ver_major, uint32 ver_minor,
+ char *my_name, char *domain_name);
+void wks_io_wks_info_100(char *desc, WKS_INFO_100 *inf, prs_struct *ps, int depth);
+void make_wks_r_query_info(WKS_R_QUERY_INFO *r_u,
+ uint32 switch_value, WKS_INFO_100 *wks100,
+ int status) ;
+void wks_io_r_query_info(char *desc, WKS_R_QUERY_INFO *r_u, prs_struct *ps, int depth);
+
+/*The following definitions come from lib/rpc/server/srv_lsa.c */
+
+BOOL api_ntlsa_rpc(pipes_struct *p, prs_struct *data);
+
+/*The following definitions come from lib/rpc/server/srv_lsa_hnd.c */
+
+void create_pol_hnd(POLICY_HND *hnd);
+void init_lsa_policy_hnd(void);
+BOOL open_lsa_policy_hnd(POLICY_HND *hnd);
+int find_lsa_policy_by_hnd(POLICY_HND *hnd);
+BOOL set_lsa_policy_samr_rid(POLICY_HND *hnd, uint32 rid);
+BOOL set_lsa_policy_samr_pol_status(POLICY_HND *hnd, uint32 pol_status);
+BOOL set_lsa_policy_samr_sid(POLICY_HND *hnd, DOM_SID *sid);
+uint32 get_lsa_policy_samr_rid(POLICY_HND *hnd);
+BOOL set_lsa_policy_reg_name(POLICY_HND *hnd, fstring name);
+BOOL get_lsa_policy_reg_name(POLICY_HND *hnd, fstring name);
+BOOL close_lsa_policy_hnd(POLICY_HND *hnd);
+
+/*The following definitions come from lib/rpc/server/srv_netlog.c */
+
+BOOL api_netlog_rpc(pipes_struct *p, prs_struct *data);
+
+/*The following definitions come from lib/rpc/server/srv_pipe_hnd.c */
+
+void reset_chain_pnum(void);
+void set_chain_pnum(int new_pnum);
+void init_rpc_pipe_hnd(void);
+int open_rpc_pipe_hnd(char *pipe_name, int cnum, uint16 vuid);
+int read_pipe(uint16 pnum, char *data, uint32 pos, int n);
+BOOL get_rpc_pipe(int pnum, pipes_struct **p);
+char *get_rpc_pipe_hnd_name(int pnum);
+BOOL set_rpc_pipe_hnd_state(pipes_struct *p, uint16 device_state);
+BOOL close_rpc_pipe_hnd(int pnum, int cnum);
+int get_rpc_pipe_num(char *buf, int where);
+
+/*The following definitions come from lib/rpc/server/srv_reg.c */
+
+BOOL api_reg_rpc(pipes_struct *p, prs_struct *data);
+
+/*The following definitions come from lib/rpc/server/srv_samr.c */
+
+BOOL api_samr_rpc(pipes_struct *p, prs_struct *data);
+
+/*The following definitions come from lib/rpc/server/srv_srvsvc.c */
+
+BOOL api_srvsvc_rpc(pipes_struct *p, prs_struct *data);
+
+/*The following definitions come from lib/rpc/server/srv_util.c */
+
+int make_dom_gids(char *gids_str, DOM_GID *gids);
+void get_domain_user_groups(char *domain_groups, char *user);
+BOOL create_rpc_reply(pipes_struct *p,
+ uint32 data_start, uint32 data_end);
+BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, struct api_struct *api_rpc_cmds,
+ prs_struct *data);
+uint32 lookup_group_name(uint32 rid, char *group_name, uint32 *type);
+uint32 lookup_alias_name(uint32 rid, char *alias_name, uint32 *type);
+uint32 lookup_user_name(uint32 rid, char *user_name, uint32 *type);
+uint32 lookup_group_rid(char *group_name, uint32 *rid);
+uint32 lookup_alias_rid(char *alias_name, uint32 *rid);
+uint32 lookup_user_rid(char *user_name, uint32 *rid);
+BOOL name_to_rid(char *user_name, uint32 *u_rid, uint32 *g_rid);
+
+/*The following definitions come from lib/rpc/server/srv_wkssvc.c */
+
+BOOL api_wkssvc_rpc(pipes_struct *p, prs_struct *data);
+
/*The following definitions come from loadparm.c */
char *lp_string(char *s);
@@ -455,6 +1100,24 @@ void smb_mem_write_errors(FILE *outfile);
void smb_mem_set_multiplier(int multiplier);
void *smb_mem_resize(void *ptr,size_t newsize);
+/*The following definitions come from membuffer.c */
+
+void mem_init(struct mem_buf *buf, int margin);
+void mem_create(struct mem_buf *buf, char *data, int size, int margin, BOOL dynamic);
+void mem_take(struct mem_buf *mem_to, struct mem_buf *mem_from);
+BOOL mem_alloc_data(struct mem_buf *buf, int size);
+BOOL mem_buf_copy(char *copy_into, struct mem_buf *buf,
+ uint32 offset, uint32 len);
+BOOL mem_buf_init(struct mem_buf **buf, uint32 margin);
+void mem_buf_free(struct mem_buf **buf);
+void mem_free_chain(struct mem_buf **buf);
+void mem_free_data(struct mem_buf *buf);
+BOOL mem_realloc_data(struct mem_buf *buf, int new_size);
+BOOL mem_grow_data(struct mem_buf **buf, BOOL io, int new_size);
+BOOL mem_find(struct mem_buf **buf, uint32 offset);
+uint32 mem_buf_len(struct mem_buf *buf);
+char *mem_data(struct mem_buf **buf, uint32 offset);
+
/*The following definitions come from message.c */
int reply_sends(char *inbuf,char *outbuf);
@@ -796,11 +1459,6 @@ BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2);
BOOL send_packet(struct packet_struct *p);
struct packet_struct *receive_packet(int fd,enum packet_type type,int t);
-/*The following definitions come from ntclient.c */
-
-BOOL do_nt_login(char *desthost, char *myhostname,
- int Client, int cnum);
-
/*The following definitions come from params.c */
BOOL pm_process( char *FileName,
@@ -820,6 +1478,8 @@ void add_session_user(char *user);
void dfs_unlogin(void);
BOOL password_check(char *password);
BOOL smb_password_check(char *password, unsigned char *part_passwd, unsigned char *c8);
+BOOL smb_password_ok(struct smb_passwd *smb_pass,
+ uchar lm_pass[24], uchar nt_pass[24]);
BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd);
BOOL user_ok(char *user,int snum);
BOOL authorise_login(int snum,char *user,char *password, int pwlen,
@@ -839,12 +1499,8 @@ void pcap_printer_fn(void (*fn)());
/*The following definitions come from pipes.c */
int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize);
+int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize);
int reply_pipe_close(char *inbuf,char *outbuf);
-BOOL api_LsarpcSNPHS(int pnum, int cnum, char *param);
-BOOL api_LsarpcTNP(int cnum,int uid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len);
/*The following definitions come from predict.c */
@@ -937,281 +1593,6 @@ int reply_writebs(char *inbuf,char *outbuf);
int reply_setattrE(char *inbuf,char *outbuf);
int reply_getattrE(char *inbuf,char *outbuf);
-/*The following definitions come from rpc_pipes/lsa_hnd.c */
-
-void init_lsa_policy_hnd(void);
-BOOL open_lsa_policy_hnd(LSA_POL_HND *hnd);
-BOOL set_lsa_policy_samr_rid(LSA_POL_HND *hnd, uint32 rid);
-BOOL set_lsa_policy_samr_pol_status(LSA_POL_HND *hnd, uint32 pol_status);
-BOOL set_lsa_policy_samr_sid(LSA_POL_HND *hnd, DOM_SID *sid);
-uint32 get_lsa_policy_samr_rid(LSA_POL_HND *hnd);
-BOOL close_lsa_policy_hnd(LSA_POL_HND *hnd);
-
-/*The following definitions come from rpc_pipes/lsaparse.c */
-
-void make_q_open_pol(LSA_Q_OPEN_POL *r_q, char *server_name,
- uint32 attributes, uint32 sec_qos,
- uint16 desired_access);
-char* lsa_io_q_open_pol(BOOL io, LSA_Q_OPEN_POL *r_q, char *q, char *base, int align, int depth);
-char* lsa_io_r_open_pol(BOOL io, LSA_R_OPEN_POL *r_p, char *q, char *base, int align, int depth);
-void make_q_query(LSA_Q_QUERY_INFO *q_q, LSA_POL_HND *hnd, uint16 info_class);
-char* lsa_io_q_query(BOOL io, LSA_Q_QUERY_INFO *q_q, char *q, char *base, int align, int depth);
-char* lsa_io_q_enum_trust_dom(BOOL io, LSA_Q_ENUM_TRUST_DOM *q_e, char *q, char *base, int align, int depth);
-void make_r_enum_trust_dom(LSA_R_ENUM_TRUST_DOM *r_e, LSA_POL_HND *hnd, uint32 status);
-char* lsa_io_r_enum_trust_dom(BOOL io, LSA_R_ENUM_TRUST_DOM *r_e, char *q, char *base, int align, int depth);
-void make_q_close(LSA_Q_CLOSE *q_c, LSA_POL_HND *hnd);
-char* lsa_io_q_close(BOOL io, LSA_Q_CLOSE *q_c, char *q, char *base, int align, int depth);
-void make_r_close(LSA_R_CLOSE *q_r, LSA_POL_HND *hnd);
-char* lsa_io_r_close(BOOL io, LSA_R_CLOSE *r_c, char *q, char *base, int align, int depth);
-char* lsa_io_r_query(BOOL io, LSA_R_QUERY_INFO *r_q, char *q, char *base, int align, int depth);
-char* lsa_io_q_lookup_sids(BOOL io, LSA_Q_LOOKUP_SIDS *q_s, char *q, char *base, int align, int depth);
-char* lsa_io_r_lookup_sids(BOOL io, LSA_R_LOOKUP_SIDS *r_s, char *q, char *base, int align, int depth);
-char* lsa_io_q_lookup_rids(BOOL io, LSA_Q_LOOKUP_RIDS *q_r, char *q, char *base, int align, int depth);
-char* lsa_io_r_lookup_rids(BOOL io, LSA_R_LOOKUP_RIDS *r_r, char *q, char *base, int align, int depth);
-void make_q_req_chal(LSA_Q_REQ_CHAL *q_c,
- char *logon_srv, char *logon_clnt,
- DOM_CHAL *clnt_chal);
-char* lsa_io_q_req_chal(BOOL io, LSA_Q_REQ_CHAL *q_c, char *q, char *base, int align, int depth);
-char* lsa_io_r_req_chal(BOOL io, LSA_R_REQ_CHAL *r_c, char *q, char *base, int align, int depth);
-void make_q_auth_2(LSA_Q_AUTH_2 *q_a,
- char *logon_srv, char *acct_name, uint16 sec_chan, char *comp_name,
- DOM_CHAL *clnt_chal, uint32 clnt_flgs);
-char* lsa_io_q_auth_2(BOOL io, LSA_Q_AUTH_2 *q_a, char *q, char *base, int align, int depth);
-char* lsa_io_r_auth_2(BOOL io, LSA_R_AUTH_2 *r_a, char *q, char *base, int align, int depth);
-void make_q_srv_pwset(LSA_Q_SRV_PWSET *q_s, char sess_key[8],
- char *logon_srv, char *acct_name, uint16 sec_chan, char *comp_name,
- DOM_CRED *cred, char nt_cypher[16]);
-char* lsa_io_q_srv_pwset(BOOL io, LSA_Q_SRV_PWSET *q_s, char *q, char *base, int align, int depth);
-char* lsa_io_r_srv_pwset(BOOL io, LSA_R_SRV_PWSET *r_s, char *q, char *base, int align, int depth);
-char* lsa_io_user_info(BOOL io, LSA_USER_INFO *usr, char *q, char *base, int align, int depth);
-char* lsa_io_q_sam_logon(BOOL io, LSA_Q_SAM_LOGON *q_l, char *q, char *base, int align, int depth);
-char* lsa_io_r_sam_logon(BOOL io, LSA_R_SAM_LOGON *r_l, char *q, char *base, int align, int depth);
-char* lsa_io_q_sam_logoff(BOOL io, LSA_Q_SAM_LOGOFF *q_l, char *q, char *base, int align, int depth);
-char* lsa_io_r_sam_logoff(BOOL io, LSA_R_SAM_LOGOFF *r_l, char *q, char *base, int align, int depth);
-
-/*The following definitions come from rpc_pipes/ntclientlsa.c */
-
-BOOL do_lsa_open_policy(uint16 fnum, uint32 call_id,
- char *server_name, LSA_POL_HND *hnd);
-BOOL do_lsa_query_info_pol(uint16 fnum, uint32 call_id,
- LSA_POL_HND *hnd, uint16 info_class,
- fstring domain_name, pstring domain_sid);
-BOOL do_lsa_close(uint16 fnum, uint32 call_id,
- LSA_POL_HND *hnd);
-
-/*The following definitions come from rpc_pipes/ntclientnet.c */
-
-BOOL do_lsa_req_chal(uint16 fnum, uint32 call_id,
- char *desthost, char *myhostname,
- DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal);
-BOOL do_lsa_auth2(uint16 fnum, uint32 call_id,
- char *logon_srv, char *acct_name, uint16 sec_chan, char *comp_name,
- DOM_CHAL *clnt_chal, uint32 neg_flags, DOM_CHAL *srv_chal);
-BOOL do_lsa_srv_pwset(uint16 fnum, uint32 call_id,
- uchar sess_key[8],
- char *logon_srv, char *mach_acct, uint16 sec_chan_type, char *comp_name,
- DOM_CRED *clnt_cred, DOM_CRED *srv_cred,
- char nt_owf_new_mach_pwd[16]);
-BOOL do_lsa_sam_logon(uint16 fnum, uint32 call_id,
- uchar sess_key[8], DOM_CRED *sto_clnt_cred,
- char *logon_srv, char *comp_name,
- DOM_CRED *clnt_cred, DOM_CRED *rtn_cred,
- uint16 logon_level, uint16 switch_value, DOM_ID_INFO_1 *id1,
- LSA_USER_INFO *user_info,
- DOM_CRED *srv_cred);
-BOOL do_lsa_sam_logoff(uint16 fnum, uint32 call_id,
- uchar sess_key[8], DOM_CRED *sto_clnt_cred,
- char *logon_srv, char *comp_name,
- DOM_CRED *clnt_cred, DOM_CRED *rtn_cred,
- uint16 logon_level, uint16 switch_value, DOM_ID_INFO_1 *id1,
- DOM_CRED *srv_cred);
-
-/*The following definitions come from rpc_pipes/ntclientpipe.c */
-
-uint16 rpc_pipe_open(char *inbuf, char *outbuf, char *rname, int Client, int cnum);
-BOOL rpc_pipe_set_hnd_state(char *pipe_name, uint16 fnum, uint16 device_state);
-BOOL rpc_pipe_bind(char *pipe_name, uint16 fnum, uint32 call_id,
- RPC_IFACE *abstract, RPC_IFACE *transfer);
-
-/*The following definitions come from rpc_pipes/pipe_hnd.c */
-
-void reset_chain_pnum(void);
-void init_rpc_pipe_hnd(void);
-int open_rpc_pipe_hnd(char *pipe_name, int cnum);
-char *get_rpc_pipe_hnd_name(int pnum);
-BOOL set_rpc_pipe_hnd_state(int pnum, int cnum, uint16 device_state);
-BOOL close_rpc_pipe_hnd(int pnum, int cnum);
-int get_rpc_pipe_num(char *buf, int where);
-
-/*The following definitions come from rpc_pipes/pipenetlog.c */
-
-BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len);
-
-/*The following definitions come from rpc_pipes/pipentlsa.c */
-
-BOOL api_ntLsarpcTNP(int cnum,int uid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len);
-
-/*The following definitions come from rpc_pipes/pipesamr.c */
-
-BOOL api_samrTNP(int cnum,int uid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len);
-
-/*The following definitions come from rpc_pipes/pipesrvsvc.c */
-
-BOOL api_srvsvcTNP(int cnum,int uid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len);
-
-/*The following definitions come from rpc_pipes/pipeutil.c */
-
-void initrpcreply(char *inbuf, char *q);
-void endrpcreply(char *inbuf, char *q, int datalen, int rtnval, int *rlen);
-BOOL name_to_rid(char *user_name, uint32 *u_rid, uint32 *g_rid);
-char *dom_sid_to_string(DOM_SID *sid);
-int make_dom_sids(char *sids_str, DOM_SID *sids, int max_sids);
-int make_dom_gids(char *gids_str, DOM_GID *gids);
-int create_rpc_request(uint32 call_id, uint8 op_num, char *q, int data_len);
-int create_rpc_reply(uint32 call_id, char *q, int data_len);
-
-/*The following definitions come from rpc_pipes/pipewkssvc.c */
-
-BOOL api_wkssvcTNP(int cnum,int uid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len);
-
-/*The following definitions come from rpc_pipes/samrparse.c */
-
-char* samr_io_q_close(BOOL io, SAMR_Q_CLOSE *q_u, char *q, char *base, int align, int depth);
-char* samr_io_r_close(BOOL io, SAMR_R_CLOSE *r_u, char *q, char *base, int align, int depth);
-char* samr_io_q_open_secret(BOOL io, SAMR_Q_OPEN_SECRET *q_u, char *q, char *base, int align, int depth);
-char* samr_io_r_open_secret(BOOL io, SAMR_R_OPEN_SECRET *r_u, char *q, char *base, int align, int depth);
-char* samr_io_q_lookup_rids(BOOL io, SAMR_Q_LOOKUP_RIDS *q_u, char *q, char *base, int align, int depth);
-void make_samr_r_lookup_rids(SAMR_R_LOOKUP_RIDS *r_u,
- uint32 num_rids, uint32 rid, uint32 status);
-char* samr_io_r_lookup_rids(BOOL io, SAMR_R_LOOKUP_RIDS *r_u, char *q, char *base, int align, int depth);
-char* samr_io_q_unknown_22(BOOL io, SAMR_Q_UNKNOWN_22 *q_u, char *q, char *base, int align, int depth);
-char* samr_io_r_unknown_22(BOOL io, SAMR_R_UNKNOWN_22 *r_u, char *q, char *base, int align, int depth);
-char* samr_io_q_unknown_24(BOOL io, SAMR_Q_UNKNOWN_24 *q_u, char *q, char *base, int align, int depth);
-void make_samr_r_unknown_24(SAMR_R_UNKNOWN_24 *r_u,
- uint16 unknown_0, NTTIME *expiry, char *mach_acct,
- uint32 unknown_id_0, uint32 status);
-char* samr_io_r_unknown_24(BOOL io, SAMR_R_UNKNOWN_24 *r_u, char *q, char *base, int align, int depth);
-char* samr_io_q_unknown_32(BOOL io, SAMR_Q_UNKNOWN_32 *q_u, char *q, char *base, int align, int depth);
-char* samr_io_r_unknown_32(BOOL io, SAMR_R_UNKNOWN_32 *r_u, char *q, char *base, int align, int depth);
-char* samr_io_q_open_policy(BOOL io, SAMR_Q_OPEN_POLICY *q_u, char *q, char *base, int align, int depth);
-char* samr_io_r_open_policy(BOOL io, SAMR_R_OPEN_POLICY *r_u, char *q, char *base, int align, int depth);
-
-/*The following definitions come from rpc_pipes/smbparse.c */
-
-char* smb_io_utime(BOOL io, UTIME *t, char *q, char *base, int align, int depth);
-char* smb_io_time(BOOL io, NTTIME *nttime, char *q, char *base, int align, int depth);
-void make_dom_sid(DOM_SID *sid, char *domsid);
-char* smb_io_dom_sid(BOOL io, DOM_SID *sid, char *q, char *base, int align, int depth);
-void make_uni_hdr(UNIHDR *hdr, int max_len, int len, uint16 terminate);
-char* smb_io_unihdr(BOOL io, UNIHDR *hdr, char *q, char *base, int align, int depth);
-void make_uni_hdr2(UNIHDR2 *hdr, int max_len, int len, uint16 terminate);
-char* smb_io_unihdr2(BOOL io, UNIHDR2 *hdr2, char *q, char *base, int align, int depth);
-void make_unistr(UNISTR *str, char *buf);
-char* smb_io_unistr(BOOL io, UNISTR *uni, char *q, char *base, int align, int depth);
-void make_unistr2(UNISTR2 *str, char *buf, int len);
-char* smb_io_unistr2(BOOL io, UNISTR2 *uni2, char *q, char *base, int align, int depth);
-void make_dom_sid2(DOM_SID2 *sid2, char *sid_str);
-char* smb_io_dom_sid2(BOOL io, DOM_SID2 *sid2, char *q, char *base, int align, int depth);
-void make_dom_rid2(DOM_RID2 *rid2, uint32 rid);
-char* smb_io_dom_rid2(BOOL io, DOM_RID2 *rid2, char *q, char *base, int align, int depth);
-void make_dom_rid3(DOM_RID3 *rid3, uint32 rid);
-char* smb_io_dom_rid3(BOOL io, DOM_RID3 *rid3, char *q, char *base, int align, int depth);
-void make_clnt_srv(DOM_CLNT_SRV *log, char *logon_srv, char *comp_name);
-char* smb_io_clnt_srv(BOOL io, DOM_CLNT_SRV *log, char *q, char *base, int align, int depth);
-void make_log_info(DOM_LOG_INFO *log, char *logon_srv, char *acct_name,
- uint16 sec_chan, char *comp_name);
-char* smb_io_log_info(BOOL io, DOM_LOG_INFO *log, char *q, char *base, int align, int depth);
-char* smb_io_chal(BOOL io, DOM_CHAL *chal, char *q, char *base, int align, int depth);
-char* smb_io_cred(BOOL io, DOM_CRED *cred, char *q, char *base, int align, int depth);
-void make_clnt_info2(DOM_CLNT_INFO2 *clnt,
- char *logon_srv, char *comp_name,
- DOM_CRED *clnt_cred);
-char* smb_io_clnt_info2(BOOL io, DOM_CLNT_INFO2 *clnt, char *q, char *base, int align, int depth);
-char* make_clnt_info(DOM_CLNT_INFO *clnt,
- char *logon_srv, char *acct_name,
- uint16 sec_chan, char *comp_name,
- DOM_CRED *cred);
-char* smb_io_clnt_info(BOOL io, DOM_CLNT_INFO *clnt, char *q, char *base, int align, int depth);
-void make_logon_id(DOM_LOGON_ID *log, uint32 log_id_low, uint32 log_id_high);
-char* smb_io_logon_id(BOOL io, DOM_LOGON_ID *log, char *q, char *base, int align, int depth);
-void make_arc4_owf(ARC4_OWF *hash, char data[16]);
-char* smb_io_arc4_owf(BOOL io, ARC4_OWF *hash, char *q, char *base, int align, int depth);
-void make_id_info1(DOM_ID_INFO_1 *id, char *domain_name,
- uint32 param_ctrl, uint32 log_id_low, uint32 log_id_high,
- char *user_name, char *wksta_name,
- char *sess_key,
- unsigned char lm_cypher[16], unsigned char nt_cypher[16]);
-char* smb_io_id_info1(BOOL io, DOM_ID_INFO_1 *id, char *q, char *base, int align, int depth);
-void make_sam_info(DOM_SAM_INFO *sam,
- char *logon_srv, char *comp_name, DOM_CRED *clnt_cred,
- DOM_CRED *rtn_cred, uint16 logon_level, uint16 switch_value,
- DOM_ID_INFO_1 *id1);
-char* smb_io_sam_info(BOOL io, DOM_SAM_INFO *sam, char *q, char *base, int align, int depth);
-char* smb_io_gid(BOOL io, DOM_GID *gid, char *q, char *base, int align, int depth);
-void make_rpc_hdr(RPC_HDR *hdr, enum RPC_PKT_TYPE pkt_type, uint8 frag,
- uint32 call_id, int data_len);
-char* smb_io_rpc_hdr(BOOL io, RPC_HDR *rpc, char *q, char *base, int align, int depth);
-void make_rpc_iface(RPC_IFACE *ifc, char data[16], uint32 version);
-char* smb_io_rpc_iface(BOOL io, RPC_IFACE *ifc, char *q, char *base, int align, int depth);
-void make_rpc_addr_str(RPC_ADDR_STR *str, char *name);
-char* smb_io_rpc_addr_str(BOOL io, RPC_ADDR_STR *str, char *q, char *base, int align, int depth);
-void make_rpc_hdr_bba(RPC_HDR_BBA *bba, uint16 max_tsize, uint16 max_rsize, uint32 assoc_gid);
-char* smb_io_rpc_hdr_bba(BOOL io, RPC_HDR_BBA *rpc, char *q, char *base, int align, int depth);
-void make_rpc_hdr_rb(RPC_HDR_RB *rpc,
- uint16 max_tsize, uint16 max_rsize, uint32 assoc_gid,
- uint32 num_elements, uint16 context_id, uint8 num_syntaxes,
- RPC_IFACE *abstract, RPC_IFACE *transfer);
-char* smb_io_rpc_hdr_rb(BOOL io, RPC_HDR_RB *rpc, char *q, char *base, int align, int depth);
-void make_rpc_results(RPC_RESULTS *res,
- uint8 num_results, uint16 result, uint16 reason);
-char* smb_io_rpc_results(BOOL io, RPC_RESULTS *res, char *q, char *base, int align, int depth);
-void make_rpc_hdr_ba(RPC_HDR_BA *rpc,
- uint16 max_tsize, uint16 max_rsize, uint32 assoc_gid,
- char *pipe_addr,
- uint8 num_results, uint16 result, uint16 reason,
- RPC_IFACE *transfer);
-char* smb_io_rpc_hdr_ba(BOOL io, RPC_HDR_BA *rpc, char *q, char *base, int align, int depth);
-void make_obj_attr(LSA_OBJ_ATTR *attr, uint32 attributes, uint32 sec_qos);
-char* smb_io_obj_attr(BOOL io, LSA_OBJ_ATTR *attr, char *q, char *base, int align, int depth);
-void make_rpc_hdr_rr(RPC_HDR_RR *hdr, enum RPC_PKT_TYPE pkt_type,
- uint32 call_id, int data_len, uint8 opnum);
-char* smb_io_rpc_hdr_rr(BOOL io, RPC_HDR_RR *rpc, char *q, char *base, int align, int depth);
-char* smb_io_pol_hnd(BOOL io, LSA_POL_HND *pol, char *q, char *base, int align, int depth);
-char* smb_io_dom_query_3(BOOL io, DOM_QUERY_3 *d_q, char *q, char *base, int align, int depth);
-char* smb_io_dom_query_5(BOOL io, DOM_QUERY_3 *d_q, char *q, char *base, int align, int depth);
-char* smb_io_dom_query(BOOL io, DOM_QUERY *d_q, char *q, char *base, int align, int depth);
-char* smb_io_dom_r_ref(BOOL io, DOM_R_REF *r_r, char *q, char *base, int align, int depth);
-char* smb_io_dom_name(BOOL io, DOM_NAME *name, char *q, char *base, int align, int depth);
-char* smb_io_neg_flags(BOOL io, NEG_FLAGS *neg, char *q, char *base, int align, int depth);
-
-/*The following definitions come from rpc_pipes/srvparse.c */
-
-char* srv_io_share_info1_str(BOOL io, SH_INFO_1_STR *sh1, char *q, char *base, int align, int depth);
-char* srv_io_share_info1(BOOL io, SH_INFO_1 *sh1, char *q, char *base, int align, int depth);
-char* srv_io_share_1_ctr(BOOL io, SHARE_INFO_1_CTR *ctr, char *q, char *base, int align, int depth);
-char* srv_io_q_net_share_enum(BOOL io, SRV_Q_NET_SHARE_ENUM *q_n, char *q, char *base, int align, int depth);
-char* srv_io_r_net_share_enum(BOOL io, SRV_R_NET_SHARE_ENUM *r_n, char *q, char *base, int align, int depth);
-
-/*The following definitions come from rpc_pipes/wksparse.c */
-
-char* wks_io_q_unknown_0(BOOL io, WKS_Q_UNKNOWN_0 *q_u, char *q, char *base, int align, int depth);
-char* wks_io_r_unknown_0(BOOL io, WKS_R_UNKNOWN_0 *r_u, char *q, char *base, int align, int depth);
-
/*The following definitions come from server.c */
void *dflt_sig(void);
@@ -1294,10 +1675,13 @@ char *smb_errstr(char *inbuf);
/*The following definitions come from smbpass.c */
-int pw_file_lock(char *name, int type, int secs);
+int pw_file_lock(int fd, int type, int secs);
int pw_file_unlock(int fd);
+FILE *startsmbpwent(BOOL update);
+void endsmbpwent(FILE *fp);
+struct smb_passwd *getsmbpwent(FILE *fp);
struct smb_passwd *get_smbpwd_entry(char *name, int smb_userid);
-BOOL add_smbpwd_entry(struct smb_passwd* pwd);
+BOOL add_smbpwd_entry(struct smb_passwd *newpwd);
BOOL mod_smbpwd_entry(struct smb_passwd* pwd);
/*The following definitions come from status.c */
@@ -1343,6 +1727,7 @@ void put_dos_date3(char *buf,int offset,time_t unixdate);
time_t make_unix_date(void *date_ptr);
time_t make_unix_date2(void *date_ptr);
time_t make_unix_date3(void *date_ptr);
+char *http_timestring(time_t t);
char *timestring(void );
time_t get_create_time(struct stat *st);
@@ -1523,3 +1908,4 @@ char *align_offset(char *q, char *base, int align_offset_len);
void print_asc(int level, unsigned char *buf,int len);
void dump_data(int level,char *buf1,int len);
char *tab_depth(int depth);
+char *dom_sid_to_string(DOM_SID *sid);
diff --git a/source3/include/rpc_dce.h b/source3/include/rpc_dce.h
new file mode 100644
index 0000000000..9aacaaab87
--- /dev/null
+++ b/source3/include/rpc_dce.h
@@ -0,0 +1,211 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB parameters and setup
+ Copyright (C) Andrew Tridgell 1992-1997
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1997
+ Copyright (C) Paul Ashton 1997
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _DCE_RPC_H /* _DCE_RPC_H */
+#define _DCE_RPC_H
+
+#include "rpc_misc.h" /* this only pulls in STRHDR */
+
+
+/* DCE/RPC packet types */
+
+enum RPC_PKT_TYPE
+{
+ RPC_REQUEST = 0x00,
+ RPC_RESPONSE = 0x02,
+ RPC_BIND = 0x0B,
+ RPC_BINDACK = 0x0C
+};
+
+/* DCE/RPC flags */
+#define RPC_FLG_FIRST 0x01
+#define RPC_FLG_LAST 0x02
+
+
+/* RPC_IFACE */
+typedef struct rpc_iface_info
+{
+ uint8 data[16]; /* 16 bytes of rpc interface identification */
+ uint32 version; /* the interface version number */
+
+} RPC_IFACE;
+
+struct pipe_id_info
+{
+ /* the names appear not to matter: the syntaxes _do_ matter */
+
+ char *client_pipe;
+ RPC_IFACE abstr_syntax; /* this one is the abstract syntax id */
+
+ char *server_pipe; /* this one is the secondary syntax name */
+ RPC_IFACE trans_syntax; /* this one is the primary syntax id */
+};
+
+/* RPC_HDR - dce rpc header */
+typedef struct rpc_hdr_info
+{
+ uint8 major; /* 5 - RPC major version */
+ uint8 minor; /* 0 - RPC minor version */
+ uint8 pkt_type; /* RPC_PKT_TYPE - RPC response packet */
+ uint8 flags; /* DCE/RPC flags */
+ uint32 pack_type; /* 0x1000 0000 - packed data representation */
+ uint16 frag_len; /* fragment length - data size (bytes) inc header and tail. */
+ uint16 auth_len; /* 0 - authentication length */
+ uint32 call_id; /* call identifier. matches 12th uint32 of incoming RPC data. */
+
+} RPC_HDR;
+
+/* RPC_HDR_RR - ms request / response rpc header */
+typedef struct rpc_hdr_rr_info
+{
+ uint32 alloc_hint; /* allocation hint - data size (bytes) minus header and tail. */
+ uint8 context_id; /* 0 - presentation context identifier */
+ uint8 cancel_count; /* 0 - cancel count */
+ uint8 opnum; /* opnum */
+ uint8 reserved; /* 0 - reserved. */
+
+} RPC_HDR_RR;
+
+/* this seems to be the same string name depending on the name of the pipe,
+ * but is more likely to be linked to the interface name
+ * "srvsvc", "\\PIPE\\ntsvcs"
+ * "samr", "\\PIPE\\lsass"
+ * "wkssvc", "\\PIPE\\wksvcs"
+ * "NETLOGON", "\\PIPE\\NETLOGON"
+ */
+/* RPC_ADDR_STR */
+typedef struct rpc_addr_info
+{
+ uint16 len; /* length of the string including null terminator */
+ fstring str; /* the string above in single byte, null terminated form */
+
+} RPC_ADDR_STR;
+
+/* RPC_HDR_BBA */
+typedef struct rpc_hdr_bba_info
+{
+ uint16 max_tsize; /* maximum transmission fragment size (0x1630) */
+ uint16 max_rsize; /* max receive fragment size (0x1630) */
+ uint32 assoc_gid; /* associated group id (0x0) */
+
+} RPC_HDR_BBA;
+
+/* RPC_BIND_REQ - ms req bind */
+typedef struct rpc_bind_req_info
+{
+ RPC_HDR_BBA bba;
+
+ uint32 num_elements; /* the number of elements (0x1) */
+ uint16 context_id; /* presentation context identifier (0x0) */
+ uint8 num_syntaxes; /* the number of syntaxes (has always been 1?)(0x1) */
+
+ RPC_IFACE abstract; /* num and vers. of interface client is using */
+ RPC_IFACE transfer; /* num and vers. of interface to use for replies */
+
+} RPC_HDR_RB;
+
+/* RPC_RESULTS - can only cope with one reason, right now... */
+typedef struct rpc_results_info
+{
+/* uint8[] # 4-byte alignment padding, against SMB header */
+
+ uint8 num_results; /* the number of results (0x01) */
+
+/* uint8[] # 4-byte alignment padding, against SMB header */
+
+ uint16 result; /* result (0x00 = accept) */
+ uint16 reason; /* reason (0x00 = no reason specified) */
+
+} RPC_RESULTS;
+
+/* RPC_HDR_BA */
+typedef struct rpc_hdr_ba_info
+{
+ RPC_HDR_BBA bba;
+
+ RPC_ADDR_STR addr ; /* the secondary address string, as described earlier */
+ RPC_RESULTS res ; /* results and reasons */
+ RPC_IFACE transfer; /* the transfer syntax from the request */
+
+} RPC_HDR_BA;
+
+/* this is TEMPORARY */
+/* RPC_AUTH_VERIFIER */
+typedef struct rpc_auth_verif_info
+{
+ fstring ssp_str;
+ uint32 ssp_ver;
+
+} RPC_AUTH_VERIFIER;
+
+/* this is TEMPORARILY coded up as a specific structure */
+/* this structure comes after the bind request */
+/* RPC_AUTH_NTLMSSP_REQ */
+typedef struct rpc_auth_ntlmssp_req_info
+{
+ fstring ntlmssp_str; /* "NTLMSSP" */
+ uint32 ntlmssp_ver; /* 0x0000 0001 */
+
+ uint32 unknown_0; /* 0x00b2b3 */
+ STRHDR hdr_myname; /* offset is against START of this structure */
+ STRHDR hdr_domain; /* offset is against START of this structure */
+
+ fstring myname; /* calling workstation's name */
+ fstring domain; /* calling workstations's domain */
+
+} RPC_AUTH_NTLMSSP_REQ;
+
+/* this is TEMPORARILY coded up as a specific structure */
+/* this structure comes after the bind acknowledgement */
+/* RPC_AUTH_NTLMSSP_RESP */
+typedef struct rpc_auth_ntlmssp_resp_info
+{
+ uint8 auth_type; /* 0x0a */
+ uint8 auth_level; /* 0x06 */
+ uint8 stub_type_len; /* don't know */
+ uint8 padding; /* padding */
+
+ uint32 ptr_0; /* non-zero pointer to something */
+
+ fstring ntlmssp_str; /* "NTLMSSP" */
+ uint32 ntlmssp_ver; /* 0x0000 0002 */
+
+ uint32 unknown_1; /* 0x0000 0000 */
+ uint32 unknown_2; /* 0x00b2b3 */
+ uint32 unknown_3; /* 0x0082b1 */
+
+ uint8 data[16]; /* 0x10 bytes of something */
+
+} RPC_AUTH_NTLMSSP_RESP;
+
+/* attached to the end of encrypted rpc requests and responses */
+/* RPC_AUTH_NTLMSSP_CHK */
+typedef struct rpc_auth_ntlmssp_chk_info
+{
+ uint32 ver; /* 0x1 */
+ uint8 data[12];
+
+} RPC_AUTH_NTLMSSP_CHK;
+
+#endif /* _DCE_RPC_H */
+
diff --git a/source3/include/rpc_lsa.h b/source3/include/rpc_lsa.h
new file mode 100644
index 0000000000..008f8866c0
--- /dev/null
+++ b/source3/include/rpc_lsa.h
@@ -0,0 +1,288 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB parameters and setup
+ Copyright (C) Andrew Tridgell 1992-1997
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1997
+ Copyright (C) Paul Ashton 1997
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _RPC_LSA_H /* _RPC_LSA_H */
+#define _RPC_LSA_H
+
+#include "rpc_misc.h"
+
+enum SID_NAME_USE
+{
+ SID_NAME_USER = 1,
+ SID_NAME_DOM_GRP = 2, /* domain group */
+ SID_NAME_WKN_GRP = 5 /* well-known group */
+};
+
+/* ntlsa pipe */
+#define LSA_OPENPOLICY 0x2c
+#define LSA_QUERYINFOPOLICY 0x07
+#define LSA_ENUMTRUSTDOM 0x0d
+#define LSA_CLOSE 0x00
+#define LSA_OPENSECRET 0x1C
+#define LSA_LOOKUPSIDS 0x0f
+
+/* XXXX these are here to get a compile! */
+#define LSA_LOOKUPRIDS 0xFD
+#define LSA_LOOKUPNAMES 0xFC
+
+#define LSA_MAX_GROUPS 32
+#define LSA_MAX_SIDS 32
+
+/* DOM_QUERY - info class 3 and 5 LSA Query response */
+typedef struct dom_query_info
+{
+ uint16 uni_dom_max_len; /* domain name string length * 2 */
+ uint16 uni_dom_str_len; /* domain name string length * 2 */
+ uint32 buffer_dom_name; /* undocumented domain name string buffer pointer */
+ uint32 buffer_dom_sid; /* undocumented domain SID string buffer pointer */
+ UNISTR2 uni_domain_name; /* domain name (unicode string) */
+ DOM_SID2 dom_sid; /* domain SID */
+
+} DOM_QUERY;
+
+/* level 5 is same as level 3. we hope. */
+typedef DOM_QUERY DOM_QUERY_3;
+typedef DOM_QUERY DOM_QUERY_5;
+
+
+typedef struct obj_attr_info
+{
+ uint32 len; /* 0x18 - length (in bytes) inc. the length field. */
+ uint32 ptr_root_dir; /* 0 - root directory (pointer) */
+ uint32 ptr_obj_name; /* 0 - object name (pointer) */
+ uint32 attributes; /* 0 - attributes (undocumented) */
+ uint32 ptr_sec_desc; /* 0 - security descriptior (pointer) */
+ uint32 sec_qos; /* 0 - security quality of service */
+
+} LSA_OBJ_ATTR;
+
+/* LSA_Q_OPEN_POL - LSA Query Open Policy */
+typedef struct lsa_q_open_pol_info
+{
+ uint32 ptr; /* undocumented buffer pointer */
+ UNISTR2 uni_server_name; /* server name, starting with two '\'s */
+ LSA_OBJ_ATTR attr ; /* object attributes */
+
+ uint32 des_access; /* desired access attributes */
+
+} LSA_Q_OPEN_POL;
+
+/* LSA_R_OPEN_POL - response to LSA Open Policy */
+typedef struct lsa_r_open_pol_info
+{
+ POLICY_HND pol; /* policy handle */
+ uint32 status; /* return code */
+
+} LSA_R_OPEN_POL;
+
+/* LSA_Q_QUERY_INFO - LSA query info policy */
+typedef struct lsa_query_info
+{
+ POLICY_HND pol; /* policy handle */
+ uint16 info_class; /* info class */
+
+} LSA_Q_QUERY_INFO;
+
+/* LSA_R_QUERY_INFO - response to LSA query info policy */
+typedef struct lsa_r_query_info
+{
+ uint32 undoc_buffer; /* undocumented buffer pointer */
+ uint16 info_class; /* info class (same as info class in request) */
+
+ union
+ {
+ DOM_QUERY_3 id3;
+ DOM_QUERY_5 id5;
+
+ } dom;
+
+ uint32 status; /* return code */
+
+} LSA_R_QUERY_INFO;
+
+/* LSA_Q_ENUM_TRUST_DOM - LSA enumerate trusted domains */
+typedef struct lsa_enum_trust_dom_info
+{
+ POLICY_HND pol; /* policy handle */
+ uint32 enum_context; /* enumeration context handle */
+ uint32 preferred_len; /* preferred maximum length */
+
+} LSA_Q_ENUM_TRUST_DOM;
+
+/* LSA_R_ENUM_TRUST_DOM - response to LSA enumerate trusted domains */
+typedef struct lsa_r_enum_trust_dom_info
+{
+ uint32 enum_context; /* enumeration context handle */
+ uint32 num_domains; /* number of domains */
+ uint32 ptr_enum_domains; /* buffer pointer to num domains */
+
+ /* this lot is only added if ptr_enum_domains is non-NULL */
+ uint32 num_domains2; /* number of domains */
+ UNIHDR2 hdr_domain_name;
+ UNISTR2 uni_domain_name;
+ DOM_SID2 other_domain_sid;
+
+ uint32 status; /* return code */
+
+} LSA_R_ENUM_TRUST_DOM;
+
+/* LSA_Q_CLOSE */
+typedef struct lsa_q_close_info
+{
+ POLICY_HND pol; /* policy handle */
+
+} LSA_Q_CLOSE;
+
+/* LSA_R_CLOSE */
+typedef struct lsa_r_close_info
+{
+ POLICY_HND pol; /* policy handle. should be all zeros. */
+
+ uint32 status; /* return code */
+
+} LSA_R_CLOSE;
+
+
+#define MAX_REF_DOMAINS 10
+
+/* DOM_R_REF */
+typedef struct dom_ref_info
+{
+ uint32 undoc_buffer; /* undocumented buffer pointer. */
+ uint32 num_ref_doms_1; /* num referenced domains? */
+ uint32 buffer_dom_name; /* undocumented domain name buffer pointer. */
+ uint32 max_entries; /* 32 - max number of entries */
+ uint32 num_ref_doms_2; /* 4 - num referenced domains? */
+
+ UNIHDR2 hdr_dom_name; /* domain name unicode string header */
+ UNIHDR2 hdr_ref_dom[MAX_REF_DOMAINS]; /* referenced domain unicode string headers */
+
+ UNISTR uni_dom_name; /* domain name unicode string */
+ DOM_SID2 ref_dom[MAX_REF_DOMAINS]; /* referenced domain SIDs */
+
+} DOM_R_REF;
+
+/* LSA_TRANS_NAME - translated name */
+typedef struct lsa_trans_name_info
+{
+ uint32 sid_name_use; /* value is 5 for a well-known group; 2 for a domain group; 1 for a user... */
+
+ UNIHDR hdr_name;
+ UNISTR2 uni_name;
+
+ uint32 domain_idx;
+
+} LSA_TRANS_NAME;
+
+#define MAX_LOOKUP_SIDS 10
+
+/* LSA_TRANS_NAME_ENUM - LSA Translated Name Enumeration container */
+typedef struct lsa_trans_name_enum_info
+{
+ uint32 num_entries;
+ uint32 ptr_trans_names;
+ uint32 num_entries2;
+
+ uint32 ptr_name[MAX_LOOKUP_SIDS]; /* translated name pointers */
+ LSA_TRANS_NAME name [MAX_LOOKUP_SIDS]; /* translated names */
+
+} LSA_TRANS_NAME_ENUM;
+
+/* LSA_SID_ENUM - LSA SID enumeration container */
+typedef struct lsa_sid_enum_info
+{
+ uint32 num_entries;
+ uint32 ptr_sid_enum;
+ uint32 num_entries2;
+
+ uint32 ptr_sid[MAX_LOOKUP_SIDS]; /* domain SID pointers to be looked up. */
+ DOM_SID2 sid [MAX_LOOKUP_SIDS]; /* domain SIDs to be looked up. */
+
+} LSA_SID_ENUM;
+
+/* LSA_Q_LOOKUP_SIDS - LSA Lookup SIDs */
+typedef struct lsa_q_lookup_sids
+{
+ POLICY_HND pol_hnd; /* policy handle */
+ LSA_SID_ENUM sids;
+ LSA_TRANS_NAME_ENUM names;
+ LOOKUP_LEVEL level;
+ uint32 mapped_count;
+
+} LSA_Q_LOOKUP_SIDS;
+
+/* LSA_R_LOOKUP_SIDS - response to LSA Lookup SIDs */
+typedef struct lsa_r_lookup_sids
+{
+ DOM_R_REF *dom_ref; /* domain reference info */
+ LSA_TRANS_NAME_ENUM *names;
+ uint32 mapped_count;
+
+ uint32 status; /* return code */
+
+} LSA_R_LOOKUP_SIDS;
+
+/* DOM_NAME - XXXX not sure about this structure */
+typedef struct dom_name_info
+{
+ uint32 uni_str_len;
+ UNISTR str;
+
+} DOM_NAME;
+
+
+#define UNKNOWN_LEN 1
+
+/* LSA_Q_LOOKUP_RIDS - LSA Lookup RIDs */
+typedef struct lsa_q_lookup_rids
+{
+ POLICY_HND pol_hnd; /* policy handle */
+ uint32 num_entries;
+ uint32 num_entries2;
+ uint32 buffer_dom_sid; /* undocumented domain SID buffer pointer */
+ uint32 buffer_dom_name; /* undocumented domain name buffer pointer */
+ DOM_NAME lookup_name[MAX_LOOKUP_SIDS]; /* names to be looked up */
+ uint8 undoc[UNKNOWN_LEN]; /* completely undocumented bytes of unknown length */
+
+} LSA_Q_LOOKUP_RIDS;
+
+/* LSA_R_LOOKUP_RIDS - response to LSA Lookup RIDs by name */
+typedef struct lsa_r_lookup_rids
+{
+ DOM_R_REF dom_ref; /* domain reference info */
+
+ uint32 num_entries;
+ uint32 undoc_buffer; /* undocumented buffer pointer */
+
+ uint32 num_entries2;
+ DOM_RID2 dom_rid[MAX_LOOKUP_SIDS]; /* domain RIDs being looked up */
+
+ uint32 num_entries3;
+
+ uint32 status; /* return code */
+
+} LSA_R_LOOKUP_RIDS;
+
+
+#endif /* _RPC_LSA_H */
+
diff --git a/source3/include/rpc_misc.h b/source3/include/rpc_misc.h
new file mode 100644
index 0000000000..5d4e385875
--- /dev/null
+++ b/source3/include/rpc_misc.h
@@ -0,0 +1,272 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB parameters and setup
+ Copyright (C) Andrew Tridgell 1992-1997
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1997
+ Copyright (C) Paul Ashton 1997
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _RPC_MISC_H /* _RPC_MISC_H */
+#define _RPC_MISC_H
+
+
+#include "rpc_dce.h"
+
+/* pipe string names */
+#define PIPE_SRVSVC "\\PIPE\\srvsvc"
+#define PIPE_SAMR "\\PIPE\\samr"
+#define PIPE_WINREG "\\PIPE\\winreg"
+#define PIPE_WKSSVC "\\PIPE\\wkssvc"
+#define PIPE_NETLOGON "\\PIPE\\NETLOGON"
+#define PIPE_NTLSA "\\PIPE\\ntlsa"
+#define PIPE_NTSVCS "\\PIPE\\ntsvcs"
+#define PIPE_LSASS "\\PIPE\\lsass"
+#define PIPE_LSARPC "\\PIPE\\lsarpc"
+
+/* well-known RIDs - Relative IDs */
+
+/* RIDs - Well-known users ... */
+#define DOMAIN_USER_RID_ADMIN (0x000001F4L)
+#define DOMAIN_USER_RID_GUEST (0x000001F5L)
+
+/* RIDs - well-known groups ... */
+#define DOMAIN_GROUP_RID_ADMINS (0x00000200L)
+#define DOMAIN_GROUP_RID_USERS (0x00000201L)
+#define DOMAIN_GROUP_RID_GUESTS (0x00000202L)
+
+/* RIDs - well-known aliases ... */
+#define DOMAIN_ALIAS_RID_ADMINS (0x00000220L)
+#define DOMAIN_ALIAS_RID_USERS (0x00000221L)
+#define DOMAIN_ALIAS_RID_GUESTS (0x00000222L)
+#define DOMAIN_ALIAS_RID_POWER_USERS (0x00000223L)
+
+#define DOMAIN_ALIAS_RID_ACCOUNT_OPS (0x00000224L)
+#define DOMAIN_ALIAS_RID_SYSTEM_OPS (0x00000225L)
+#define DOMAIN_ALIAS_RID_PRINT_OPS (0x00000226L)
+#define DOMAIN_ALIAS_RID_BACKUP_OPS (0x00000227L)
+
+#define DOMAIN_ALIAS_RID_REPLICATOR (0x00000228L)
+
+/* ENUM_HND */
+typedef struct enum_hnd_info
+{
+ uint32 ptr_hnd; /* pointer to enumeration handle */
+ uint32 handle; /* enumeration handle */
+
+} ENUM_HND;
+
+/* LOOKUP_LEVEL - switch value */
+typedef struct lookup_level_info
+{
+ uint16 value;
+
+} LOOKUP_LEVEL;
+
+#define MAXSUBAUTHS 15 /* max sub authorities in a SID */
+
+/* DOM_SID - security id */
+typedef struct sid_info
+{
+ uint8 sid_rev_num; /* SID revision number */
+ uint8 num_auths; /* number of sub-authorities */
+ uint8 id_auth[6]; /* Identifier Authority */
+ uint32 sub_auths[MAXSUBAUTHS]; /* pointer to sub-authorities. */
+
+} DOM_SID;
+
+/* DOM_SID2 - security id */
+typedef struct sid_info_2
+{
+ uint32 num_auths; /* length, bytes, including length of len :-) */
+
+ DOM_SID sid;
+
+} DOM_SID2;
+
+/* STRHDR - string header */
+typedef struct header_info
+{
+ uint16 str_max_len;
+ uint16 str_str_len;
+ uint32 buffer; /* non-zero */
+
+} STRHDR;
+
+/* UNIHDR - unicode string header */
+typedef struct unihdr_info
+{
+ uint16 uni_max_len;
+ uint16 uni_str_len;
+ uint32 buffer; /* usually has a value of 4 */
+
+} UNIHDR;
+
+/* UNIHDR2 - unicode string header and undocumented buffer */
+typedef struct unihdr2_info
+{
+ UNIHDR unihdr;
+ uint32 buffer; /* 32 bit buffer pointer */
+
+} UNIHDR2;
+
+/* clueless as to what maximum length should be */
+#define MAX_UNISTRLEN 256
+#define MAX_STRINGLEN 256
+
+/* UNISTR - unicode string size and buffer */
+typedef struct unistr_info
+{
+ uint16 buffer[MAX_UNISTRLEN]; /* unicode characters. ***MUST*** be null-terminated */
+
+} UNISTR;
+
+/* UNINOTSTR2 - unicode string, size (in uint8 ascii chars) and buffer */
+/* pathetic. some stupid team of \PIPE\winreg writers got the concept */
+/* of a unicode string different from the other \PIPE\ writers */
+typedef struct uninotstr2_info
+{
+ uint32 uni_max_len;
+ uint32 undoc;
+ uint32 uni_buf_len;
+ uint16 buffer[MAX_UNISTRLEN]; /* unicode characters. **NOT** necessarily null-terminated */
+
+} UNINOTSTR2;
+
+/* UNISTR2 - unicode string size (in uint16 unicode chars) and buffer */
+typedef struct unistr2_info
+{
+ uint32 uni_max_len;
+ uint32 undoc;
+ uint32 uni_str_len;
+ uint16 buffer[MAX_UNISTRLEN]; /* unicode characters. **NOT** necessarily null-terminated */
+
+} UNISTR2;
+
+/* STRING2 - string size (in uint8 chars) and buffer */
+typedef struct string2_info
+{
+ uint32 str_max_len;
+ uint32 undoc;
+ uint32 str_str_len;
+ uint8 buffer[MAX_STRINGLEN]; /* uint8 characters. **NOT** necessarily null-terminated */
+
+} STRING2;
+
+
+/* DOM_RID2 - domain RID structure for ntlsa pipe */
+typedef struct domrid2_info
+{
+ uint32 type; /* value is 5 */
+ uint32 undoc; /* value is non-zero */
+ uint32 rid;
+ uint32 rid_idx; /* don't know what this is */
+
+} DOM_RID2;
+
+/* DOM_RID3 - domain RID structure for samr pipe */
+typedef struct domrid3_info
+{
+ uint32 rid; /* domain-relative (to a SID) id */
+ uint32 type1; /* value is 0x1 */
+ uint32 ptr_type; /* undocumented pointer */
+ uint32 type2; /* value is 0x1 */
+
+} DOM_RID3;
+
+/* DOM_RID4 - rid + user attributes */
+typedef struct domrid4_info
+{
+ uint32 unknown;
+ uint16 attr;
+ uint32 rid; /* user RID */
+
+} DOM_RID4;
+
+/* DOM_CLNT_SRV - client / server names */
+typedef struct clnt_srv_info
+{
+ uint32 undoc_buffer; /* undocumented 32 bit buffer pointer */
+ UNISTR2 uni_logon_srv; /* logon server name */
+ uint32 undoc_buffer2; /* undocumented 32 bit buffer pointer */
+ UNISTR2 uni_comp_name; /* client machine name */
+
+} DOM_CLNT_SRV;
+
+/* DOM_LOG_INFO - login info */
+typedef struct log_info
+{
+ uint32 undoc_buffer; /* undocumented 32 bit buffer pointer */
+ UNISTR2 uni_logon_srv; /* logon server name */
+ UNISTR2 uni_acct_name; /* account name */
+ uint16 sec_chan; /* secure channel type */
+ UNISTR2 uni_comp_name; /* client machine name */
+
+} DOM_LOG_INFO;
+
+/* DOM_CLNT_INFO - client info */
+typedef struct clnt_info
+{
+ DOM_LOG_INFO login;
+ DOM_CRED cred;
+
+} DOM_CLNT_INFO;
+
+/* DOM_CLNT_INFO2 - client info */
+typedef struct clnt_info2
+{
+ DOM_CLNT_SRV login;
+ uint32 ptr_cred;
+ DOM_CRED cred;
+
+} DOM_CLNT_INFO2;
+
+/* DOM_LOGON_ID - logon id */
+typedef struct logon_info
+{
+ uint32 low;
+ uint32 high;
+
+} DOM_LOGON_ID;
+
+/* ARC4_OWF */
+typedef struct arc4_owf_info
+{
+ uint8 data[16];
+
+} ARC4_OWF;
+
+
+/* DOM_GID - group id + user attributes */
+typedef struct gid_info
+{
+ uint32 g_rid; /* a group RID */
+ uint32 attr;
+
+} DOM_GID;
+
+#define POL_HND_SIZE 20
+
+/* POLICY_HND */
+typedef struct lsa_policy_info
+{
+ uint8 data[POL_HND_SIZE]; /* policy handle */
+
+} POLICY_HND;
+
+#endif /* _RPC_MISC_H */
+
diff --git a/source3/include/rpc_netlogon.h b/source3/include/rpc_netlogon.h
new file mode 100644
index 0000000000..1808649328
--- /dev/null
+++ b/source3/include/rpc_netlogon.h
@@ -0,0 +1,372 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB parameters and setup
+ Copyright (C) Andrew Tridgell 1992-1997
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1997
+ Copyright (C) Paul Ashton 1997
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _RPC_NETLOGON_H /* _RPC_NETLOGON_H */
+#define _RPC_NETLOGON_H
+
+
+/* NETLOGON pipe */
+#define NET_REQCHAL 0x04
+#define NET_SRVPWSET 0x06
+#define NET_SAMLOGON 0x02
+#define NET_SAMLOGOFF 0x03
+#define NET_AUTH2 0x0f
+#define NET_LOGON_CTRL2 0x0e
+#define NET_TRUST_DOM_LIST 0x13
+
+/* Secure Channel types. used in NetrServerAuthenticate negotiation */
+#define SEC_CHAN_WKSTA 2
+#define SEC_CHAN_DOMAIN 4
+
+
+/* NET_USER_INFO_3 */
+typedef struct net_user_info_3
+{
+ uint32 ptr_user_info;
+
+ 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_logon_script; /* logon script unicode string header */
+ UNIHDR hdr_profile_path; /* profile path unicode string header */
+ UNIHDR hdr_home_dir; /* home directory unicode string header */
+ UNIHDR hdr_dir_drive; /* home directory drive unicode string header */
+
+ uint16 logon_count; /* logon count */
+ uint16 bad_pw_count; /* bad password count */
+
+ uint32 user_id; /* User ID */
+ uint32 group_id; /* Group ID */
+ uint32 num_groups; /* num groups */
+ uint32 buffer_groups; /* undocumented buffer pointer to groups. */
+ uint32 user_flgs; /* user flags */
+
+ uint8 user_sess_key[16]; /* unused user session key */
+
+ UNIHDR hdr_logon_srv; /* logon server unicode string header */
+ UNIHDR hdr_logon_dom; /* logon domain unicode string header */
+
+ uint32 buffer_dom_id; /* undocumented logon domain id pointer */
+ uint8 padding[40]; /* unused padding bytes. expansion room */
+
+ uint32 num_other_sids; /* 0 - num_sids */
+ uint32 buffer_other_sids; /* NULL - undocumented pointer to SIDs. */
+
+ UNISTR2 uni_user_name; /* username unicode string */
+ UNISTR2 uni_full_name; /* user's full name unicode string */
+ UNISTR2 uni_logon_script; /* logon script unicode string */
+ UNISTR2 uni_profile_path; /* profile path unicode string */
+ UNISTR2 uni_home_dir; /* home directory unicode string */
+ UNISTR2 uni_dir_drive; /* home directory drive unicode string */
+
+ uint32 num_groups2; /* num groups */
+ DOM_GID gids[LSA_MAX_GROUPS]; /* group info */
+
+ UNISTR2 uni_logon_srv; /* logon server unicode string */
+ UNISTR2 uni_logon_dom; /* logon domain unicode string */
+
+ DOM_SID2 dom_sid; /* domain SID */
+ DOM_SID2 other_sids[LSA_MAX_SIDS]; /* undocumented - domain SIDs */
+
+} NET_USER_INFO_3;
+
+
+/********************************************************
+ Logon Control Query
+
+ query_level 0x1 - pdc status
+ query_level 0x3 - number of logon attempts.
+
+ ********************************************************/
+/* NET_Q_LOGON_CTRL2 - LSA Netr Logon Control 2*/
+typedef struct net_q_logon_ctrl2_info
+{
+ uint32 ptr; /* undocumented buffer pointer */
+ UNISTR2 uni_server_name; /* server name, starting with two '\'s */
+
+ uint32 function_code; /* 0x1 */
+ uint32 query_level; /* 0x1, 0x3 */
+ uint32 switch_value; /* 0x1 */
+
+} NET_Q_LOGON_CTRL2;
+
+/* NETLOGON_INFO_1 - pdc status info, i presume */
+typedef struct netlogon_1_info
+{
+ uint32 flags; /* 0x0 - undocumented */
+ uint32 pdc_status; /* 0x0 - undocumented */
+
+} NETLOGON_INFO_1;
+
+/* NETLOGON_INFO_2 - pdc status info, plus trusted domain info */
+typedef struct netlogon_2_info
+{
+ uint32 flags; /* 0x0 - undocumented */
+ uint32 pdc_status; /* 0x0 - undocumented */
+ uint32 ptr_trusted_dc_name; /* pointer to trusted domain controller name */
+ uint32 tc_status; /* 0x051f - ERROR_NO_LOGON_SERVERS */
+ UNISTR2 uni_trusted_dc_name; /* unicode string - trusted dc name */
+
+} NETLOGON_INFO_2;
+
+/* NETLOGON_INFO_3 - logon status info, i presume */
+typedef struct netlogon_3_info
+{
+ uint32 flags; /* 0x0 - undocumented */
+ uint32 logon_attempts; /* number of logon attempts */
+ uint32 reserved_1; /* 0x0 - undocumented */
+ uint32 reserved_2; /* 0x0 - undocumented */
+ uint32 reserved_3; /* 0x0 - undocumented */
+ uint32 reserved_4; /* 0x0 - undocumented */
+ uint32 reserved_5; /* 0x0 - undocumented */
+
+} NETLOGON_INFO_3;
+
+/*******************************************************
+ Logon Control Response
+
+ switch_value is same as query_level in request
+ *******************************************************/
+
+/* NET_R_LOGON_CTRL2 - response to LSA Logon Control2 */
+typedef struct net_r_logon_ctrl2_info
+{
+ uint32 switch_value; /* 0x1, 0x3 */
+ uint32 ptr;
+
+ union
+ {
+ NETLOGON_INFO_1 info1;
+ NETLOGON_INFO_2 info2;
+ NETLOGON_INFO_3 info3;
+
+ } logon;
+
+ uint32 status; /* return code */
+
+} NET_R_LOGON_CTRL2;
+
+/* NET_Q_TRUST_DOM_LIST - LSA Query Trusted Domains */
+typedef struct net_q_trust_dom_info
+{
+ uint32 ptr; /* undocumented buffer pointer */
+ UNISTR2 uni_server_name; /* server name, starting with two '\'s */
+
+ uint32 function_code; /* 0x31 */
+
+} NET_Q_TRUST_DOM_LIST;
+
+#define MAX_TRUST_DOMS 1
+
+/* NET_R_TRUST_DOM_LIST - response to LSA Trusted Domains */
+typedef struct net_r_trust_dom_info
+{
+ UNISTR2 uni_trust_dom_name[MAX_TRUST_DOMS];
+
+ uint32 status; /* return code */
+
+} NET_R_TRUST_DOM_LIST;
+
+
+/* NEG_FLAGS */
+typedef struct neg_flags_info
+{
+ uint32 neg_flags; /* negotiated flags */
+
+} NEG_FLAGS;
+
+
+/* NET_Q_REQ_CHAL */
+typedef struct net_q_req_chal_info
+{
+ uint32 undoc_buffer; /* undocumented buffer pointer */
+ UNISTR2 uni_logon_srv; /* logon server unicode string */
+ UNISTR2 uni_logon_clnt; /* logon client unicode string */
+ DOM_CHAL clnt_chal; /* client challenge */
+
+} NET_Q_REQ_CHAL;
+
+
+/* NET_R_REQ_CHAL */
+typedef struct net_r_req_chal_info
+{
+ DOM_CHAL srv_chal; /* server challenge */
+
+ uint32 status; /* return code */
+
+} NET_R_REQ_CHAL;
+
+
+
+/* NET_Q_AUTH_2 */
+typedef struct net_q_auth2_info
+{
+ DOM_LOG_INFO clnt_id; /* client identification info */
+ DOM_CHAL clnt_chal; /* client-calculated credentials */
+
+ NEG_FLAGS clnt_flgs; /* usually 0x0000 01ff */
+
+} NET_Q_AUTH_2;
+
+
+/* NET_R_AUTH_2 */
+typedef struct net_r_auth2_info
+{
+ DOM_CHAL srv_chal; /* server-calculated credentials */
+ NEG_FLAGS srv_flgs; /* usually 0x0000 01ff */
+
+ uint32 status; /* return code */
+
+} NET_R_AUTH_2;
+
+
+/* NET_Q_SRV_PWSET */
+typedef struct net_q_srv_pwset_info
+{
+ DOM_CLNT_INFO clnt_id; /* client identification/authentication info */
+ uint8 pwd[16]; /* new password - undocumented. */
+
+} NET_Q_SRV_PWSET;
+
+/* NET_R_SRV_PWSET */
+typedef struct net_r_srv_pwset_info
+{
+ DOM_CRED srv_cred; /* server-calculated credentials */
+
+ uint32 status; /* return code */
+
+} NET_R_SRV_PWSET;
+
+/* NET_ID_INFO_2 */
+typedef struct net_network_info_2
+{
+ uint32 ptr_id_info2; /* pointer to id_info_2 */
+ UNIHDR hdr_domain_name; /* domain name unicode header */
+ uint32 param_ctrl; /* param control (0x2) */
+ DOM_LOGON_ID logon_id; /* logon ID */
+ UNIHDR hdr_user_name; /* user name unicode header */
+ UNIHDR hdr_wksta_name; /* workstation name unicode header */
+ uint8 lm_chal[8]; /* lan manager 8 byte challenge */
+ STRHDR hdr_nt_chal_resp; /* nt challenge response */
+ STRHDR hdr_lm_chal_resp; /* lm challenge response */
+
+ UNISTR2 uni_domain_name; /* domain name unicode string */
+ UNISTR2 uni_user_name; /* user name unicode string */
+ UNISTR2 uni_wksta_name; /* workgroup name unicode string */
+ STRING2 nt_chal_resp; /* nt challenge response */
+ STRING2 lm_chal_resp; /* lm challenge response */
+
+} NET_ID_INFO_2;
+
+/* NET_ID_INFO_1 */
+typedef struct id_info_1
+{
+ uint32 ptr_id_info1; /* pointer to id_info_1 */
+ UNIHDR hdr_domain_name; /* domain name unicode header */
+ uint32 param_ctrl; /* param control */
+ DOM_LOGON_ID logon_id; /* logon ID */
+ UNIHDR hdr_user_name; /* user name unicode header */
+ UNIHDR hdr_wksta_name; /* workstation name unicode header */
+ ARC4_OWF arc4_lm_owf; /* arc4 LM OWF Password */
+ ARC4_OWF arc4_nt_owf; /* arc4 NT OWF Password */
+ UNISTR2 uni_domain_name; /* domain name unicode string */
+ UNISTR2 uni_user_name; /* user name unicode string */
+ UNISTR2 uni_wksta_name; /* workgroup name unicode string */
+
+} NET_ID_INFO_1;
+
+/* NET_ID_INFO_CTR */
+typedef struct net_id_info_ctr_info
+{
+ uint16 switch_value;
+
+ union
+ {
+ NET_ID_INFO_1 id1; /* auth-level 1 - interactive user login */
+ NET_ID_INFO_2 id2; /* auth-level 2 - workstation referred login */
+
+ } auth;
+
+} NET_ID_INFO_CTR;
+
+/* SAM_INFO - sam logon/off id structure */
+typedef struct sam_info
+{
+ DOM_CLNT_INFO2 client;
+ uint32 ptr_rtn_cred; /* pointer to return credentials */
+ DOM_CRED rtn_cred; /* return credentials */
+ uint16 logon_level;
+ NET_ID_INFO_CTR *ctr;
+ uint16 validation_level;
+
+} DOM_SAM_INFO;
+
+/* NET_Q_SAM_LOGON */
+typedef struct net_q_sam_logon_info
+{
+ DOM_SAM_INFO sam_id;
+
+} NET_Q_SAM_LOGON;
+
+/* NET_R_SAM_LOGON */
+typedef struct net_r_sam_logon_info
+{
+ uint32 buffer_creds; /* undocumented buffer pointer */
+ DOM_CRED srv_creds; /* server credentials. server time stamp appears to be ignored. */
+
+ uint16 switch_value; /* 3 - indicates type of USER INFO */
+ NET_USER_INFO_3 *user;
+
+ uint32 auth_resp; /* 1 - Authoritative response; 0 - Non-Auth? */
+
+ uint32 status; /* return code */
+
+} NET_R_SAM_LOGON;
+
+
+/* NET_Q_SAM_LOGOFF */
+typedef struct net_q_sam_logoff_info
+{
+ DOM_SAM_INFO sam_id;
+
+} NET_Q_SAM_LOGOFF;
+
+/* NET_R_SAM_LOGOFF */
+typedef struct net_r_sam_logoff_info
+{
+ uint32 buffer_creds; /* undocumented buffer pointer */
+ DOM_CRED srv_creds; /* server credentials. server time stamp appears to be ignored. */
+
+ uint32 status; /* return code */
+
+} NET_R_SAM_LOGOFF;
+
+
+#endif /* _RPC_NETLOGON_H */
+
diff --git a/source3/include/rpc_reg.h b/source3/include/rpc_reg.h
new file mode 100644
index 0000000000..28d11710cd
--- /dev/null
+++ b/source3/include/rpc_reg.h
@@ -0,0 +1,141 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB parameters and setup
+ Copyright (C) Andrew Tridgell 1992-1997
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1997
+ Copyright (C) Paul Ashton 1997
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _RPC_REG_H /* _RPC_REG_H */
+#define _RPC_REG_H
+
+
+/* winreg pipe defines */
+#define REG_OPEN_POLICY 0x02
+#define REG_OPEN_ENTRY 0x0f
+#define REG_INFO 0x11
+#define REG_CLOSE 0x05
+
+/* REG_Q_OPEN_POLICY */
+typedef struct q_reg_open_policy_info
+{
+ uint32 ptr;
+ uint16 unknown_0; /* 0x5da0 - 16 bit unknown */
+ uint32 level; /* 0x0000 0001 - 32 bit unknown */
+ uint16 unknown_1; /* 0x0200 - 16 bit unknown */
+
+} REG_Q_OPEN_POLICY;
+
+/* REG_R_OPEN_POLICY */
+typedef struct r_reg_open_policy_info
+{
+ POLICY_HND pol; /* policy handle */
+ uint32 status; /* return status */
+
+} REG_R_OPEN_POLICY;
+
+
+/* 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_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 */
+ UNINOTSTR2 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 */
+ uint16 unknown_1; /* 16 bit unknown - 0x0000 */
+ uint16 unknown_2; /* 16 bit unknown - 0x0200 */
+
+} 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 */
+
diff --git a/source3/include/rpc_samr.h b/source3/include/rpc_samr.h
new file mode 100644
index 0000000000..bcce64b6be
--- /dev/null
+++ b/source3/include/rpc_samr.h
@@ -0,0 +1,1023 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB parameters and setup
+ Copyright (C) Andrew Tridgell 1992-1997
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1997
+ Copyright (C) Paul Ashton 1997
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#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_UNKNOWN_8 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_32 0x32
+#define SAMR_UNKNOWN_34 0x34
+#define SAMR_CONNECT 0x39
+#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 rid_group;
+
+} 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_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_UNKNOWN_8 - probably a query on domain group info.
+*****************************************************************************/
+
+/* SAMR_Q_UNKNOWN_8 - */
+typedef struct q_samr_unknown_8_info
+{
+ POLICY_HND domain_pol; /* policy handle */
+ uint16 switch_value; /* 0x0002 */
+
+} SAMR_Q_UNKNOWN_8;
+
+typedef struct sam_unkown_info_2_info
+{
+ uint32 unknown_0; /* 0x0000 0000 */
+ uint32 unknown_1; /* 0x0000 0000 */
+ uint32 unknown_2; /* 0x8000 0000 */
+ uint32 unknown_3; /* 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 unknown_4; /* 0x0000 0099 */
+ uint32 unknown_5; /* 0x0000 0000 */
+
+ uint32 unknown_6 ; /* 0x0000 0001 */
+ uint32 unknown_7 ; /* 0x0000 0003 */
+ uint32 unknown_8 ; /* 0x0000 0001 */
+ uint32 unknown_9 ; /* 0x0000 0008 */
+ uint32 unknown_10; /* 0x0000 0003 */
+
+ uint8 padding[16]; /* 16 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_UNKNOWN_8 - */
+typedef struct r_samr_unknown_8_info
+{
+ uint32 ptr_1;
+ uint16 switch_value; /* same as in query */
+
+ SAM_UNK_CTR *ctr;
+
+ uint32 status; /* return status */
+
+} SAMR_R_UNKNOWN_8;
+
+
+/****************************************************************************
+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 - 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
+{
+ LOOKUP_LEVEL level; /* 0x0006 */
+ uint32 ptr_0; /* 0x0000 0000 */
+ uint32 status;
+
+} 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_server; /* server name unicode header */
+ UNISTR2 uni_server; /* 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_1; /* seems to always contain 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 result; /* 0 == OK, C000006A (NT_STATUS_WRONG_PASSWORD) */
+
+} SAMR_R_CHGPASSWD_USER;
+
+#endif /* _RPC_SAMR_H */
+
diff --git a/source3/include/rpc_srvsvc.h b/source3/include/rpc_srvsvc.h
new file mode 100644
index 0000000000..4d11b915e4
--- /dev/null
+++ b/source3/include/rpc_srvsvc.h
@@ -0,0 +1,540 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB parameters and setup
+ Copyright (C) Andrew Tridgell 1992-1997
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1997
+ Copyright (C) Paul Ashton 1997
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _RPC_SRVSVC_H /* _RPC_SRVSVC_H */
+#define _RPC_SRVSVC_H
+
+
+/* srvsvc pipe */
+#define SRV_NETCONNENUM 0x08
+#define SRV_NETFILEENUM 0x09
+#define SRV_NETSESSENUM 0x0c
+#define SRV_NETSHAREENUM 0x0f
+#define SRV_NET_SRV_GET_INFO 0x15
+#define SRV_NET_SRV_SET_INFO 0x16
+
+
+/* SESS_INFO_0 (pointers to level 0 session info strings) */
+typedef struct ptr_sess_info0
+{
+ uint32 ptr_name; /* pointer to name. */
+
+} SESS_INFO_0;
+
+/* SESS_INFO_0_STR (level 0 session info strings) */
+typedef struct str_sess_info0
+{
+ UNISTR2 uni_name; /* unicode string of name */
+
+} SESS_INFO_0_STR;
+
+/* oops - this is going to take up a *massive* amount of stack. */
+/* the UNISTR2s already have 1024 uint16 chars in them... */
+#define MAX_SESS_ENTRIES 32
+
+/* SRV_SESS_INFO_0 */
+typedef struct srv_sess_info_0_info
+{
+ uint32 num_entries_read; /* EntriesRead */
+ uint32 ptr_sess_info; /* Buffer */
+ uint32 num_entries_read2; /* EntriesRead */
+
+ SESS_INFO_0 info_0 [MAX_SESS_ENTRIES]; /* session entry pointers */
+ SESS_INFO_0_STR info_0_str[MAX_SESS_ENTRIES]; /* session entry strings */
+
+} SRV_SESS_INFO_0;
+
+/* SESS_INFO_1 (pointers to level 1 session info strings) */
+typedef struct ptr_sess_info1
+{
+ uint32 ptr_name; /* pointer to name. */
+ uint32 ptr_user; /* pointer to user name. */
+
+ uint32 num_opens;
+ uint32 open_time;
+ uint32 idle_time;
+ uint32 user_flags;
+
+} SESS_INFO_1;
+
+/* SESS_INFO_1_STR (level 1 session info strings) */
+typedef struct str_sess_info1
+{
+ UNISTR2 uni_name; /* unicode string of name */
+ UNISTR2 uni_user; /* unicode string of user */
+
+} SESS_INFO_1_STR;
+
+/* SRV_SESS_INFO_1 */
+typedef struct srv_sess_info_1_info
+{
+ uint32 num_entries_read; /* EntriesRead */
+ uint32 ptr_sess_info; /* Buffer */
+ uint32 num_entries_read2; /* EntriesRead */
+
+ SESS_INFO_1 info_1 [MAX_SESS_ENTRIES]; /* session entry pointers */
+ SESS_INFO_1_STR info_1_str[MAX_SESS_ENTRIES]; /* session entry strings */
+
+} SRV_SESS_INFO_1;
+
+/* SRV_SESS_INFO_CTR */
+typedef struct srv_sess_info_ctr_info
+{
+ uint32 switch_value; /* switch value */
+ uint32 ptr_sess_ctr; /* pointer to sess info union */
+ union
+ {
+ SRV_SESS_INFO_0 info0; /* session info level 0 */
+ SRV_SESS_INFO_1 info1; /* session info level 1 */
+
+ } sess;
+
+} SRV_SESS_INFO_CTR;
+
+
+/* SRV_Q_NET_SESS_ENUM */
+typedef struct q_net_sess_enum_info
+{
+ uint32 ptr_srv_name; /* pointer (to server name?) */
+ UNISTR2 uni_srv_name; /* server name */
+
+ uint32 ptr_qual_name; /* pointer (to qualifier name) */
+ UNISTR2 uni_qual_name; /* qualifier name "\\qualifier" */
+
+ uint32 sess_level; /* session level */
+
+ SRV_SESS_INFO_CTR *ctr;
+
+ uint32 preferred_len; /* preferred maximum length (0xffff ffff) */
+ ENUM_HND enum_hnd;
+
+} SRV_Q_NET_SESS_ENUM;
+
+/* SRV_R_NET_SESS_ENUM */
+typedef struct r_net_sess_enum_info
+{
+ uint32 sess_level; /* share level */
+
+ SRV_SESS_INFO_CTR *ctr;
+
+ uint32 total_entries; /* total number of entries */
+ ENUM_HND enum_hnd;
+
+ uint32 status; /* return status */
+
+} SRV_R_NET_SESS_ENUM;
+
+/* CONN_INFO_0 (pointers to level 0 connection info strings) */
+typedef struct ptr_conn_info0
+{
+ uint32 id; /* connection id. */
+
+} CONN_INFO_0;
+
+/* oops - this is going to take up a *massive* amount of stack. */
+/* the UNISTR2s already have 1024 uint16 chars in them... */
+#define MAX_CONN_ENTRIES 32
+
+/* SRV_CONN_INFO_0 */
+typedef struct srv_conn_info_0_info
+{
+ uint32 num_entries_read; /* EntriesRead */
+ uint32 ptr_conn_info; /* Buffer */
+ uint32 num_entries_read2; /* EntriesRead */
+
+ CONN_INFO_0 info_0 [MAX_CONN_ENTRIES]; /* connection entry pointers */
+
+} SRV_CONN_INFO_0;
+
+/* CONN_INFO_1 (pointers to level 1 connection info strings) */
+typedef struct ptr_conn_info1
+{
+ uint32 id; /* connection id */
+ uint32 type; /* 0x3 */
+ uint32 num_opens;
+ uint32 num_users;
+ uint32 open_time;
+
+ uint32 ptr_usr_name; /* pointer to user name. */
+ uint32 ptr_net_name; /* pointer to network name (e.g IPC$). */
+
+} CONN_INFO_1;
+
+/* CONN_INFO_1_STR (level 1 connection info strings) */
+typedef struct str_conn_info1
+{
+ UNISTR2 uni_usr_name; /* unicode string of user */
+ UNISTR2 uni_net_name; /* unicode string of name */
+
+} CONN_INFO_1_STR;
+
+/* SRV_CONN_INFO_1 */
+typedef struct srv_conn_info_1_info
+{
+ uint32 num_entries_read; /* EntriesRead */
+ uint32 ptr_conn_info; /* Buffer */
+ uint32 num_entries_read2; /* EntriesRead */
+
+ CONN_INFO_1 info_1 [MAX_CONN_ENTRIES]; /* connection entry pointers */
+ CONN_INFO_1_STR info_1_str[MAX_CONN_ENTRIES]; /* connection entry strings */
+
+} SRV_CONN_INFO_1;
+
+/* SRV_CONN_INFO_CTR */
+typedef struct srv_conn_info_ctr_info
+{
+ uint32 switch_value; /* switch value */
+ uint32 ptr_conn_ctr; /* pointer to conn info union */
+ union
+ {
+ SRV_CONN_INFO_0 info0; /* connection info level 0 */
+ SRV_CONN_INFO_1 info1; /* connection info level 1 */
+
+ } conn;
+
+} SRV_CONN_INFO_CTR;
+
+
+/* SRV_Q_NET_CONN_ENUM */
+typedef struct q_net_conn_enum_info
+{
+ uint32 ptr_srv_name; /* pointer (to server name) */
+ UNISTR2 uni_srv_name; /* server name "\\server" */
+
+ uint32 ptr_qual_name; /* pointer (to qualifier name) */
+ UNISTR2 uni_qual_name; /* qualifier name "\\qualifier" */
+
+ uint32 conn_level; /* connection level */
+
+ SRV_CONN_INFO_CTR *ctr;
+
+ uint32 preferred_len; /* preferred maximum length (0xffff ffff) */
+ ENUM_HND enum_hnd;
+
+} SRV_Q_NET_CONN_ENUM;
+
+/* SRV_R_NET_CONN_ENUM */
+typedef struct r_net_conn_enum_info
+{
+ uint32 conn_level; /* share level */
+
+ SRV_CONN_INFO_CTR *ctr;
+
+ uint32 total_entries; /* total number of entries */
+ ENUM_HND enum_hnd;
+
+ uint32 status; /* return status */
+
+} SRV_R_NET_CONN_ENUM;
+
+/* oops - this is going to take up a *massive* amount of stack. */
+/* the UNISTR2s already have 1024 uint16 chars in them... */
+#define MAX_SHARE_ENTRIES 32
+
+/* SH_INFO_1 (pointers to level 1 share info strings) */
+typedef struct ptr_share_info1
+{
+ uint32 ptr_netname; /* pointer to net name. */
+ uint32 type; /* ipc, print, disk ... */
+ uint32 ptr_remark; /* pointer to comment. */
+
+} SH_INFO_1;
+
+/* SH_INFO_1_STR (level 1 share info strings) */
+typedef struct str_share_info1
+{
+ UNISTR2 uni_netname; /* unicode string of net name */
+ UNISTR2 uni_remark; /* unicode string of comment */
+
+} SH_INFO_1_STR;
+
+/* SRV_SHARE_INFO_1 */
+typedef struct share_info_1_info
+{
+ uint32 num_entries_read; /* EntriesRead */
+ uint32 ptr_share_info; /* Buffer */
+ uint32 num_entries_read2; /* EntriesRead */
+
+ SH_INFO_1 info_1 [MAX_SHARE_ENTRIES]; /* share entry pointers */
+ SH_INFO_1_STR info_1_str[MAX_SHARE_ENTRIES]; /* share entry strings */
+
+} SRV_SHARE_INFO_1;
+
+/* SH_INFO_2 (pointers to level 2 share info strings) */
+typedef struct ptr_share_info2
+{
+ uint32 ptr_netname; /* pointer to net name. */
+ uint32 type; /* ipc, print, disk ... */
+ uint32 ptr_remark; /* pointer to comment. */
+ uint32 perms; /* permissions */
+ uint32 max_uses; /* maximum uses */
+ uint32 num_uses; /* current uses */
+ uint32 ptr_path; /* pointer to path name */
+ uint32 ptr_passwd; /* pointer to password */
+
+} SH_INFO_2;
+
+/* SH_INFO_2_STR (level 2 share info strings) */
+typedef struct str_share_info2
+{
+ UNISTR2 uni_netname; /* unicode string of net name (e.g NETLOGON) */
+ UNISTR2 uni_remark; /* unicode string of comment (e.g "Logon server share") */
+ UNISTR2 uni_path; /* unicode string of local path (e.g c:\winnt\system32\repl\import\scripts) */
+ UNISTR2 uni_passwd; /* unicode string of password - presumably for share level security (e.g NULL) */
+
+} SH_INFO_2_STR;
+
+/* SRV_SHARE_INFO_2 */
+typedef struct share_info_2_info
+{
+ uint32 num_entries_read; /* EntriesRead */
+ uint32 ptr_share_info; /* Buffer */
+ uint32 num_entries_read2; /* EntriesRead */
+
+ SH_INFO_2 info_2 [MAX_SHARE_ENTRIES]; /* share entry pointers */
+ SH_INFO_2_STR info_2_str[MAX_SHARE_ENTRIES]; /* share entry strings */
+
+} SRV_SHARE_INFO_2;
+
+/* SRV_SHARE_INFO_CTR */
+typedef struct srv_share_info_1_info
+{
+ uint32 switch_value; /* switch value */
+ uint32 ptr_share_ctr; /* pointer to share info union */
+ union
+ {
+ SRV_SHARE_INFO_1 info1; /* share info level 1 */
+ SRV_SHARE_INFO_2 info2; /* share info level 2 */
+
+ } share;
+
+} SRV_SHARE_INFO_CTR;
+
+/* SRV_Q_NET_SHARE_ENUM */
+typedef struct q_net_share_enum_info
+{
+ uint32 ptr_srv_name; /* pointer (to server name?) */
+ UNISTR2 uni_srv_name; /* server name */
+
+ uint32 share_level; /* share level */
+
+ SRV_SHARE_INFO_CTR *ctr; /* share info container */
+
+ uint32 preferred_len; /* preferred maximum length (0xffff ffff) */
+
+ ENUM_HND enum_hnd;
+
+} SRV_Q_NET_SHARE_ENUM;
+
+
+/* SRV_R_NET_SHARE_ENUM */
+typedef struct r_net_share_enum_info
+{
+ uint32 share_level; /* share level */
+ SRV_SHARE_INFO_CTR *ctr; /* share info container */
+
+ uint32 total_entries; /* total number of entries */
+ ENUM_HND enum_hnd;
+
+ uint32 status; /* return status */
+
+} SRV_R_NET_SHARE_ENUM;
+
+/* FILE_INFO_3 (level 3 file info strings) */
+typedef struct file_info3_info
+{
+ uint32 id; /* file index */
+ uint32 perms; /* file permissions. don't know what format */
+ uint32 num_locks; /* file locks */
+ uint32 ptr_path_name; /* file name */
+ uint32 ptr_user_name; /* file owner */
+
+} FILE_INFO_3;
+
+/* FILE_INFO_3_STR (level 3 file info strings) */
+typedef struct str_file_info3_info
+{
+ UNISTR2 uni_path_name; /* unicode string of file name */
+ UNISTR2 uni_user_name; /* unicode string of file owner. */
+
+} FILE_INFO_3_STR;
+
+/* oops - this is going to take up a *massive* amount of stack. */
+/* the UNISTR2s already have 1024 uint16 chars in them... */
+#define MAX_FILE_ENTRIES 32
+
+/* SRV_FILE_INFO_3 */
+typedef struct srv_file_info_3
+{
+ uint32 num_entries_read; /* EntriesRead */
+ uint32 ptr_file_info; /* Buffer */
+
+ uint32 num_entries_read2; /* EntriesRead */
+
+ FILE_INFO_3 info_3 [MAX_FILE_ENTRIES]; /* file entry details */
+ FILE_INFO_3_STR info_3_str[MAX_FILE_ENTRIES]; /* file entry strings */
+
+} SRV_FILE_INFO_3;
+
+/* SRV_FILE_INFO_CTR */
+typedef struct srv_file_info_3_info
+{
+ uint32 switch_value; /* switch value */
+ uint32 ptr_file_ctr; /* pointer to file info union */
+ union
+ {
+ SRV_FILE_INFO_3 info3; /* file info with 0 entries */
+
+ } file;
+
+} SRV_FILE_INFO_CTR;
+
+
+/* SRV_Q_NET_FILE_ENUM */
+typedef struct q_net_file_enum_info
+{
+ uint32 ptr_srv_name; /* pointer (to server name?) */
+ UNISTR2 uni_srv_name; /* server name */
+
+ uint32 ptr_qual_name; /* pointer (to qualifier name) */
+ UNISTR2 uni_qual_name; /* qualifier name "\\qualifier" */
+
+ uint32 file_level; /* file level */
+
+ SRV_FILE_INFO_CTR *ctr;
+
+ uint32 preferred_len; /* preferred maximum length (0xffff ffff) */
+ ENUM_HND enum_hnd;
+
+} SRV_Q_NET_FILE_ENUM;
+
+
+/* SRV_R_NET_FILE_ENUM */
+typedef struct r_net_file_enum_info
+{
+ uint32 file_level; /* file level */
+
+ SRV_FILE_INFO_CTR *ctr;
+
+ uint32 total_entries; /* total number of files */
+ ENUM_HND enum_hnd;
+
+ uint32 status; /* return status */
+
+} SRV_R_NET_FILE_ENUM;
+
+/* SRV_INFO_101 */
+typedef struct srv_info_101_info
+{
+ uint32 platform_id; /* 0x500 */
+ uint32 ptr_name; /* pointer to server name */
+ uint32 ver_major; /* 0x4 */
+ uint32 ver_minor; /* 0x2 */
+ uint32 srv_type; /* browse etc type */
+ uint32 ptr_comment; /* pointer to server comment */
+
+ UNISTR2 uni_name; /* server name "server" */
+ UNISTR2 uni_comment; /* server comment "samba x.x.x blah" */
+
+} SRV_INFO_101;
+
+/* SRV_INFO_102 */
+typedef struct srv_info_102_info
+{
+ uint32 platform_id; /* 0x500 */
+ uint32 ptr_name; /* pointer to server name */
+ uint32 ver_major; /* 0x4 */
+ uint32 ver_minor; /* 0x2 */
+ uint32 srv_type; /* browse etc type */
+ uint32 ptr_comment; /* pointer to server comment */
+ uint32 users; /* 0xffff ffff*/
+ uint32 disc; /* 0xf */
+ uint32 hidden; /* 0x0 */
+ uint32 announce; /* 240 */
+ uint32 ann_delta; /* 3000 */
+ uint32 licenses; /* 0 */
+ uint32 ptr_usr_path; /* pointer to user path */
+
+ UNISTR2 uni_name; /* server name "server" */
+ UNISTR2 uni_comment; /* server comment "samba x.x.x blah" */
+ UNISTR2 uni_usr_path; /* "c:\" (eh?) */
+
+} SRV_INFO_102;
+
+
+/* SRV_INFO_CTR */
+typedef struct srv_info_ctr_info
+{
+ uint32 switch_value; /* switch value */
+ uint32 ptr_srv_ctr; /* pointer to server info */
+ union
+ {
+ SRV_INFO_102 sv102; /* server info level 102 */
+ SRV_INFO_101 sv101; /* server info level 101 */
+
+ } srv;
+
+} SRV_INFO_CTR;
+
+/* SRV_Q_NET_SRV_GET_INFO */
+typedef struct q_net_srv_get_info
+{
+ uint32 ptr_srv_name;
+ UNISTR2 uni_srv_name; /* "\\server" */
+ uint32 switch_value;
+
+} SRV_Q_NET_SRV_GET_INFO;
+
+/* SRV_R_NET_SRV_GET_INFO */
+typedef struct r_net_srv_get_info
+{
+ SRV_INFO_CTR *ctr;
+
+ uint32 status; /* return status */
+
+} SRV_R_NET_SRV_GET_INFO;
+
+/* SRV_Q_NET_SRV_SET_INFO */
+typedef struct q_net_srv_set_info
+{
+ uint32 ptr_srv_name;
+ UNISTR2 uni_srv_name; /* "\\server" */
+ uint32 switch_value;
+
+ SRV_INFO_CTR *ctr;
+
+} SRV_Q_NET_SRV_SET_INFO;
+
+
+/* SRV_R_NET_SRV_SET_INFO */
+typedef struct r_net_srv_set_info
+{
+ uint32 switch_value; /* switch value */
+
+ uint32 status; /* return status */
+
+} SRV_R_NET_SRV_SET_INFO;
+
+
+#endif /* _RPC_SRVSVC_H */
+
diff --git a/source3/include/rpc_wkssvc.h b/source3/include/rpc_wkssvc.h
new file mode 100644
index 0000000000..1483997acb
--- /dev/null
+++ b/source3/include/rpc_wkssvc.h
@@ -0,0 +1,73 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB parameters and setup
+ Copyright (C) Andrew Tridgell 1992-1997
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1997
+ Copyright (C) Paul Ashton 1997
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _RPC_WKS_H /* _RPC_WKS_H */
+#define _RPC_WKS_H
+
+
+/* wkssvc pipe */
+#define WKS_QUERY_INFO 0x00
+
+
+/* WKS_Q_QUERY_INFO - probably a capabilities request */
+typedef struct q_wks_query_info_info
+{
+ uint32 ptr_srv_name; /* pointer (to server name?) */
+ UNISTR2 uni_srv_name; /* unicode server name starting with '\\' */
+
+ uint16 switch_value; /* info level 100 (0x64) */
+
+} WKS_Q_QUERY_INFO;
+
+
+/* WKS_INFO_100 - level 100 info */
+typedef struct wks_info_100_info
+{
+ uint32 platform_id; /* 0x0000 01f4 - unknown */
+ uint32 ptr_compname; /* pointer to server name */
+ uint32 ptr_lan_grp ; /* pointer to domain name */
+ uint32 ver_major; /* 4 - unknown */
+ uint32 ver_minor; /* 0 - unknown */
+
+ UNISTR2 uni_compname; /* unicode server name */
+ UNISTR2 uni_lan_grp ; /* unicode domain name */
+
+} WKS_INFO_100;
+
+
+/* WKS_R_QUERY_INFO - probably a capabilities request */
+typedef struct r_wks_query_info_info
+{
+ uint16 switch_value; /* 100 (0x64) - switch value */
+
+ /* for now, only level 100 is supported. this should be an enum container */
+ uint32 ptr_1; /* pointer 1 */
+ WKS_INFO_100 *wks100; /* workstation info level 100 */
+
+ uint32 status; /* return status */
+
+} WKS_R_QUERY_INFO;
+
+
+#endif /* _RPC_WKS_H */
+
diff --git a/source3/include/smb.h b/source3/include/smb.h
index ccb3b0424a..a60b74a835 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -36,6 +36,11 @@
#define BOOLSTR(b) ((b) ? "Yes" : "No")
#define BITSETB(ptr,bit) ((((char *)ptr)[0] & (1<<(bit)))!=0)
#define BITSETW(ptr,bit) ((SVAL(ptr,0) & (1<<(bit)))!=0)
+
+#define IS_BITS_SET_ALL(var,bit) (((var)&(bit))==(bit))
+#define IS_BITS_SET_SOME(var,bit) (((var)&(bit))!=0)
+#define IS_BITS_CLR_ALL(var,bit) (((var)&(~(bit)))==0)
+
#define PTR_DIFF(p1,p2) ((ptrdiff_t)(((char *)(p1)) - (char *)(p2)))
typedef int BOOL;
@@ -246,90 +251,6 @@ typedef fstring string;
#define PIPE_LSASS "\\PIPE\\lsass"
#define PIPE_LSARPC "\\PIPE\\lsarpc"
-/* NETLOGON opcodes and data structures */
-
-enum RPC_PKT_TYPE
-{
- RPC_REQUEST = 0x00,
- RPC_RESPONSE = 0x02,
- RPC_BIND = 0x0B,
- RPC_BINDACK = 0x0C
-};
-
-#define NET_QUERYFORPDC 7 /* Query for PDC */
-#define NET_QUERYFORPDC_R 12 /* Response to Query for PDC */
-#define NET_SAMLOGON 18
-#define NET_SAMLOGON_R 19
-
-/* Allowable account control bits */
-#define ACB_DISABLED 1 /* 1 = User account disabled */
-#define ACB_HOMDIRREQ 2 /* 1 = Home directory required */
-#define ACB_PWNOTREQ 4 /* 1 = User password not required */
-#define ACB_TEMPDUP /* 1 = Temporary duplicate account */
-#define ACB_NORMAL /* 1 = Normal user account */
-#define ACB_MNS /* 1 = MNS logon user account */
-#define ACB_DOMTRUST /* 1 = Interdomain trust account */
-#define ACB_WSTRUST /* 1 = Workstation trust account */
-#define ACB_SVRTRUST /* 1 = Server trust account */
-#define ACB_PWNOEXP /* 1 = User password does not expire */
-#define ACB_AUTOLOCK /* 1 = Account auto locked */
-
-#define SAMR_CLOSE 0x01
-#define SAMR_OPEN_SECRET 0x07
-#define SAMR_LOOKUP_RIDS 0x11
-#define SAMR_UNKNOWN_3 0x03
-#define SAMR_UNKNOWN_22 0x22
-#define SAMR_UNKNOWN_24 0x24
-#define SAMR_UNKNOWN_34 0x34
-#define SAMR_OPEN_POLICY 0x39
-
-#define LSA_OPENPOLICY 0x2c
-#define LSA_QUERYINFOPOLICY 0x07
-#define LSA_ENUMTRUSTDOM 0x0d
-#define LSA_REQCHAL 0x04
-#define LSA_SRVPWSET 0x06
-#define LSA_SAMLOGON 0x02
-#define LSA_SAMLOGOFF 0x03
-#define LSA_AUTH2 0x0f
-#define LSA_CLOSE 0x00
-
-/* XXXX these are here to get a compile! */
-
-#define LSA_OPENSECRET 0xFF
-#define LSA_LOOKUPSIDS 0xFE
-#define LSA_LOOKUPRIDS 0xFD
-#define LSA_LOOKUPNAMES 0xFC
-
-/* srvsvc pipe */
-#define NETSERVERGETINFO 0x15
-#define NETSHAREENUM 0x0f
-
-/* well-known RIDs - Relative IDs */
-
-/* RIDs - Well-known users ... */
-#define DOMAIN_USER_RID_ADMIN (0x000001F4L)
-#define DOMAIN_USER_RID_GUEST (0x000001F5L)
-
-/* RIDs - well-known groups ... */
-#define DOMAIN_GROUP_RID_ADMINS (0x00000200L)
-#define DOMAIN_GROUP_RID_USERS (0x00000201L)
-#define DOMAIN_GROUP_RID_GUESTS (0x00000202L)
-
-/* RIDs - well-known aliases ... */
-#define DOMAIN_ALIAS_RID_ADMINS (0x00000220L)
-#define DOMAIN_ALIAS_RID_USERS (0x00000221L)
-#define DOMAIN_ALIAS_RID_GUESTS (0x00000222L)
-#define DOMAIN_ALIAS_RID_POWER_USERS (0x00000223L)
-
-#define DOMAIN_ALIAS_RID_ACCOUNT_OPS (0x00000224L)
-#define DOMAIN_ALIAS_RID_SYSTEM_OPS (0x00000225L)
-#define DOMAIN_ALIAS_RID_PRINT_OPS (0x00000226L)
-#define DOMAIN_ALIAS_RID_BACKUP_OPS (0x00000227L)
-
-#define DOMAIN_ALIAS_RID_REPLICATOR (0x00000228L)
-
-
-
/* 32 bit time (sec) since 01jan1970 - cifs6.txt, section 3.5, page 30 */
typedef struct time_info
{
@@ -344,990 +265,20 @@ typedef struct nttime_info
uint32 high;
} NTTIME;
-
-
-#define MAXSUBAUTHS 15 /* max sub authorities in a SID */
-
-/* DOM_SID - security id */
-typedef struct sid_info
-{
- uint8 sid_rev_num; /* SID revision number */
- uint8 num_auths; /* number of sub-authorities */
- uint8 id_auth[6]; /* Identifier Authority */
- uint32 sub_auths[MAXSUBAUTHS]; /* pointer to sub-authorities. */
-
-} DOM_SID;
-
-/* UNIHDR - unicode string header */
-typedef struct unihdr_info
-{
- uint16 uni_max_len;
- uint16 uni_str_len;
- uint32 undoc; /* usually has a value of 4 */
-
-} UNIHDR;
-
-/* UNIHDR2 - unicode string header and undocumented buffer */
-typedef struct unihdr2_info
-{
- UNIHDR unihdr;
- uint32 undoc_buffer; /* undocumented 32 bit buffer pointer */
-
-} UNIHDR2;
-
-/* clueless as to what maximum length should be */
-#define MAX_UNISTRLEN 1024
-
-/* UNISTR - unicode string size and buffer */
-typedef struct unistr_info
-{
- uint16 buffer[MAX_UNISTRLEN]; /* unicode characters. ***MUST*** be null-terminated */
-
-} UNISTR;
-
-/* UNISTR2 - unicode string size and buffer */
-typedef struct unistr2_info
-{
- uint32 uni_max_len;
- uint32 undoc;
- uint32 uni_str_len;
- uint16 buffer[MAX_UNISTRLEN]; /* unicode characters. **NOT** necessarily null-terminated */
-
-} UNISTR2;
-
-/* DOM_SID2 - domain SID structure - SIDs stored in unicode */
-typedef struct domsid2_info
-{
- uint32 type; /* value is 5 */
- uint32 undoc; /* value is 0 */
-
- UNIHDR2 hdr; /* XXXX conflict between hdr and str for length */
- UNISTR str; /* XXXX conflict between hdr and str for length */
-
-} DOM_SID2;
-
-/* DOM_RID2 - domain RID structure for ntlsa pipe */
-typedef struct domrid2_info
-{
- uint32 type; /* value is 5 */
- uint32 undoc; /* value is non-zero */
- uint32 rid;
- uint32 rid_idx; /* don't know what this is */
-
-} DOM_RID2;
-
-/* DOM_RID3 - domain RID structure for samr pipe */
-typedef struct domrid3_info
-{
- uint32 rid; /* domain-relative (to a SID) id */
- uint32 type1; /* value is 0x1 */
- uint32 ptr_type; /* undocumented pointer */
- uint32 type2; /* value is 0x1 */
-
-} DOM_RID3;
-
-/* DOM_CLNT_SRV - client / server names */
-typedef struct clnt_srv_info
-{
- uint32 undoc_buffer; /* undocumented 32 bit buffer pointer */
- UNISTR2 uni_logon_srv; /* logon server name */
- uint32 undoc_buffer2; /* undocumented 32 bit buffer pointer */
- UNISTR2 uni_comp_name; /* client machine name */
-
-} DOM_CLNT_SRV;
-
-/* DOM_LOG_INFO - login info */
-typedef struct log_info
-{
- uint32 undoc_buffer; /* undocumented 32 bit buffer pointer */
- UNISTR2 uni_logon_srv; /* logon server name */
- UNISTR2 uni_acct_name; /* account name */
- uint16 sec_chan; /* secure channel type */
- UNISTR2 uni_comp_name; /* client machine name */
-
-} DOM_LOG_INFO;
-
-/* DOM_CHAL - challenge info */
-typedef struct chal_info
-{
- uchar data[8]; /* credentials */
-} DOM_CHAL;
-
-/* DOM_CREDs - timestamped client or server credentials */
-typedef struct cred_info
-{
- DOM_CHAL challenge; /* credentials */
- UTIME timestamp; /* credential time-stamp */
-
-} DOM_CRED;
-
-/* DOM_CLNT_INFO - client info */
-typedef struct clnt_info
-{
- DOM_LOG_INFO login;
- DOM_CRED cred;
-
-} DOM_CLNT_INFO;
-
-/* DOM_CLNT_INFO2 - client info */
-typedef struct clnt_info2
-{
- DOM_CLNT_SRV login;
- uint32 ptr_cred;
- DOM_CRED cred;
-
-} DOM_CLNT_INFO2;
-
-/* DOM_LOGON_ID - logon id */
-typedef struct logon_info
-{
- uint32 low;
- uint32 high;
-
-} DOM_LOGON_ID;
-
-/* ARC4_OWF */
-typedef struct arc4_owf_info
-{
- uint8 data[16];
-
-} ARC4_OWF;
-
-
-/* DOM_ID_INFO_1 */
-typedef struct id_info_1
-{
- uint32 ptr_id_info1; /* pointer to id_info_1 */
- UNIHDR hdr_domain_name; /* domain name unicode header */
- uint32 param_ctrl; /* param control */
- DOM_LOGON_ID logon_id; /* logon ID */
- UNIHDR hdr_user_name; /* user name unicode header */
- UNIHDR hdr_wksta_name; /* workgroup name unicode header */
- ARC4_OWF arc4_lm_owf; /* arc4 LM OWF Password */
- ARC4_OWF arc4_nt_owf; /* arc4 NT OWF Password */
- UNISTR2 uni_domain_name; /* domain name unicode string */
- UNISTR2 uni_user_name; /* user name unicode string */
- UNISTR2 uni_wksta_name; /* workgroup name unicode string */
-
-} DOM_ID_INFO_1;
-
-/* SAM_INFO - sam logon/off id structure */
-typedef struct sam_info
-{
- DOM_CLNT_INFO2 client;
- uint32 ptr_rtn_cred; /* pointer to return credentials */
- DOM_CRED rtn_cred; /* return credentials */
- uint16 logon_level;
- uint16 switch_value;
-
- union
- {
- DOM_ID_INFO_1 *id1; /* auth-level 1 */
-
- } auth;
-
-} DOM_SAM_INFO;
-
-/* DOM_GID - group id + user attributes */
-typedef struct gid_info
-{
- uint32 g_rid; /* a group RID */
- uint32 attr;
-
-} DOM_GID;
-
-/* RPC_HDR - ms rpc header */
-typedef struct rpc_hdr_info
-{
- uint8 major; /* 5 - RPC major version */
- uint8 minor; /* 0 - RPC minor version */
- uint8 pkt_type; /* 2 - RPC response packet */
- uint8 frag; /* 3 - first frag + last frag */
- uint32 pack_type; /* 0x1000 0000 - packed data representation */
- uint16 frag_len; /* fragment length - data size (bytes) inc header and tail. */
- uint16 auth_len; /* 0 - authentication length */
- uint32 call_id; /* call identifier. matches 12th uint32 of incoming RPC data. */
-
-} RPC_HDR;
-
-/* RPC_HDR_RR - ms request / response rpc header */
-typedef struct rpc_hdr_rr_info
-{
- RPC_HDR hdr;
-
- uint32 alloc_hint; /* allocation hint - data size (bytes) minus header and tail. */
- uint16 context_id; /* 0 - presentation context identifier */
- uint8 cancel_count; /* 0 - cancel count */
- uint8 opnum; /* request: 0 - reserved. response: opnum */
-
-} RPC_HDR_RR;
-
-/* the interfaces are numbered. as yet I haven't seen more than one interface
- * used on the same pipe name
- * srvsvc
- * abstract (0x4B324FC8, 0x01D31670, 0x475A7812, 0x88E16EBF, 0x00000003)
- * transfer (0x8A885D04, 0x11C91CEB, 0x0008E89F, 0x6048102B, 0x00000002)
- */
-/* RPC_IFACE */
-typedef struct rpc_iface_info
-{
- uint8 data[16]; /* 16 bytes of number */
- uint32 version; /* the interface number */
-
-} RPC_IFACE;
-
-
-/* this seems to be the same string name depending on the name of the pipe,
- * but is more likely to be linked to the interface name
- * "srvsvc", "\\PIPE\\ntsvcs"
- * "samr", "\\PIPE\\lsass"
- * "wkssvc", "\\PIPE\\wksvcs"
- * "NETLOGON", "\\PIPE\\NETLOGON"
- */
-/* RPC_ADDR_STR */
-typedef struct rpc_addr_info
-{
- uint16 len; /* length of the string including null terminator */
- fstring str; /* the string above in single byte, null terminated form */
-
-} RPC_ADDR_STR;
-
-/* RPC_HDR_BBA */
-typedef struct rpc_hdr_bba_info
-{
- uint16 max_tsize; /* maximum transmission fragment size (0x1630) */
- uint16 max_rsize; /* max receive fragment size (0x1630) */
- uint32 assoc_gid; /* associated group id (0x0) */
-
-} RPC_HDR_BBA;
-
-/* RPC_BIND_REQ - ms req bind */
-typedef struct rpc_bind_req_info
-{
- RPC_HDR_BBA bba;
-
- uint32 num_elements; /* the number of elements (0x1) */
- uint16 context_id; /* presentation context identifier (0x0) */
- uint8 num_syntaxes; /* the number of syntaxes (has always been 1?)(0x1) */
-
- RPC_IFACE abstract; /* num and vers. of interface client is using */
- RPC_IFACE transfer; /* num and vers. of interface to use for replies */
-
-} RPC_HDR_RB;
-
-/* RPC_RESULTS - can only cope with one reason, right now... */
-typedef struct rpc_results_info
-{
-/* uint8[] # 4-byte alignment padding, against SMB header */
-
- uint8 num_results; /* the number of results (0x01) */
-
-/* uint8[] # 4-byte alignment padding, against SMB header */
-
- uint16 result; /* result (0x00 = accept) */
- uint16 reason; /* reason (0x00 = no reason specified) */
-
-} RPC_RESULTS;
-
-/* RPC_HDR_BA */
-typedef struct rpc_hdr_ba_info
-{
- RPC_HDR_BBA bba;
-
- RPC_ADDR_STR addr ; /* the secondary address string, as described earlier */
- RPC_RESULTS res ; /* results and reasons */
- RPC_IFACE transfer; /* the transfer syntax from the request */
-
-} RPC_HDR_BA;
-
-
-/* DOM_QUERY - info class 3 and 5 LSA Query response */
-typedef struct dom_query_info
-{
- uint16 uni_dom_max_len; /* domain name string length * 2 */
- uint16 uni_dom_str_len; /* domain name string length * 2 */
- uint32 buffer_dom_name; /* undocumented domain name string buffer pointer */
- uint32 buffer_dom_sid; /* undocumented domain SID string buffer pointer */
- UNISTR2 uni_domain_name; /* domain name (unicode string) */
- DOM_SID dom_sid; /* domain SID */
-
-} DOM_QUERY;
-
-/* level 5 is same as level 3. we hope. */
-typedef DOM_QUERY DOM_QUERY_3;
-typedef DOM_QUERY DOM_QUERY_5;
-
-#define POL_HND_SIZE 20
-
-/* LSA_POL_HND */
-typedef struct lsa_policy_info
-{
- uint8 data[POL_HND_SIZE]; /* policy handle */
-
-} LSA_POL_HND;
-
-/* OBJ_ATTR (object attributes) */
-typedef struct object_attributes_info
-{
- uint32 len; /* 0x18 - length (in bytes) inc. the length field. */
- uint32 ptr_root_dir; /* 0 - root directory (pointer) */
- uint32 ptr_obj_name; /* 0 - object name (pointer) */
- uint32 attributes; /* 0 - attributes (undocumented) */
- uint32 ptr_sec_desc; /* 0 - security descriptior (pointer) */
- uint32 sec_qos; /* 0 - security quality of service */
-
-} LSA_OBJ_ATTR;
-
-/* LSA_Q_OPEN_POL - LSA Query Open Policy */
-typedef struct lsa_q_open_pol_info
-{
- uint32 ptr; /* undocumented buffer pointer */
- UNISTR2 uni_server_name; /* server name, starting with two '\'s */
- LSA_OBJ_ATTR attr ; /* object attributes */
-
- uint32 des_access; /* desired access attributes */
-
-} LSA_Q_OPEN_POL;
-
-/* LSA_R_OPEN_POL - response to LSA Open Policy */
-typedef struct lsa_r_open_pol_info
-{
- LSA_POL_HND pol; /* policy handle */
-
- uint32 status; /* return code */
-
-} LSA_R_OPEN_POL;
-
-/* LSA_Q_QUERY_INFO - LSA query info policy */
-typedef struct lsa_query_info
-{
- LSA_POL_HND pol; /* policy handle */
- uint16 info_class; /* info class */
-
-} LSA_Q_QUERY_INFO;
-
-/* LSA_R_QUERY_INFO - response to LSA query info policy */
-typedef struct lsa_r_query_info
-{
- uint32 undoc_buffer; /* undocumented buffer pointer */
- uint16 info_class; /* info class (same as info class in request) */
-
- union
- {
- DOM_QUERY_3 id3;
- DOM_QUERY_5 id5;
-
- } dom;
-
- uint32 status; /* return code */
-
-} LSA_R_QUERY_INFO;
-
-/* LSA_Q_ENUM_TRUST_DOM - LSA enumerate trusted domains */
-typedef struct lsa_enum_trust_dom_info
-{
- LSA_POL_HND pol; /* policy handle */
- uint32 enum_context; /* enumeration context handle */
- uint32 preferred_len; /* preferred maximum length */
-
-} LSA_Q_ENUM_TRUST_DOM;
-
-/* LSA_R_ENUM_TRUST_DOM - response to LSA enumerate trusted domains */
-typedef struct lsa_r_enum_trust_dom_info
-{
- LSA_POL_HND pol; /* policy handle */
-
- uint32 status; /* return code */
-
-} LSA_R_ENUM_TRUST_DOM;
-
-/* LSA_Q_CLOSE */
-typedef struct lsa_q_close_info
-{
- LSA_POL_HND pol; /* policy handle */
-
-} LSA_Q_CLOSE;
-
-/* LSA_R_CLOSE */
-typedef struct lsa_r_close_info
-{
- LSA_POL_HND pol; /* policy handle. should be all zeros. */
-
- uint32 status; /* return code */
-
-} LSA_R_CLOSE;
-
-
-#define MAX_REF_DOMAINS 10
-
-/* DOM_R_REF */
-typedef struct dom_ref_info
-{
- uint32 undoc_buffer; /* undocumented buffer pointer. */
- uint32 num_ref_doms_1; /* num referenced domains? */
- uint32 buffer_dom_name; /* undocumented domain name buffer pointer. */
- uint32 max_entries; /* 32 - max number of entries */
- uint32 num_ref_doms_2; /* 4 - num referenced domains? */
-
- UNIHDR2 hdr_dom_name; /* domain name unicode string header */
- UNIHDR2 hdr_ref_dom[MAX_REF_DOMAINS]; /* referenced domain unicode string headers */
-
- UNISTR uni_dom_name; /* domain name unicode string */
- DOM_SID ref_dom[MAX_REF_DOMAINS]; /* referenced domain SIDs */
-
-} DOM_R_REF;
-
-#define MAX_LOOKUP_SIDS 10
-
-/* LSA_Q_LOOKUP_SIDS - LSA Lookup SIDs */
-typedef struct lsa_q_lookup_sids
-{
- LSA_POL_HND pol_hnd; /* policy handle */
- uint32 num_entries;
- uint32 buffer_dom_sid; /* undocumented domain SID buffer pointer */
- uint32 buffer_dom_name; /* undocumented domain name buffer pointer */
- uint32 buffer_lookup_sids[MAX_LOOKUP_SIDS]; /* undocumented domain SID pointers to be looked up. */
- DOM_SID dom_sids[MAX_LOOKUP_SIDS]; /* domain SIDs to be looked up. */
- uint8 undoc[16]; /* completely undocumented 16 bytes */
-
-} LSA_Q_LOOKUP_SIDS;
-
-/* LSA_R_LOOKUP_SIDS - response to LSA Lookup SIDs */
-typedef struct lsa_r_lookup_sids
-{
- DOM_R_REF dom_ref; /* domain reference info */
-
- uint32 num_entries;
- uint32 undoc_buffer; /* undocumented buffer pointer */
- uint32 num_entries2;
-
- DOM_SID2 dom_sid[MAX_LOOKUP_SIDS]; /* domain SIDs being looked up */
-
- uint32 num_entries3;
-
- uint32 status; /* return code */
-
-} LSA_R_LOOKUP_SIDS;
-
-/* DOM_NAME - XXXX not sure about this structure */
-typedef struct dom_name_info
-{
- uint32 uni_str_len;
- UNISTR str;
-
-} DOM_NAME;
-
-
-#define UNKNOWN_LEN 1
-
-/* LSA_Q_LOOKUP_RIDS - LSA Lookup RIDs */
-typedef struct lsa_q_lookup_rids
-{
-
- LSA_POL_HND pol_hnd; /* policy handle */
- uint32 num_entries;
- uint32 num_entries2;
- uint32 buffer_dom_sid; /* undocumented domain SID buffer pointer */
- uint32 buffer_dom_name; /* undocumented domain name buffer pointer */
- DOM_NAME lookup_name[MAX_LOOKUP_SIDS]; /* names to be looked up */
- uint8 undoc[UNKNOWN_LEN]; /* completely undocumented bytes of unknown length */
-
-} LSA_Q_LOOKUP_RIDS;
-
-/* LSA_R_LOOKUP_RIDS - response to LSA Lookup RIDs by name */
-typedef struct lsa_r_lookup_rids
-{
- DOM_R_REF dom_ref; /* domain reference info */
-
- uint32 num_entries;
- uint32 undoc_buffer; /* undocumented buffer pointer */
-
- uint32 num_entries2;
- DOM_RID2 dom_rid[MAX_LOOKUP_SIDS]; /* domain RIDs being looked up */
-
- uint32 num_entries3;
-
- uint32 status; /* return code */
-
-} LSA_R_LOOKUP_RIDS;
-
-
-
-/* NEG_FLAGS */
-typedef struct lsa_neg_flags_info
-{
- uint32 neg_flags; /* negotiated flags */
-
-} NEG_FLAGS;
-
-
-/* LSA_Q_REQ_CHAL */
-typedef struct lsa_q_req_chal_info
-{
- uint32 undoc_buffer; /* undocumented buffer pointer */
- UNISTR2 uni_logon_srv; /* logon server unicode string */
- UNISTR2 uni_logon_clnt; /* logon client unicode string */
- DOM_CHAL clnt_chal; /* client challenge */
-
-} LSA_Q_REQ_CHAL;
-
-
-/* LSA_R_REQ_CHAL */
-typedef struct lsa_r_req_chal_info
-{
- DOM_CHAL srv_chal; /* server challenge */
-
- uint32 status; /* return code */
-
-} LSA_R_REQ_CHAL;
-
-
-
-/* LSA_Q_AUTH_2 */
-typedef struct lsa_q_auth2_info
-{
- DOM_LOG_INFO clnt_id; /* client identification info */
- DOM_CHAL clnt_chal; /* client-calculated credentials */
-
- NEG_FLAGS clnt_flgs; /* usually 0x0000 01ff */
-
-} LSA_Q_AUTH_2;
-
-
-/* LSA_R_AUTH_2 */
-typedef struct lsa_r_auth2_info
-{
- DOM_CHAL srv_chal; /* server-calculated credentials */
- NEG_FLAGS srv_flgs; /* usually 0x0000 01ff */
-
- uint32 status; /* return code */
-
-} LSA_R_AUTH_2;
-
-
-/* LSA_Q_SRV_PWSET */
-typedef struct lsa_q_srv_pwset_info
-{
- DOM_CLNT_INFO clnt_id; /* client identification/authentication info */
- char pwd[16]; /* new password - undocumented. */
-
-} LSA_Q_SRV_PWSET;
-
-/* LSA_R_SRV_PWSET */
-typedef struct lsa_r_srv_pwset_info
-{
- DOM_CRED srv_cred; /* server-calculated credentials */
-
- uint32 status; /* return code */
-
-} LSA_R_SRV_PWSET;
-
-#define LSA_MAX_GROUPS 32
-#define LSA_MAX_SIDS 32
-
-/* LSA_USER_INFO */
-typedef struct lsa_q_user_info
-{
- uint32 ptr_user_info;
-
- 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_logon_script; /* logon script unicode string header */
- UNIHDR hdr_profile_path; /* profile path unicode string header */
- UNIHDR hdr_home_dir; /* home directory unicode string header */
- UNIHDR hdr_dir_drive; /* home directory drive unicode string header */
-
- uint16 logon_count; /* logon count */
- uint16 bad_pw_count; /* bad password count */
-
- uint32 user_id; /* User ID */
- uint32 group_id; /* Group ID */
- uint32 num_groups; /* num groups */
- uint32 buffer_groups; /* undocumented buffer pointer to groups. */
- uint32 user_flgs; /* user flags */
-
- char user_sess_key[16]; /* unused user session key */
-
- UNIHDR hdr_logon_srv; /* logon server unicode string header */
- UNIHDR hdr_logon_dom; /* logon domain unicode string header */
-
- uint32 buffer_dom_id; /* undocumented logon domain id pointer */
- char padding[40]; /* unused padding bytes. expansion room */
-
- uint32 num_other_sids; /* 0 - num_sids */
- uint32 buffer_other_sids; /* NULL - undocumented pointer to SIDs. */
-
- UNISTR2 uni_user_name; /* username unicode string */
- UNISTR2 uni_full_name; /* user's full name unicode string */
- UNISTR2 uni_logon_script; /* logon script unicode string */
- UNISTR2 uni_profile_path; /* profile path unicode string */
- UNISTR2 uni_home_dir; /* home directory unicode string */
- UNISTR2 uni_dir_drive; /* home directory drive unicode string */
-
- uint32 num_groups2; /* num groups */
- DOM_GID gids[LSA_MAX_GROUPS]; /* group info */
-
- UNISTR2 uni_logon_srv; /* logon server unicode string */
- UNISTR2 uni_logon_dom; /* logon domain unicode string */
-
- DOM_SID dom_sid; /* domain SID */
- DOM_SID other_sids[LSA_MAX_SIDS]; /* undocumented - domain SIDs */
-
-} LSA_USER_INFO;
-
-
-/* LSA_Q_SAM_LOGON */
-typedef struct lsa_q_sam_logon_info
-{
- DOM_SAM_INFO sam_id;
-
-} LSA_Q_SAM_LOGON;
-
-/* LSA_R_SAM_LOGON */
-typedef struct lsa_r_sam_logon_info
-{
- uint32 buffer_creds; /* undocumented buffer pointer */
- DOM_CRED srv_creds; /* server credentials. server time stamp appears to be ignored. */
-
- uint16 switch_value; /* 3 - indicates type of USER INFO */
- LSA_USER_INFO *user;
-
- uint32 auth_resp; /* 1 - Authoritative response; 0 - Non-Auth? */
-
- uint32 status; /* return code */
-
-} LSA_R_SAM_LOGON;
-
-
-/* LSA_Q_SAM_LOGOFF */
-typedef struct lsa_q_sam_logoff_info
-{
- DOM_SAM_INFO sam_id;
-
-} LSA_Q_SAM_LOGOFF;
-
-/* LSA_R_SAM_LOGOFF */
-typedef struct lsa_r_sam_logoff_info
-{
- uint32 buffer_creds; /* undocumented buffer pointer */
- DOM_CRED srv_creds; /* server credentials. server time stamp appears to be ignored. */
-
- uint32 status; /* return code */
-
-} LSA_R_SAM_LOGOFF;
-
-
-/* SH_INFO_1 (pointers to level 1 share info strings) */
-typedef struct ptr_share_info1
-{
- uint32 ptr_netname; /* pointer to net name. */
- uint32 type; /* type of share. 0 - undocumented. */
- uint32 ptr_remark; /* pointer to comment. */
-
-} SH_INFO_1;
-
-/* SH_INFO_1_STR (level 1 share info strings) */
-typedef struct str_share_info1
-{
- UNISTR2 uni_netname; /* unicode string of net name */
- UNISTR2 uni_remark; /* unicode string of comment. */
-
-} SH_INFO_1_STR;
-
-/* oops - this is going to take up a *massive* amount of stack. */
-/* the UNISTR2s already have 1024 uint16 chars in them... */
-#define MAX_SHARE_ENTRIES 32
-
-/* SHARE_INFO_1_CONTAINER */
-typedef struct share_info_ctr
-{
- uint32 num_entries_read; /* EntriesRead */
- uint32 ptr_share_info; /* Buffer */
- uint32 num_entries_read2; /* EntriesRead */
- SH_INFO_1 info_1 [MAX_SHARE_ENTRIES]; /* share entry pointers */
- SH_INFO_1_STR info_1_str[MAX_SHARE_ENTRIES]; /* share entry strings */
- uint32 num_entries_read3; /* EntriesRead2 */
- uint32 padding; /* padding */
-
-} SHARE_INFO_1_CTR;
-
-
-/* SRV_Q_NET_SHARE_ENUM */
-typedef struct q_net_share_enum_info
-{
- uint32 ptr_srv_name; /* pointer (to server name?) */
- UNISTR2 uni_srv_name; /* server name */
-
- uint32 share_level; /* share level */
- uint32 switch_value; /* switch value */
-
- uint32 ptr_share_info; /* pointer to SHARE_INFO_1_CTR */
-
- union
- {
- SHARE_INFO_1_CTR info1; /* share info with 0 entries */
-
- } share;
-
- uint32 preferred_len; /* preferred maximum length (0xffff ffff) */
-
-} SRV_Q_NET_SHARE_ENUM;
-
-
-/* SRV_R_NET_SHARE_ENUM */
-typedef struct r_net_share_enum_info
-{
- uint32 share_level; /* share level */
- uint32 switch_value; /* switch value */
-
- uint32 ptr_share_info; /* pointer to SHARE_INFO_1_CTR */
- union
- {
- SHARE_INFO_1_CTR info1; /* share info container */
-
- } share;
-
- uint32 status; /* return status */
-
-} SRV_R_NET_SHARE_ENUM;
-
-
-/* SAMR_Q_CLOSE - probably a policy handle close */
-typedef struct q_samr_close_info
-{
- LSA_POL_HND pol; /* policy handle */
-
-} SAMR_Q_CLOSE;
-
-
-/* SAMR_R_CLOSE - probably a policy handle close */
-typedef struct r_samr_close_info
-{
- LSA_POL_HND pol; /* policy handle */
- uint32 status; /* return status */
-
-} SAMR_R_CLOSE;
-
-
-/****************************************************************************
-SAMR_Q_OPEN_SECRET - unknown_0 values seen associated with SIDs:
-
-0x0000 0200 and a specific domain sid - S-1-5-21-44c01ca6-797e5c3d-33f83fd0
-0x0000 0280 and a well-known domain sid - S-1-5-20
-0x2000 0000 and a well-known domain sid - S-1-5-20
-0x2000 0000 and a specific domain sid - S-1-5-21-44c01ca6-797e5c3d-33f83fd0
-*****************************************************************************/
-
-/* SAMR_Q_OPEN_SECRET - probably an open secret */
-typedef struct q_samr_open_secret_info
-{
- LSA_POL_HND pol; /* policy handle */
- uint32 unknown_0; /* 0x2000 0000; 0x0000 0211; 0x0000 0280; 0x0000 0200 - unknown */
- DOM_SID dom_sid; /* domain SID */
-
-} SAMR_Q_OPEN_SECRET;
-
-
-/* SAMR_R_OPEN_SECRET - probably an open */
-typedef struct r_samr_open_secret_info
-{
- LSA_POL_HND pol; /* policy handle associated with the SID */
- uint32 status; /* return status */
-
-} SAMR_R_OPEN_SECRET;
-
-
-/****************************************************************************
-SAMR_Q_LOOKUP_RIDS - do a conversion (only one!) 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_RIDS - probably a "read SAM entry" */
-typedef struct q_samr_lookup_names_info
-{
- LSA_POL_HND pol; /* policy handle */
-
- uint32 num_rids1; /* 1 - number of rids being looked up */
- uint32 rid; /* 0000 03e8 - RID of the server being queried? */
- uint32 ptr; /* 0 - 32 bit unknown */
- uint32 num_rids2; /* 1 - number of rids being looked up */
-
- UNIHDR hdr_mach_acct; /* unicode machine account name header */
- UNISTR2 uni_mach_acct; /* unicode machine account name */
-
-} SAMR_Q_LOOKUP_RIDS;
-
-
-/* SAMR_R_LOOKUP_RIDS - probably an open */
-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_RIDS;
-
-
-/* SAMR_Q_UNKNOWN_22 - probably an open */
-typedef struct q_samr_unknown_22_info
-{
- LSA_POL_HND pol; /* policy handle */
- uint32 unknown_id_0; /* 0x0000 03E8 - 32 bit unknown id */
-
-} SAMR_Q_UNKNOWN_22;
-
-
-/* SAMR_R_UNKNOWN_22 - probably an open */
-typedef struct r_samr_unknown_22_info
-{
- LSA_POL_HND pol; /* policy handle associated with unknown id */
- uint32 status; /* return status */
-
-} SAMR_R_UNKNOWN_22;
-
-
-/* SAMR_Q_UNKNOWN_24 - probably a get sam info */
-typedef struct q_samr_unknown_24_info
-{
- LSA_POL_HND pol; /* policy handle associated with unknown id */
- uint16 unknown_0; /* 0x0015 or 0x0011 - 16 bit unknown */
-
-} SAMR_Q_UNKNOWN_24;
-
-
-/* SAMR_R_UNKNOWN_24 - probably a get sam info */
-typedef struct r_samr_unknown_24_info
-{
- uint32 ptr; /* pointer */
- uint16 unknown_0; /* 0x0015 or 0x0011 - 16 bit unknown (same as above) */
- uint16 unknown_1; /* 0x8b73 - 16 bit unknown */
- 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 unknown_id_0; /* unknown id associated with policy handle */
- uint16 unknown_2; /* 0x0201 - 16 bit unknown */
- uint32 unknown_3; /* 0x0000 0080 - 32 bit unknown */
- 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 */
-
- uint32 status; /* return status */
-
-} SAMR_R_UNKNOWN_24;
-
-
-/* SAMR_Q_UNKNOWN_32 - probably a "create SAM entry" */
-typedef struct q_samr_unknown_32_info
-{
- LSA_POL_HND pol; /* policy handle */
-
- UNIHDR hdr_mach_acct; /* unicode machine account name header */
- UNISTR2 uni_mach_acct; /* unicode machine account name */
-
- uint32 unknown_0; /* 32 bit unknown */
- uint16 unknown_1; /* 16 bit unknown */
- uint16 unknown_2; /* 16 bit unknown */
-
-} SAMR_Q_UNKNOWN_32;
-
-
-/* SAMR_R_UNKNOWN_32 - probably a "create SAM entry" */
-typedef struct r_samr_unknown_32_info
-{
- LSA_POL_HND pol; /* policy handle */
- uint32 unknown_0; /* 0x0000 0030 - 32 bit unknown */
- uint32 padding; /* 0 - 4 byte padding */
-
- uint32 status; /* return status - 0xC000 0099: user exists */
-
-} SAMR_R_UNKNOWN_32;
-
-
-/* SAMR_Q_OPEN_POLICY - probably an open */
-typedef struct q_samr_open_policy_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_OPEN_POLICY;
-
-
-/* SAMR_R_OPEN_POLICY - probably an open */
-typedef struct r_samr_open_policy_info
-{
- LSA_POL_HND pol; /* policy handle */
- uint32 status; /* return status */
-
-} SAMR_R_OPEN_POLICY;
-
-
-/* WKS_Q_UNKNOWN_0 - probably a capabilities request */
-typedef struct q_wks_unknown_0_info
-{
- uint32 ptr_srv_name; /* pointer (to server name?) */
- UNISTR2 uni_srv_name; /* unicode server name starting with '\\' */
-
- uint32 unknown_0; /* 0x64 - 32 bit unknown */
- uint16 unknown_1; /* 16 bit unknown */
-
-} WKS_Q_UNKNOWN_0;
-
-
-/* WKS_R_UNKNOWN_0 - probably a capabilities request */
-typedef struct r_wks_unknown_0_info
-{
- uint32 unknown_0; /* 64 - unknown */
- uint32 ptr_1; /* pointer 1 */
- uint32 unknown_1; /* 0x0000 01f4 - unknown */
- uint32 ptr_srv_name; /* pointer to server name */
- uint32 ptr_dom_name; /* pointer to domain name */
- uint32 unknown_2; /* 4 - unknown */
- uint32 unknown_3; /* 0 - unknown */
-
- UNISTR2 uni_srv_name; /* unicode server name */
- UNISTR2 uni_dom_name; /* unicode domainn name */
- uint32 status; /* return status */
-
-} WKS_R_UNKNOWN_0;
-
+/* Allowable account control bits */
+#define ACB_DISABLED 0x0001 /* 1 = User account disabled */
+#define ACB_HOMDIRREQ 0x0002 /* 1 = Home directory required */
+#define ACB_PWNOTREQ 0x0004 /* 1 = User password not required */
+#define ACB_TEMPDUP 0x0008 /* 1 = Temporary duplicate account */
+#define ACB_NORMAL 0x0010 /* 1 = Normal user account */
+#define ACB_MNS 0x0020 /* 1 = MNS logon user account */
+#define ACB_DOMTRUST 0x0040 /* 1 = Interdomain trust account */
+#define ACB_WSTRUST 0x0080 /* 1 = Workstation trust account */
+#define ACB_SVRTRUST 0x0100 /* 1 = Server trust account */
+#define ACB_PWNOEXP 0x0200 /* 1 = User password does not expire */
+#define ACB_AUTOLOCK 0x0400 /* 1 = Account auto locked */
+
struct smb_passwd
{
int smb_userid;
@@ -1335,6 +286,7 @@ struct smb_passwd
unsigned char *smb_passwd; /* Null if no password */
unsigned char *smb_nt_passwd; /* Null if no password */
/* Other fields / flags may be added later */
+ uint16 acct_ctrl;
};
struct cli_state {
@@ -1491,6 +443,20 @@ typedef struct
} connection_struct;
+/* DOM_CHAL - challenge info */
+typedef struct chal_info
+{
+ uchar data[8]; /* credentials */
+} DOM_CHAL;
+
+/* DOM_CREDs - timestamped client or server credentials */
+typedef struct cred_info
+{
+ DOM_CHAL challenge; /* credentials */
+ UTIME timestamp; /* credential time-stamp */
+
+} DOM_CRED;
+
/* Domain controller authentication protocol info */
struct dcinfo
{
@@ -2058,6 +1024,14 @@ char *Strstr(char *s, char *p);
#define BROWSER_ELECTION_VERSION 0x010f
#define BROWSER_CONSTANT 0xaa55
+/* NT Flags2 bits - cifs6.txt section 3.1.2 */
+
+#define FLAGS2_LONG_PATH_COMPONENTS 0x0001
+#define FLAGS2_EXTENDED_ATTRIBUTES 0x0002
+#define FLAGS2_DFS_PATHNAMES 0x1000
+#define FLAGS2_READ_PERMIT_NO_EXECUTE 0x2000
+#define FLAGS2_32_BIT_ERROR_CODES 0x4000
+#define FLAGS2_UNICODE_STRINGS 0x8000
/* Capabilities. see ftp.microsoft.com/developr/drg/cifs/cifs/cifs4.txt */
@@ -2129,8 +1103,6 @@ enum case_handling {CASE_LOWER,CASE_UPPER};
#define UID_FIELD_INVALID 0
#define VUID_OFFSET 100 /* Amount to bias returned vuid numbers */
-#endif
-
/* Defines needed for multi-codepage support. */
#define MSDOS_LATIN_1_CODEPAGE 850
#define KANJI_CODEPAGE 932
@@ -2227,4 +1199,8 @@ extern int unix_ERR_code;
#define CMD_REPLY 0x8000
+#endif /* _SMB_H */
+
+#include "ntdomain.h"
+
/* _SMB_H */
diff --git a/source3/lib/membuffer.c b/source3/lib/membuffer.c
new file mode 100644
index 0000000000..0665b19ead
--- /dev/null
+++ b/source3/lib/membuffer.c
@@ -0,0 +1,370 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Samba memory buffer functions
+ Copyright (C) Andrew Tridgell 1992-1997
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1997
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*******************************************************************
+ *
+ * Description: memory buffer / stream management.
+ * Author : Luke K C Leighton
+ * Created : Dec 1997
+ *
+
+ * this module is intended for use in streaming data in and out of
+ * buffers. it is intended that a single data stream be subdivided
+ * into manageable sections.
+
+ * for example, an rpc header contains a length field, but until the
+ * data has been created, the length is unknown. using this module,
+ * the header section can be tacked onto the front of the data memory
+ * list once the size of the data section preceding it is known.
+
+ * the "margin" can be used to over-run and retrospectively lengthen
+ * the buffer. this is to save time in some of the loops, where it is
+ * not particularly desirable to realloc data by 1, 2 or 4 bytes
+ * repetitively...
+
+ * each memory buffer contains a start and end offset. the end of
+ * one buffer should equal to the start of the next in the chain.
+ * (end - start = len, instead of end - start + 1 = len)
+
+ * the debug log levels are very high in some of the routines: you
+ * have no idea how boring it gets staring at debug output from these
+
+ ********************************************************************/
+
+
+#include "includes.h"
+
+extern int DEBUGLEVEL;
+
+/*******************************************************************
+ initialise a memory buffer.
+ ********************************************************************/
+void mem_init(struct mem_buf *buf, int margin)
+{
+ buf->dynamic = True;
+ buf->data = NULL;
+ buf->data_size = 0;
+ buf->data_used = 0;
+
+ buf->margin = margin;
+
+ buf->next = NULL;
+
+ buf->offset.start = 0;
+ buf->offset.end = 0;
+}
+
+/*******************************************************************
+ initialise a memory buffer.
+
+ dynamic indicates memory has been dynamically allocated.
+ if mem_free is called, the memory will be freed.
+ ********************************************************************/
+void mem_create(struct mem_buf *buf, char *data, int size, int margin, BOOL dynamic)
+{
+ buf->dynamic = dynamic;
+ buf->data = data;
+ buf->data_size = size;
+ buf->data_used = size;
+
+ buf->margin = margin;
+
+ buf->next = NULL;
+
+ buf->offset.start = 0;
+ buf->offset.end = size;
+}
+
+/*******************************************************************
+ takes a memory buffer out of one structure: puts it in the other.
+ NULLs the one that the buffer is being stolen from.
+ ********************************************************************/
+void mem_take(struct mem_buf *mem_to, struct mem_buf *mem_from)
+{
+ memcpy(mem_to, mem_from, sizeof(*mem_to));
+
+ mem_init(mem_from, mem_from->margin);
+}
+
+/*******************************************************************
+ allocate a memory buffer. assume it's empty
+ ********************************************************************/
+BOOL mem_alloc_data(struct mem_buf *buf, int size)
+{
+ if (!buf->dynamic)
+ {
+ DEBUG(3,("mem_alloc_data: warning - memory buffer type is set to static\n"));
+ }
+
+ buf->data_size = size + buf->margin;
+ buf->data_used = size;
+
+ buf->data = malloc(buf->data_size);
+
+ if (buf->data == NULL)
+ {
+ DEBUG(3,("mem_alloc: could not malloc size %d\n",
+ buf->data_size));
+ mem_init(buf, buf->margin);
+
+ return False;
+ }
+
+ bzero(buf->data, buf->data_size);
+
+ return True;
+}
+
+/*******************************************************************
+ allocates a memory buffer structure
+ ********************************************************************/
+BOOL mem_buf_copy(char *copy_into, struct mem_buf *buf,
+ uint32 offset, uint32 len)
+{
+ uint32 end = offset + len;
+ char *q = NULL;
+ uint32 data_len = mem_buf_len(buf);
+ uint32 start_offset = offset;
+ struct mem_buf **bcp = &buf;
+
+ if (buf == NULL || copy_into == NULL) return False;
+
+ DEBUG(200,("mem_buf_copy: data[%d..%d] offset %d len %d\n",
+ buf->offset.start, data_len, offset, len));
+
+ /* there's probably an off-by-one bug, here, and i haven't even tested the code :-) */
+ while (offset < end && ((q = mem_data(bcp, offset)) != NULL))
+ {
+ uint32 copy_len = (*bcp)->offset.end - offset;
+
+ DEBUG(200,("\tdata[%d..%d] - offset %d len %d\n",
+ (*bcp)->offset.start, (*bcp)->offset.end,
+ offset, copy_len));
+
+ memcpy(copy_into, q, copy_len);
+
+ offset += copy_len;
+ copy_into += copy_len;
+ }
+
+ if ((*bcp) != NULL)
+ {
+ DEBUG(200,("mem_buf_copy: copied %d bytes\n", offset - start_offset));
+ }
+ else
+ {
+ DEBUG(200,("mem_buf_copy: failed\n"));
+ }
+
+ return buf != NULL;
+}
+
+/*******************************************************************
+ allocates a memory buffer structure
+ ********************************************************************/
+BOOL mem_buf_init(struct mem_buf **buf, uint32 margin)
+{
+ if (buf == NULL) return False;
+
+ if ((*buf) == NULL)
+ {
+ (*buf) = malloc(sizeof(**buf));
+ if ((*buf) != NULL)
+ {
+ mem_init((*buf), margin);
+ return True;
+ }
+ }
+ else
+ {
+ (*buf)->margin = margin;
+ return True;
+ }
+ return False;
+}
+
+/*******************************************************************
+ frees up a memory buffer.
+ ********************************************************************/
+void mem_buf_free(struct mem_buf **buf)
+{
+ if (buf == NULL) return;
+ if ((*buf) == NULL) return;
+
+ mem_free_data(*buf); /* delete memory data */
+ free(*buf); /* delete item */
+ (*buf) = NULL;
+}
+
+/*******************************************************************
+ frees a memory buffer chain. assumes that all items are malloced.
+ ********************************************************************/
+void mem_free_chain(struct mem_buf **buf)
+{
+ if (buf == NULL) return;
+ if ((*buf) == NULL) return;
+
+ if ((*buf)->next != NULL)
+ {
+ mem_free_chain(&((*buf)->next)); /* delete all other items in chain */
+ }
+ mem_buf_free(buf);
+}
+
+/*******************************************************************
+ frees a memory buffer.
+ ********************************************************************/
+void mem_free_data(struct mem_buf *buf)
+{
+ if (buf == NULL) return;
+
+ if (buf->data != NULL && buf->dynamic)
+ {
+ free(buf->data); /* delete data in this structure */
+ }
+ mem_init(buf, buf->margin);
+}
+
+/*******************************************************************
+ reallocate a memory buffer, including a safety margin
+ ********************************************************************/
+BOOL mem_realloc_data(struct mem_buf *buf, int new_size)
+{
+ char *new_data;
+
+ if (!buf->dynamic)
+ {
+ DEBUG(3,("mem_realloc_data: memory buffer has not been dynamically allocated!\n"));
+ return False;
+ }
+
+ if (new_size == 0)
+ {
+ mem_free_data(buf);
+ return True;
+ }
+
+ new_data = Realloc(buf->data, new_size + buf->margin);
+
+ if (new_data != NULL)
+ {
+ buf->data = new_data;
+ buf->data_size = new_size + buf->margin;
+ buf->data_used = new_size;
+ }
+ else if (buf->data_size <= new_size)
+ {
+ DEBUG(3,("mem_realloc: warning - could not realloc to %d(+%d)\n",
+ new_size, buf->margin));
+
+ buf->data_used = new_size;
+ }
+ else
+ {
+ DEBUG(3,("mem_realloc: error - could not realloc to %d\n",
+ new_size));
+
+ mem_free_data(buf);
+ return False;
+ }
+
+ return True;
+}
+
+/*******************************************************************
+ reallocate a memory buffer, retrospectively :-)
+ ********************************************************************/
+BOOL mem_grow_data(struct mem_buf **buf, BOOL io, int new_size)
+{
+ if (new_size + (*buf)->margin >= (*buf)->data_size)
+ {
+ if (io)
+ {
+ DEBUG(3,("mem_grow_data: cannot resize when reading from a data stream\n"));
+ }
+ else
+ {
+ return mem_realloc_data((*buf), new_size);
+ return False;
+ }
+ }
+ return True;
+}
+
+/*******************************************************************
+ search for a memory buffer that falls within the specified offset
+ ********************************************************************/
+BOOL mem_find(struct mem_buf **buf, uint32 offset)
+{
+ struct mem_buf *f;
+ if (buf == NULL) return False;
+
+ f = *buf;
+
+ DEBUG(200,("mem_find: data[%d..%d] offset: %d\n",
+ f->offset.start, f->offset.end, offset));
+
+ while (f != NULL && offset >= f->offset.end)
+ {
+ f = f->next;
+
+ DEBUG(200,("mem_find: next[%d..%d]\n",
+ f->offset.start, f->offset.end));
+ }
+
+ (*buf) = f;
+
+ DEBUG(200,("mem_find: found data[%d..%d]\n",
+ (*buf)->offset.start,(*buf)->offset.end));
+
+ return f != NULL;
+}
+
+
+/*******************************************************************
+ add up the lengths of all sections.
+ ********************************************************************/
+uint32 mem_buf_len(struct mem_buf *buf)
+{
+ int len = 0;
+ while (buf != NULL)
+ {
+ len += buf->offset.end - buf->offset.start;
+ buf = buf->next;
+ }
+ return len;
+}
+
+
+/*******************************************************************
+ return the memory location specified by offset. may return NULL.
+ ********************************************************************/
+char *mem_data(struct mem_buf **buf, uint32 offset)
+{
+ if (mem_find(buf, offset))
+ {
+ return &((*buf)->data[offset - (*buf)->offset.start]);
+ }
+ return NULL;
+}
+
+
diff --git a/source3/lib/util.c b/source3/lib/util.c
index 5af41cc06c..19fa42592f 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -4848,4 +4848,29 @@ char *tab_depth(int depth)
return spaces;
}
+/*****************************************************************
+ Convert a domain SID to an ascii string. (non-reentrant).
+*****************************************************************/
+/* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
+char *dom_sid_to_string(DOM_SID *sid)
+{
+ static pstring sidstr;
+ char subauth[16];
+ int i;
+ uint32 ia = (sid->id_auth[5]) +
+ (sid->id_auth[4] << 8 ) +
+ (sid->id_auth[3] << 16) +
+ (sid->id_auth[2] << 24);
+
+ sprintf(sidstr, "S-%d-%d", sid->sid_rev_num, ia);
+
+ for (i = 0; i < sid->num_auths; i++)
+ {
+ sprintf(subauth, "-%d", sid->sub_auths[i]);
+ strcat(sidstr, subauth);
+ }
+
+ DEBUG(7,("dom_sid_to_string returning %s\n", sidstr));
+ return sidstr;
+}
diff --git a/source3/lib/util_hnd.c b/source3/lib/util_hnd.c
new file mode 100644
index 0000000000..c8eabf35b4
--- /dev/null
+++ b/source3/lib/util_hnd.c
@@ -0,0 +1,316 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-1997,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+
+
+extern int DEBUGLEVEL;
+
+#ifndef MAX_OPEN_POLS
+#define MAX_OPEN_POLS 50
+#endif
+
+struct reg_info
+{
+ /* for use by \PIPE\winreg */
+ fstring name; /* name of registry key */
+};
+
+struct samr_info
+{
+ /* for use by the \PIPE\samr policy */
+ DOM_SID sid;
+ uint32 rid; /* relative id associated with the pol_hnd */
+ uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
+};
+
+static struct
+{
+ BOOL open;
+ POLICY_HND pol_hnd;
+
+ union
+ {
+ struct samr_info samr;
+ struct reg_info reg;
+
+ } dev;
+
+} Policy[MAX_OPEN_POLS];
+
+
+#define VALID_POL(pnum) (((pnum) >= 0) && ((pnum) < MAX_OPEN_POLS))
+#define OPEN_POL(pnum) (VALID_POL(pnum) && Policy[pnum].open)
+
+/****************************************************************************
+ create a unique policy handle
+****************************************************************************/
+void create_pol_hnd(POLICY_HND *hnd)
+{
+ static uint32 pol_hnd_low = 0;
+ static uint32 pol_hnd_high = 0;
+
+ if (hnd == NULL) return;
+
+ /* i severely doubt that pol_hnd_high will ever be non-zero... */
+ pol_hnd_low++;
+ if (pol_hnd_low == 0) pol_hnd_high++;
+
+ SIVAL(hnd->data, 0 , 0x0); /* first bit must be null */
+ SIVAL(hnd->data, 4 , pol_hnd_low ); /* second bit is incrementing */
+ SIVAL(hnd->data, 8 , pol_hnd_high); /* second bit is incrementing */
+ SIVAL(hnd->data, 12, time(NULL)); /* something random */
+ SIVAL(hnd->data, 16, getpid()); /* something more random */
+}
+
+/****************************************************************************
+ initialise policy handle states...
+****************************************************************************/
+void init_lsa_policy_hnd(void)
+{
+ int i;
+ for (i = 0; i < MAX_OPEN_POLS; i++)
+ {
+ Policy[i].open = False;
+ }
+
+ return;
+}
+
+/****************************************************************************
+ find first available policy slot. creates a policy handle for you.
+****************************************************************************/
+BOOL open_lsa_policy_hnd(POLICY_HND *hnd)
+{
+ int i;
+
+ for (i = 0; i < MAX_OPEN_POLS; i++)
+ {
+ if (!Policy[i].open)
+ {
+ Policy[i].open = True;
+
+ create_pol_hnd(hnd);
+ memcpy(&(Policy[i].pol_hnd), hnd, sizeof(*hnd));
+
+ DEBUG(4,("Opened policy hnd[%x] ", i));
+ dump_data(4, hnd->data, sizeof(hnd->data));
+
+ return True;
+ }
+ }
+
+ /* i love obscure error messages. */
+#if TERRY_PRATCHET_INTERESTING_TIMES
+ DEBUG(1,("+++ OUT OF CHEESE ERROR +++ REDO FROM START ... @?!*@@\n"));
+#else
+ DEBUG(1,("ERROR - open_lsa_policy_hnd: out of Policy Handles!\n"));
+#endif
+
+ return False;
+}
+
+/****************************************************************************
+ find policy index by handle
+****************************************************************************/
+int find_lsa_policy_by_hnd(POLICY_HND *hnd)
+{
+ int i;
+
+ for (i = 0; i < MAX_OPEN_POLS; i++)
+ {
+ if (memcmp(&(Policy[i].pol_hnd), hnd, sizeof(*hnd)) == 0)
+ {
+ DEBUG(4,("Found policy hnd[%x] ", i));
+ dump_data(4, hnd->data, sizeof(hnd->data));
+
+ return i;
+ }
+ }
+
+ DEBUG(4,("Policy not found: "));
+ dump_data(4, hnd->data, sizeof(hnd->data));
+
+ return -1;
+}
+
+/****************************************************************************
+ set samr rid
+****************************************************************************/
+BOOL set_lsa_policy_samr_rid(POLICY_HND *hnd, uint32 rid)
+{
+ int pnum = find_lsa_policy_by_hnd(hnd);
+
+ if (OPEN_POL(pnum))
+ {
+ DEBUG(3,("%s Setting policy device rid=%x pnum=%x\n",
+ timestring(), rid, pnum));
+
+ Policy[pnum].dev.samr.rid = rid;
+ return True;
+ }
+ else
+ {
+ DEBUG(3,("%s Error setting policy rid=%x (pnum=%x)\n",
+ timestring(), rid, pnum));
+ return False;
+ }
+}
+
+/****************************************************************************
+ set samr pol status. absolutely no idea what this is.
+****************************************************************************/
+BOOL set_lsa_policy_samr_pol_status(POLICY_HND *hnd, uint32 pol_status)
+{
+ int pnum = find_lsa_policy_by_hnd(hnd);
+
+ if (OPEN_POL(pnum))
+ {
+ DEBUG(3,("%s Setting policy status=%x pnum=%x\n",
+ timestring(), pol_status, pnum));
+
+ Policy[pnum].dev.samr.status = pol_status;
+ return True;
+ }
+ else
+ {
+ DEBUG(3,("%s Error setting policy status=%x (pnum=%x)\n",
+ timestring(), pol_status, pnum));
+ return False;
+ }
+}
+
+/****************************************************************************
+ set samr sid
+****************************************************************************/
+BOOL set_lsa_policy_samr_sid(POLICY_HND *hnd, DOM_SID *sid)
+{
+ int pnum = find_lsa_policy_by_hnd(hnd);
+
+ if (OPEN_POL(pnum))
+ {
+ DEBUG(3,("%s Setting policy sid=%s pnum=%x\n",
+ timestring(), dom_sid_to_string(sid), pnum));
+
+ memcpy(&(Policy[pnum].dev.samr.sid), sid, sizeof(*sid));
+ return True;
+ }
+ else
+ {
+ DEBUG(3,("%s Error setting policy sid=%s (pnum=%x)\n",
+ timestring(), dom_sid_to_string(sid), pnum));
+ return False;
+ }
+}
+
+/****************************************************************************
+ set samr rid
+****************************************************************************/
+uint32 get_lsa_policy_samr_rid(POLICY_HND *hnd)
+{
+ int pnum = find_lsa_policy_by_hnd(hnd);
+
+ if (OPEN_POL(pnum))
+ {
+ uint32 rid = Policy[pnum].dev.samr.rid;
+ DEBUG(3,("%s Getting policy device rid=%x pnum=%x\n",
+ timestring(), rid, pnum));
+
+ return rid;
+ }
+ else
+ {
+ DEBUG(3,("%s Error getting policy (pnum=%x)\n",
+ timestring(), pnum));
+ return 0xffffffff;
+ }
+}
+
+/****************************************************************************
+ set reg name
+****************************************************************************/
+BOOL set_lsa_policy_reg_name(POLICY_HND *hnd, fstring name)
+{
+ int pnum = find_lsa_policy_by_hnd(hnd);
+
+ if (OPEN_POL(pnum))
+ {
+ DEBUG(3,("%s Setting policy pnum=%x name=%s\n",
+ timestring(), pnum, name));
+
+ fstrcpy(Policy[pnum].dev.reg.name, name);
+ return True;
+ }
+ else
+ {
+ DEBUG(3,("%s Error setting policy (pnum=%x) name=%s\n",
+ timestring(), pnum, name));
+ return False;
+ }
+}
+
+/****************************************************************************
+ get reg name
+****************************************************************************/
+BOOL get_lsa_policy_reg_name(POLICY_HND *hnd, fstring name)
+{
+ int pnum = find_lsa_policy_by_hnd(hnd);
+
+ if (OPEN_POL(pnum))
+ {
+ fstrcpy(name, Policy[pnum].dev.reg.name);
+
+ DEBUG(3,("%s Getting policy pnum=%x name=%s\n",
+ timestring(), pnum, name));
+
+ return True;
+ }
+ else
+ {
+ DEBUG(3,("%s Error getting policy (pnum=%x)\n",
+ timestring(), pnum));
+ return False;
+ }
+}
+
+/****************************************************************************
+ close an lsa policy
+****************************************************************************/
+BOOL close_lsa_policy_hnd(POLICY_HND *hnd)
+{
+ int pnum = find_lsa_policy_by_hnd(hnd);
+
+ if (OPEN_POL(pnum))
+ {
+ DEBUG(3,("%s Closed policy name pnum=%x\n", timestring(), pnum));
+ Policy[pnum].open = False;
+ return True;
+ }
+ else
+ {
+ DEBUG(3,("%s Error closing policy pnum=%x\n", timestring(), pnum));
+ return False;
+ }
+}
+
diff --git a/source3/lsarpcd/srv_lsa.c b/source3/lsarpcd/srv_lsa.c
new file mode 100644
index 0000000000..60b74cf599
--- /dev/null
+++ b/source3/lsarpcd/srv_lsa.c
@@ -0,0 +1,444 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-1997,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ * Copyright (C) Paul Ashton 1997.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+
+
+/***************************************************************************
+lsa_reply_open_policy
+ ***************************************************************************/
+static void lsa_reply_open_policy(prs_struct *rdata)
+{
+ int i;
+ LSA_R_OPEN_POL r_o;
+
+ /* set up the LSA QUERY INFO response */
+ bzero(&(r_o.pol.data), POL_HND_SIZE);
+ for (i = 4; i < POL_HND_SIZE; i++)
+ {
+ r_o.pol.data[i] = i;
+ }
+ r_o.status = 0x0;
+
+ /* store the response in the SMB stream */
+ lsa_io_r_open_pol("", &r_o, rdata, 0);
+}
+
+/***************************************************************************
+make_dom_query
+ ***************************************************************************/
+static void make_dom_query(DOM_QUERY *d_q, char *dom_name, char *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
+ ***************************************************************************/
+static void lsa_reply_enum_trust_dom(LSA_Q_ENUM_TRUST_DOM *q_e,
+ prs_struct *rdata,
+ uint32 enum_context, char *dom_name, char *dom_sid)
+{
+ LSA_R_ENUM_TRUST_DOM r_e;
+
+ /* set up the LSA QUERY INFO response */
+ make_r_enum_trust_dom(&r_e, enum_context, dom_name, dom_sid,
+ dom_name != NULL ? 0x0 : 0x80000000 | NT_STATUS_UNABLE_TO_FREE_VM);
+
+ /* store the response in the SMB stream */
+ lsa_io_r_enum_trust_dom("", &r_e, rdata, 0);
+}
+
+/***************************************************************************
+lsa_reply_query_info
+ ***************************************************************************/
+static void lsa_reply_query_info(LSA_Q_QUERY_INFO *q_q, prs_struct *rdata,
+ char *dom_name, char *dom_sid)
+{
+ LSA_R_QUERY_INFO r_q;
+
+ /* set up the LSA QUERY INFO response */
+
+ r_q.undoc_buffer = 0x22000000; /* bizarre */
+ r_q.info_class = q_q->info_class;
+
+ make_dom_query(&r_q.dom.id5, dom_name, dom_sid);
+
+ r_q.status = 0x0;
+
+ /* store the response in the SMB stream */
+ lsa_io_r_query("", &r_q, rdata, 0);
+}
+
+/***************************************************************************
+make_dom_ref
+
+ pretty much hard-coded choice of "other" sids, unfortunately...
+
+ ***************************************************************************/
+static void make_dom_ref(DOM_R_REF *ref,
+ char *dom_name, char *dom_sid,
+ char *other_sid1, char *other_sid2, char *other_sid3)
+{
+ int len_dom_name = strlen(dom_name);
+ int len_other_sid1 = strlen(other_sid1);
+ int len_other_sid2 = strlen(other_sid2);
+ int len_other_sid3 = strlen(other_sid3);
+
+ ref->undoc_buffer = 1;
+ ref->num_ref_doms_1 = 4;
+ ref->buffer_dom_name = 1;
+ ref->max_entries = 32;
+ ref->num_ref_doms_2 = 4;
+
+ make_uni_hdr2(&(ref->hdr_dom_name ), len_dom_name , len_dom_name , 0);
+ make_uni_hdr2(&(ref->hdr_ref_dom[0]), len_other_sid1, len_other_sid1, 0);
+ make_uni_hdr2(&(ref->hdr_ref_dom[1]), len_other_sid2, len_other_sid2, 0);
+ make_uni_hdr2(&(ref->hdr_ref_dom[2]), len_other_sid3, len_other_sid3, 0);
+
+ if (dom_name != NULL)
+ {
+ make_unistr(&(ref->uni_dom_name), dom_name);
+ }
+
+ make_dom_sid2(&(ref->ref_dom[0]), dom_sid );
+ make_dom_sid2(&(ref->ref_dom[1]), other_sid1);
+ make_dom_sid2(&(ref->ref_dom[2]), other_sid2);
+ make_dom_sid2(&(ref->ref_dom[3]), other_sid3);
+}
+
+/***************************************************************************
+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],
+ char *dom_name, char *dom_sid,
+ char *other_sid1, char *other_sid2, char *other_sid3)
+{
+ int i;
+
+ make_dom_ref(&(r_l->dom_ref), dom_name, dom_sid,
+ other_sid1, other_sid2, other_sid3);
+
+ r_l->num_entries = num_entries;
+ r_l->undoc_buffer = 1;
+ r_l->num_entries2 = num_entries;
+
+ for (i = 0; i < num_entries; i++)
+ {
+ make_dom_rid2(&(r_l->dom_rid[i]), dom_rids[i]);
+ }
+
+ 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;
+
+ for (i = 0; i < num_entries; i++)
+ {
+ uint32 rid = 0xffffffff;
+ uint8 num_auths = sid[i].sid.num_auths;
+ fstring name;
+ uint32 type;
+
+ trn->ptr_name[i] = 0;
+ trn->ptr_name[(*total)] = 0;
+
+ /* 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)
+ {
+ trn->ptr_name[i] = 1;
+ make_lsa_trans_name(&(trn->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],
+ char *dom_name, char *dom_sid,
+ char *other_sid1, char *other_sid2, char *other_sid3)
+{
+ LSA_R_LOOKUP_SIDS r_l;
+ DOM_R_REF ref;
+ LSA_TRANS_NAME_ENUM names;
+ uint32 mapped_count = 0;
+
+ /* set up the LSA Lookup SIDs response */
+ make_dom_ref(&ref, dom_name, dom_sid, other_sid1, other_sid2, other_sid3);
+ 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],
+ char *dom_name, char *dom_sid,
+ char *other_sid1, char *other_sid2, char *other_sid3)
+{
+ LSA_R_LOOKUP_RIDS r_l;
+
+ /* set up the LSA Lookup RIDs response */
+ make_reply_lookup_rids(&r_l, num_entries, dom_rids,
+ dom_name, dom_sid, other_sid1, other_sid2, other_sid3);
+ r_l.status = 0x0;
+
+ /* store the response in the SMB stream */
+ lsa_io_r_lookup_rids("", &r_l, rdata, 0);
+}
+
+/***************************************************************************
+api_lsa_open_policy
+ ***************************************************************************/
+static void api_lsa_open_policy( int uid, prs_struct *data,
+ prs_struct *rdata )
+{
+ LSA_Q_OPEN_POL q_o;
+
+ /* grab the server, object attributes and desired access flag...*/
+ lsa_io_q_open_pol("", &q_o, data, 0);
+
+ /* lkclXXXX having decoded it, ignore all fields in the open policy! */
+
+ /* return a 20 byte policy handle */
+ lsa_reply_open_policy(rdata);
+}
+
+/***************************************************************************
+api_lsa_enum_trust_dom
+ ***************************************************************************/
+static void api_lsa_enum_trust_dom( int uid, prs_struct *data,
+ prs_struct *rdata )
+{
+ LSA_Q_ENUM_TRUST_DOM q_e;
+
+ /* grab the enum trust domain context etc. */
+ lsa_io_q_enum_trust_dom("", &q_e, data, 0);
+
+ /* construct reply. return status is always 0x0 */
+ lsa_reply_enum_trust_dom(&q_e, rdata,
+ 0, NULL, NULL);
+}
+
+/***************************************************************************
+api_lsa_query_info
+ ***************************************************************************/
+static void api_lsa_query_info( int uid, prs_struct *data,
+ prs_struct *rdata )
+{
+ LSA_Q_QUERY_INFO q_i;
+ pstring dom_name;
+ pstring dom_sid;
+
+ /* grab the info class and policy handle */
+ lsa_io_q_query("", &q_i, data, 0);
+
+ pstrcpy(dom_name, lp_workgroup());
+ pstrcpy(dom_sid , lp_domain_sid());
+
+ /* construct reply. return status is always 0x0 */
+ lsa_reply_query_info(&q_i, rdata, dom_name, dom_sid);
+}
+
+/***************************************************************************
+api_lsa_lookup_sids
+ ***************************************************************************/
+static void api_lsa_lookup_sids( int uid, prs_struct *data,
+ prs_struct *rdata )
+{
+ LSA_Q_LOOKUP_SIDS q_l;
+ pstring dom_name;
+ pstring dom_sid;
+
+ /* grab the info class and policy handle */
+ lsa_io_q_lookup_sids("", &q_l, data, 0);
+
+ pstrcpy(dom_name, lp_workgroup());
+ pstrcpy(dom_sid , lp_domain_sid());
+
+ /* construct reply. return status is always 0x0 */
+ lsa_reply_lookup_sids(rdata,
+ q_l.sids.num_entries, q_l.sids.sid, /* SIDs */
+ dom_name, dom_sid, /* domain name, domain SID */
+ "S-1-1", "S-1-3", "S-1-5"); /* the three other SIDs */
+}
+
+/***************************************************************************
+api_lsa_lookup_names
+ ***************************************************************************/
+static void api_lsa_lookup_names( int uid, prs_struct *data,
+ prs_struct *rdata )
+{
+ int i;
+ LSA_Q_LOOKUP_RIDS q_l;
+ pstring dom_name;
+ pstring dom_sid;
+ uint32 dom_rids[MAX_LOOKUP_SIDS];
+ uint32 dummy_g_rid;
+
+ /* grab the info class and policy handle */
+ lsa_io_q_lookup_rids("", &q_l, data, 0);
+
+ pstrcpy(dom_name, lp_workgroup());
+ pstrcpy(dom_sid , lp_domain_sid());
+
+ /* convert received RIDs to strings, so we can do them. */
+ for (i = 0; i < q_l.num_entries; i++)
+ {
+ char *user_name = unistr2(q_l.lookup_name[i].str.buffer);
+ if (!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 */
+ dom_name, dom_sid, /* domain name, domain SID */
+ "S-1-1", "S-1-3", "S-1-5"); /* the three other SIDs */
+}
+
+/***************************************************************************
+ api_lsa_close
+ ***************************************************************************/
+static void api_lsa_close( int uid, prs_struct *data,
+ prs_struct *rdata)
+{
+ /* XXXX this is NOT good */
+ char *q = mem_data(&(rdata->data), rdata->offset);
+
+ SIVAL(q, 0, 0); q += 4;
+ SIVAL(q, 0, 0); q += 4;
+ SIVAL(q, 0, 0); q += 4;
+ SIVAL(q, 0, 0); q += 4;
+ SIVAL(q, 0, 0); q += 4;
+ SIVAL(q, 0, 0); q += 4;
+
+ rdata->offset += 24;
+}
+
+/***************************************************************************
+ api_lsa_open_secret
+ ***************************************************************************/
+static void api_lsa_open_secret( int uid, prs_struct *data,
+ prs_struct *rdata)
+{
+ /* XXXX this is NOT good */
+ char *q = mem_data(&(rdata->data), rdata->offset);
+
+ SIVAL(q, 0, 0); q += 4;
+ SIVAL(q, 0, 0); q += 4;
+ SIVAL(q, 0, 0); q += 4;
+ SIVAL(q, 0, 0); q += 4;
+ SIVAL(q, 0, 0); q += 4;
+ SIVAL(q, 0, 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND); q += 4;
+
+ rdata->offset += 24;
+}
+
+/***************************************************************************
+ \PIPE\ntlsa commands
+ ***************************************************************************/
+static struct api_struct api_lsa_cmds[] =
+{
+ { "LSA_OPENPOLICY" , LSA_OPENPOLICY , api_lsa_open_policy },
+ { "LSA_QUERYINFOPOLICY" , LSA_QUERYINFOPOLICY , api_lsa_query_info },
+ { "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 }
+};
+
+/***************************************************************************
+ api_ntLsarpcTNP
+ ***************************************************************************/
+BOOL api_ntlsa_rpc(pipes_struct *p, prs_struct *data)
+{
+ return api_rpcTNP(p, "api_ntlsa_rpc", api_lsa_cmds, data);
+}
+
diff --git a/source3/nmbd/nmbd_processlogon.c b/source3/nmbd/nmbd_processlogon.c
index 64f66038e0..f881b867c0 100644
--- a/source3/nmbd/nmbd_processlogon.c
+++ b/source3/nmbd/nmbd_processlogon.c
@@ -195,7 +195,7 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
* Let's ignore the SID.
*/
- strcpy(ascuser, unistr(uniuser));
+ pstrcpy(ascuser, unistr(uniuser));
DEBUG(3,("process_logon_packet: SAMLOGON user %s\n", ascuser));
strcpy(reply_name,"\\\\"); /* Here it wants \\LOGONSERVER. */
@@ -203,12 +203,18 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
smb_pass = get_smbpwd_entry(ascuser, 0);
- if(!smb_pass)
+ if(!smb_pass )
{
DEBUG(3,("process_logon_packet: SAMLOGON request from %s(%s) for %s, not in password file\n",
unistr(unicomp),inet_ntoa(p->ip), ascuser));
return;
}
+ else if(smb_pass->acct_ctrl & ACB_DISABLED)
+ {
+ DEBUG(3,("process_logon_packet: SAMLOGON request from %s(%s) for %s, accound disabled.\n",
+ unistr(unicomp),inet_ntoa(p->ip), ascuser));
+ return;
+ }
else
{
DEBUG(3,("process_logon_packet: SAMLOGON request from %s(%s) for %s, returning logon svr %s domain %s code %x token=%x\n",
diff --git a/source3/nmbd/nmbd_subnetdb.c b/source3/nmbd/nmbd_subnetdb.c
index 07692cc82c..e10ddc2c6a 100644
--- a/source3/nmbd/nmbd_subnetdb.c
+++ b/source3/nmbd/nmbd_subnetdb.c
@@ -300,10 +300,12 @@ struct subnet_record *get_next_subnet_maybe_unicast(struct subnet_record *subrec
struct subnet_record *get_next_subnet_maybe_unicast_or_wins_server(struct subnet_record *subrec)
{
if(subrec == unicast_subnet)
+ {
if(wins_server_subnet)
return wins_server_subnet;
else
return NULL;
+ }
if(wins_server_subnet && subrec == wins_server_subnet)
return NULL;
diff --git a/source3/nmbd/nmbd_winsserver.c b/source3/nmbd/nmbd_winsserver.c
index 134b758c29..afc8741366 100644
--- a/source3/nmbd/nmbd_winsserver.c
+++ b/source3/nmbd/nmbd_winsserver.c
@@ -1260,12 +1260,13 @@ void send_wins_name_query_response(int rcode, struct packet_struct *p,
}
}
- for(; i < namerec->num_ips; i++)
+ for(j = 0; j < namerec->num_ips; j++)
{
- if(i == same_net_index)
+ if(j == same_net_index)
continue;
set_nb_flags(&prdata[i*6],namerec->nb_flags);
- putip((char *)&prdata[2+(i*6)], &namerec->ip[i]);
+ putip((char *)&prdata[2+(i*6)], &namerec->ip[j]);
+ i++;
}
reply_data_len = namerec->num_ips * 6;
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index 39f6de0e1e..2768a9da72 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -461,7 +461,7 @@ static struct parm_struct parm_table[] =
{"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, 0},
{"valid chars", P_STRING, P_GLOBAL, &Globals.szValidChars, handle_valid_chars, NULL, 0},
{"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkGroup, NULL, NULL, FLAG_BASIC},
-#ifdef NTDOMAIN
+
{"domain sid", P_USTRING, P_GLOBAL, &Globals.szDomainSID, NULL, NULL, 0},
{"domain other sids",P_STRING, P_GLOBAL, &Globals.szDomainOtherSIDs, NULL, NULL, 0},
{"domain groups", P_STRING, P_GLOBAL, &Globals.szDomainGroups, NULL, NULL, 0},
@@ -472,7 +472,7 @@ static struct parm_struct parm_table[] =
{"domain allow hosts",P_STRING, P_GLOBAL, &Globals.szDomainHostsallow, NULL, NULL, 0},
{"domain hosts deny", P_STRING, P_GLOBAL, &Globals.szDomainHostsdeny, NULL, NULL, 0},
{"domain deny hosts", P_STRING, P_GLOBAL, &Globals.szDomainHostsdeny, NULL, NULL, 0},
-#endif /* NTDOMAIN */
+
{"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, 0},
{"character set", P_STRING, P_GLOBAL, &Globals.szCharacterSet, handle_character_set, NULL, 0},
{"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, 0},
@@ -898,7 +898,6 @@ FN_GLOBAL_STRING(lp_announce_version,&Globals.szAnnounceVersion)
FN_GLOBAL_STRING(lp_netbios_aliases,&Globals.szNetbiosAliases)
FN_GLOBAL_STRING(lp_driverfile,&Globals.szDriverFile)
-#ifdef NTDOMAIN
FN_GLOBAL_STRING(lp_domain_sid,&Globals.szDomainSID)
FN_GLOBAL_STRING(lp_domain_other_sids,&Globals.szDomainOtherSIDs)
FN_GLOBAL_STRING(lp_domain_groups,&Globals.szDomainGroups)
@@ -906,7 +905,6 @@ FN_GLOBAL_STRING(lp_domain_admin_users,&Globals.szDomainAdminUsers)
FN_GLOBAL_STRING(lp_domain_guest_users,&Globals.szDomainGuestUsers)
FN_GLOBAL_STRING(lp_domain_hostsallow,&Globals.szDomainHostsallow)
FN_GLOBAL_STRING(lp_domain_hostsdeny,&Globals.szDomainHostsdeny)
-#endif /* NTDOMAIN */
FN_GLOBAL_BOOL(lp_dns_proxy,&Globals.bDNSproxy)
FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport)
diff --git a/source3/passdb/smbpass.c b/source3/passdb/smbpass.c
index fbda8949bc..b51f675306 100644
--- a/source3/passdb/smbpass.c
+++ b/source3/passdb/smbpass.c
@@ -19,854 +19,844 @@
#include "includes.h"
-extern int DEBUGLEVEL;
+extern int DEBUGLEVEL;
-int gotalarm;
+static int gotalarm;
+static char s_readbuf[16 * 1024];
-void
-gotalarm_sig()
+/***************************************************************
+ Signal function to tell us we timed out.
+****************************************************************/
+
+static void gotalarm_sig()
{
- gotalarm = 1;
+ gotalarm = 1;
}
-int
-do_pw_lock(int fd, int waitsecs, int type)
+/***************************************************************
+ Lock or unlock a fd for a known lock type. Abandon after waitsecs
+ seconds.
+****************************************************************/
+
+static int do_pw_lock(int fd, int waitsecs, int type)
{
- struct flock lock;
- int ret;
-
- gotalarm = 0;
- signal(SIGALRM, SIGNAL_CAST gotalarm_sig);
-
- lock.l_type = type;
- lock.l_whence = SEEK_SET;
- lock.l_start = 0;
- lock.l_len = 1;
- lock.l_pid = 0;
-
- alarm(5);
- ret = fcntl(fd, F_SETLKW, &lock);
- alarm(0);
- signal(SIGALRM, SIGNAL_CAST SIG_DFL);
-
- if (gotalarm) {
- DEBUG(0, ("do_pw_lock: failed to %s SMB passwd file.\n",
- type == F_UNLCK ? "unlock" : "lock"));
- return -1;
- }
- return ret;
+ struct flock lock;
+ int ret;
+
+ gotalarm = 0;
+ signal(SIGALRM, SIGNAL_CAST gotalarm_sig);
+
+ lock.l_type = type;
+ lock.l_whence = SEEK_SET;
+ lock.l_start = 0;
+ lock.l_len = 1;
+ lock.l_pid = 0;
+
+ alarm(5);
+ ret = fcntl(fd, F_SETLKW, &lock);
+ alarm(0);
+ signal(SIGALRM, SIGNAL_CAST SIG_DFL);
+
+ if (gotalarm) {
+ DEBUG(0, ("do_pw_lock: failed to %s SMB passwd file.\n",
+ type == F_UNLCK ? "unlock" : "lock"));
+ return -1;
+ }
+ return ret;
}
-int pw_file_lock(char *name, int type, int secs)
+/***************************************************************
+ Lock an fd. Abandon after waitsecs seconds.
+****************************************************************/
+
+int pw_file_lock(int fd, int type, int secs)
{
- int fd = open(name, O_RDWR | O_CREAT, 0600);
- if (fd < 0)
- return (-1);
- if (do_pw_lock(fd, secs, type)) {
- close(fd);
- return -1;
- }
- return fd;
+ if (fd < 0)
+ return (-1);
+ if (do_pw_lock(fd, secs, type)) {
+ return -1;
+ }
+ return fd;
}
+/***************************************************************
+ Unlock an fd. Abandon after waitsecs seconds.
+****************************************************************/
+
int pw_file_unlock(int fd)
{
- do_pw_lock(fd, 5, F_UNLCK);
- return close(fd);
+ return do_pw_lock(fd, 5, F_UNLCK);
}
-/*
- * Routine to get the next 32 hex characters and turn them
- * into a 16 byte array.
- */
+/***************************************************************
+ Open the smbpasswd file - get ready to enumerate it.
+****************************************************************/
+
+FILE *startsmbpwent(BOOL update)
+{
+ FILE *fp = NULL;
+ char *pfile = lp_smb_passwd_file();
+
+ if (!*pfile) {
+ DEBUG(0, ("startsmbpwent: No SMB password file set\n"));
+ return (NULL);
+ }
+ DEBUG(10, ("startsmbpwent: opening file %s\n", pfile));
+
+ fp = fopen(pfile, update ? "r+b" : "rb");
+
+ if (fp == NULL) {
+ DEBUG(0, ("startsmbpwent: unable to open file %s\n", pfile));
+ return NULL;
+ }
+
+ /* Set a 16k buffer to do more efficient reads */
+ setvbuf(fp, s_readbuf, _IOFBF, sizeof(s_readbuf));
+
+ if ((pw_file_lock(fileno(fp), F_RDLCK | (update ? F_WRLCK : 0), 5)) < 0) {
+ DEBUG(0, ("startsmbpwent: unable to lock file %s\n", pfile));
+ fclose(fp);
+ return NULL;
+ }
+
+ /* Make sure it is only rw by the owner */
+ chmod(pfile, 0600);
+
+ /* We have a lock on the file. */
+ return fp;
+}
+
+/***************************************************************
+ Close the smbpasswd file - end enumeration.
+****************************************************************/
+
+void endsmbpwent(FILE *fp)
+{
+ pw_file_unlock(fileno(fp));
+ fclose(fp);
+ DEBUG(7, ("endsmbpwent: closed password file.\n"));
+}
+
+/*************************************************************
+ Routine to get the next 32 hex characters and turn them
+ into a 16 byte array.
+**************************************************************/
static int gethexpwd(char *p, char *pwd)
{
- int i;
- unsigned char lonybble, hinybble;
- char *hexchars = "0123456789ABCDEF";
- char *p1, *p2;
-
- for (i = 0; i < 32; i += 2) {
- hinybble = toupper(p[i]);
- lonybble = toupper(p[i + 1]);
+ int i;
+ unsigned char lonybble, hinybble;
+ char *hexchars = "0123456789ABCDEF";
+ char *p1, *p2;
+
+ for (i = 0; i < 32; i += 2) {
+ hinybble = toupper(p[i]);
+ lonybble = toupper(p[i + 1]);
- p1 = strchr(hexchars, hinybble);
- p2 = strchr(hexchars, lonybble);
- if (!p1 || !p2)
- return (False);
- hinybble = PTR_DIFF(p1, hexchars);
- lonybble = PTR_DIFF(p2, hexchars);
+ p1 = strchr(hexchars, hinybble);
+ p2 = strchr(hexchars, lonybble);
+ if (!p1 || !p2)
+ return (False);
+ hinybble = PTR_DIFF(p1, hexchars);
+ lonybble = PTR_DIFF(p2, hexchars);
- pwd[i / 2] = (hinybble << 4) | lonybble;
- }
- return (True);
+ pwd[i / 2] = (hinybble << 4) | lonybble;
+ }
+ return (True);
}
/*************************************************************************
- Routine to search the smbpasswd file for an entry matching the username
- or user id. if the name is NULL, then the smb_uid is used instead.
+ Routine to return the next entry in the smbpasswd file.
*************************************************************************/
-struct smb_passwd *get_smbpwd_entry(char *name, int smb_userid)
+
+struct smb_passwd *getsmbpwent(FILE *fp)
{
- /* Static buffers we will return. */
- static struct smb_passwd pw_buf;
- static pstring user_name;
- static unsigned char smbpwd[16];
- static unsigned char smbntpwd[16];
- char linebuf[256];
- char readbuf[16 * 1024];
- unsigned char c;
- unsigned char *p;
- long uidval;
- long linebuf_len;
- FILE *fp;
- int lockfd;
- char *pfile = lp_smb_passwd_file();
-
- if (!*pfile) {
- DEBUG(0, ("No SMB password file set\n"));
- return (NULL);
- }
- DEBUG(10, ("get_smbpwd_entry: opening file %s\n", pfile));
-
- if (name != NULL)
- {
- DEBUG(10, ("get_smbpwd_entry: search by name: %s\n", name));
- }
- else
- {
- DEBUG(10, ("get_smbpwd_entry: search by smb_userid: %x\n", smb_userid));
- }
-
- fp = fopen(pfile, "r");
-
- if (fp == NULL) {
- DEBUG(0, ("get_smbpwd_entry: unable to open file %s\n", pfile));
- return NULL;
- }
- /* Set a 16k buffer to do more efficient reads */
- setvbuf(fp, readbuf, _IOFBF, sizeof(readbuf));
-
- if ((lockfd = pw_file_lock(pfile, F_RDLCK, 5)) < 0) {
- DEBUG(0, ("get_smbpwd_entry: unable to lock file %s\n", pfile));
- fclose(fp);
- return NULL;
- }
- /* make sure it is only rw by the owner */
- chmod(pfile, 0600);
-
- /* We have a read lock on the file. */
- /*
- * Scan the file, a line at a time and check if the name matches.
- */
- while (!feof(fp)) {
- linebuf[0] = '\0';
-
- fgets(linebuf, 256, fp);
- if (ferror(fp)) {
- fclose(fp);
- pw_file_unlock(lockfd);
- return NULL;
- }
- /*
- * Check if the string is terminated with a newline - if not
- * then we must keep reading and discard until we get one.
- */
- linebuf_len = strlen(linebuf);
- if (linebuf[linebuf_len - 1] != '\n') {
- c = '\0';
- while (!ferror(fp) && !feof(fp)) {
- c = fgetc(fp);
- if (c == '\n')
- break;
- }
- } else
- linebuf[linebuf_len - 1] = '\0';
+ /* Static buffers we will return. */
+ static struct smb_passwd pw_buf;
+ static pstring user_name;
+ static unsigned char smbpwd[16];
+ static unsigned char smbntpwd[16];
+ char linebuf[256];
+ unsigned char c;
+ unsigned char *p;
+ long uidval;
+ long linebuf_len;
+
+ if(fp == NULL) {
+ DEBUG(0,("getsmbpwent: Bad password file pointer.\n"));
+ return NULL;
+ }
+
+ /*
+ * Scan the file, a line at a time and check if the name matches.
+ */
+ while (!feof(fp)) {
+ linebuf[0] = '\0';
+
+ fgets(linebuf, 256, fp);
+ if (ferror(fp)) {
+ return NULL;
+ }
+
+ /*
+ * Check if the string is terminated with a newline - if not
+ * then we must keep reading and discard until we get one.
+ */
+ linebuf_len = strlen(linebuf);
+ if (linebuf[linebuf_len - 1] != '\n') {
+ c = '\0';
+ while (!ferror(fp) && !feof(fp)) {
+ c = fgetc(fp);
+ if (c == '\n')
+ break;
+ }
+ } else
+ linebuf[linebuf_len - 1] = '\0';
#ifdef DEBUG_PASSWORD
- DEBUG(100, ("get_smbpwd_entry: got line |%s|\n", linebuf));
+ DEBUG(100, ("getsmbpwent: got line |%s|\n", linebuf));
#endif
- if ((linebuf[0] == 0) && feof(fp)) {
- DEBUG(4, ("get_smbpwd_entry: end of file reached\n"));
- break;
- }
- /*
- * The line we have should be of the form :-
- *
- * username:uid:[32hex bytes]:....other flags presently
- * ignored....
- *
- * or,
- *
- * username:uid:[32hex bytes]:[32hex bytes]:....ignored....
- *
- * if Windows NT compatible passwords are also present.
- */
-
- if (linebuf[0] == '#' || linebuf[0] == '\0') {
- DEBUG(6, ("get_smbpwd_entry: skipping comment or blank line\n"));
- continue;
- }
- p = (unsigned char *) strchr(linebuf, ':');
- if (p == NULL) {
- DEBUG(0, ("get_smbpwd_entry: malformed password entry (no :)\n"));
- continue;
- }
- /*
- * As 256 is shorter than a pstring we don't need to check
- * length here - if this ever changes....
- */
- strncpy(user_name, linebuf, PTR_DIFF(p, linebuf));
- user_name[PTR_DIFF(p, linebuf)] = '\0';
-
- /* get smb uid */
-
- p++; /* Go past ':' */
- if (!isdigit(*p)) {
- DEBUG(0, ("get_smbpwd_entry: malformed password entry (uid not number)\n"));
- continue;
- }
-
- uidval = atoi((char *) p);
-
- while (*p && isdigit(*p))
- {
- p++;
- }
-
- if (*p != ':')
- {
- DEBUG(0, ("get_smbpwd_entry: malformed password entry (no : after uid)\n"));
- continue;
- }
-
- if (name != NULL)
- {
- /* search is by user name */
- if (!strequal(user_name, name)) continue;
- DEBUG(10, ("get_smbpwd_entry: found by name: %s\n", user_name));
- }
- else
- {
- /* search is by user id */
- if (uidval != smb_userid) continue;
- DEBUG(10, ("get_smbpwd_entry: found by smb_userid: %x\n", uidval));
- }
-
- /* if we're here, the entry has been found (either by name or uid) */
-
- /*
- * Now get the password value - this should be 32 hex digits
- * which are the ascii representations of a 16 byte string.
- * Get two at a time and put them into the password.
- */
-
- /* skip the ':' */
- p++;
-
- if (*p == '*' || *p == 'X')
- {
- /* Password deliberately invalid - end here. */
- DEBUG(10, ("get_smbpwd_entry: entry invalidated for user %s\n", user_name));
- fclose(fp);
- pw_file_unlock(lockfd);
- return NULL;
- }
-
- if (linebuf_len < (PTR_DIFF(p, linebuf) + 33))
- {
- DEBUG(0, ("get_smbpwd_entry: malformed password entry (passwd too short)\n"));
- fclose(fp);
- pw_file_unlock(lockfd);
- return (False);
- }
-
- if (p[32] != ':')
- {
- DEBUG(0, ("get_smbpwd_entry: malformed password entry (no terminating :)\n"));
- fclose(fp);
- pw_file_unlock(lockfd);
- return NULL;
- }
-
- if (!strncasecmp((char *) p, "NO PASSWORD", 11))
- {
- pw_buf.smb_passwd = NULL;
- }
- else
- {
- if (!gethexpwd((char *)p, (char *)smbpwd))
- {
- DEBUG(0, ("Malformed Lanman password entry (non hex chars)\n"));
- fclose(fp);
- pw_file_unlock(lockfd);
- return NULL;
- }
- pw_buf.smb_passwd = smbpwd;
- }
-
- pw_buf.smb_name = user_name;
- pw_buf.smb_userid = uidval;
- pw_buf.smb_nt_passwd = NULL;
-
- /* Now check if the NT compatible password is
- available. */
- p += 33; /* Move to the first character of the line after
- the lanman password. */
- if ((linebuf_len >= (PTR_DIFF(p, linebuf) + 33)) && (p[32] == ':')) {
- if (*p != '*' && *p != 'X') {
- if(gethexpwd((char *)p,(char *)smbntpwd))
- pw_buf.smb_nt_passwd = smbntpwd;
- }
- }
-
- fclose(fp);
- pw_file_unlock(lockfd);
- DEBUG(5, ("get_smbpwd_entrye: returning passwd entry for user %s, uid %d\n",
+ if ((linebuf[0] == 0) && feof(fp)) {
+ DEBUG(4, ("getsmbpwent: end of file reached\n"));
+ break;
+ }
+ /*
+ * The line we have should be of the form :-
+ *
+ * username:uid:[32hex bytes]:....other flags presently
+ * ignored....
+ *
+ * or,
+ *
+ * username:uid:[32hex bytes]:[32hex bytes]:....ignored....
+ *
+ * if Windows NT compatible passwords are also present.
+ */
+
+ if (linebuf[0] == '#' || linebuf[0] == '\0') {
+ DEBUG(6, ("getsmbpwent: skipping comment or blank line\n"));
+ continue;
+ }
+ p = (unsigned char *) strchr(linebuf, ':');
+ if (p == NULL) {
+ DEBUG(0, ("getsmbpwent: malformed password entry (no :)\n"));
+ continue;
+ }
+ /*
+ * As 256 is shorter than a pstring we don't need to check
+ * length here - if this ever changes....
+ */
+ strncpy(user_name, linebuf, PTR_DIFF(p, linebuf));
+ user_name[PTR_DIFF(p, linebuf)] = '\0';
+
+ /* Get smb uid. */
+
+ p++; /* Go past ':' */
+ if (!isdigit(*p)) {
+ DEBUG(0, ("getsmbpwent: malformed password entry (uid not number)\n"));
+ continue;
+ }
+
+ uidval = atoi((char *) p);
+
+ while (*p && isdigit(*p))
+ p++;
+
+ if (*p != ':') {
+ DEBUG(0, ("getsmbpwent: malformed password entry (no : after uid)\n"));
+ continue;
+ }
+
+ pw_buf.smb_name = user_name;
+ pw_buf.smb_userid = uidval;
+
+ /*
+ * Now get the password value - this should be 32 hex digits
+ * which are the ascii representations of a 16 byte string.
+ * Get two at a time and put them into the password.
+ */
+
+ /* Skip the ':' */
+ p++;
+
+ if (*p == '*' || *p == 'X') {
+ /* Password deliberately invalid - end here. */
+ DEBUG(10, ("getsmbpwent: entry invalidated for user %s\n", user_name));
+ pw_buf.smb_nt_passwd = NULL;
+ pw_buf.smb_passwd = NULL;
+ pw_buf.acct_ctrl |= ACB_DISABLED;
+ return &pw_buf;
+ }
+
+ if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) {
+ DEBUG(0, ("getsmbpwent: malformed password entry (passwd too short)\n"));
+ continue;
+ }
+
+ if (p[32] != ':') {
+ DEBUG(0, ("getsmbpwent: malformed password entry (no terminating :)\n"));
+ continue;
+ }
+
+ if (!strncasecmp((char *) p, "NO PASSWORD", 11)) {
+ pw_buf.smb_passwd = NULL;
+ pw_buf.acct_ctrl |= ACB_PWNOTREQ;
+ } else {
+ if (!gethexpwd((char *)p, (char *)smbpwd)) {
+ DEBUG(0, ("getsmbpwent: Malformed Lanman password entry (non hex chars)\n"));
+ continue;
+ }
+ pw_buf.smb_passwd = smbpwd;
+ }
+
+ /*
+ * Now check if the NT compatible password is
+ * available.
+ */
+ pw_buf.smb_nt_passwd = NULL;
+
+ p += 33; /* Move to the first character of the line after
+ the lanman password. */
+ if ((linebuf_len >= (PTR_DIFF(p, linebuf) + 33)) && (p[32] == ':')) {
+ if (*p != '*' && *p != 'X') {
+ if(gethexpwd((char *)p,(char *)smbntpwd))
+ pw_buf.smb_nt_passwd = smbntpwd;
+ }
+ p += 33; /* Move to the first character of the line after
+ the NT password. */
+ }
+
+ DEBUG(5, ("getsmbpwent: returning passwd entry for user %s, uid %d\n",
user_name, uidval));
- return &pw_buf;
- }
- fclose(fp);
- pw_file_unlock(lockfd);
- return NULL;
+ /*
+ * Check if the account type bits have been encoded after the
+ * NT password (in the form [NDHTUWSLXI]).
+ */
+
+ if (*p == '[') {
+ BOOL finished = False;
+
+ pw_buf.acct_ctrl = 0;
+
+ for(p++;*p && !finished; p++) {
+ switch (*p) {
+ case 'N':
+ /* 'N'o password. */
+ pw_buf.acct_ctrl |= ACB_PWNOTREQ;
+ break;
+ case 'D':
+ /* 'D'isabled. */
+ pw_buf.acct_ctrl |= ACB_DISABLED;
+ break;
+ case 'H':
+ /* 'H'omedir required. */
+ pw_buf.acct_ctrl |= ACB_HOMDIRREQ;
+ break;
+ case 'T':
+ /* 'T'emp account. */
+ pw_buf.acct_ctrl |= ACB_TEMPDUP;
+ break;
+ case 'U':
+ /* 'U'ser account (normal). */
+ pw_buf.acct_ctrl |= ACB_NORMAL;
+ break;
+ case 'M':
+ /* 'M'NS logon user account. What is this ? */
+ pw_buf.acct_ctrl |= ACB_MNS;
+ break;
+ case 'W':
+ /* 'W'orkstation account. */
+ pw_buf.acct_ctrl |= ACB_WSTRUST;
+ break;
+ case 'S':
+ /* 'S'erver account. */
+ pw_buf.acct_ctrl |= ACB_SVRTRUST;
+ break;
+ case 'L':
+ /* 'L'ocked account. */
+ pw_buf.acct_ctrl |= ACB_AUTOLOCK;
+ break;
+ case 'X':
+ /* No 'X'piry. */
+ pw_buf.acct_ctrl |= ACB_PWNOEXP;
+ break;
+ case 'I':
+ /* 'I'nterdomain trust account. */
+ pw_buf.acct_ctrl |= ACB_DOMTRUST;
+ break;
+
+ case ':':
+ case '\n':
+ case '\0':
+ case ']':
+ default:
+ finished = True;
+ }
+ }
+
+ /* Must have some account type set. */
+ if(pw_buf.acct_ctrl == 0)
+ pw_buf.acct_ctrl = ACB_NORMAL;
+
+ } else {
+ /* 'Old' style file. Fake up based on user name. */
+ /*
+ * Currently machine accounts are kept in the same
+ * password file as 'normal accounts'. If this changes
+ * we will have to fix this code. JRA.
+ */
+ if(pw_buf.smb_name[strlen(pw_buf.smb_name) - 1] == '$')
+ pw_buf.acct_ctrl = ACB_WSTRUST;
+ else
+ pw_buf.acct_ctrl = ACB_NORMAL;
+ }
+
+ return &pw_buf;
+ }
+
+ DEBUG(5,("getsmbpwent: end of file reached.\n"));
+ return NULL;
}
-/*
- * Routine to search the smbpasswd file for an entry matching the username.
- */
-BOOL add_smbpwd_entry(struct smb_passwd* pwd)
+/*************************************************************************
+ Routine to search the smbpasswd file for an entry matching the username
+ or user id. if the name is NULL, then the smb_uid is used instead.
+ *************************************************************************/
+
+struct smb_passwd *get_smbpwd_entry(char *name, int smb_userid)
{
- /* Static buffers we will return. */
- static pstring user_name;
-
- char linebuf[256];
- char readbuf[16 * 1024];
- unsigned char c;
- unsigned char *p;
- long linebuf_len;
- FILE *fp;
- int lockfd;
- char *pfile = lp_smb_passwd_file();
-
- int i;
- int wr_len;
-
- int fd;
- int new_entry_length;
- char *new_entry;
- long offpos;
-
- if (!*pfile)
- {
- DEBUG(0, ("No SMB password file set\n"));
- return False;
- }
- DEBUG(10, ("add_smbpwd_entry: opening file %s\n", pfile));
-
- fp = fopen(pfile, "r+");
-
- if (fp == NULL)
- {
- DEBUG(0, ("add_smbpwd_entry: unable to open file %s\n", pfile));
- return False;
- }
- /* Set a 16k buffer to do more efficient reads */
- setvbuf(fp, readbuf, _IOFBF, sizeof(readbuf));
-
- if ((lockfd = pw_file_lock(pfile, F_RDLCK | F_WRLCK, 5)) < 0)
- {
- DEBUG(0, ("add_smbpwd_entry: unable to lock file %s\n", pfile));
- fclose(fp);
- return False;
- }
- /* make sure it is only rw by the owner */
- chmod(pfile, 0600);
-
- /* We have a write lock on the file. */
- /*
- * Scan the file, a line at a time and check if the name matches.
- */
- while (!feof(fp))
- {
- linebuf[0] = '\0';
-
- fgets(linebuf, 256, fp);
- if (ferror(fp))
- {
- fclose(fp);
- pw_file_unlock(lockfd);
- return False;
- }
-
- /*
- * Check if the string is terminated with a newline - if not
- * then we must keep reading and discard until we get one.
- */
- linebuf_len = strlen(linebuf);
- if (linebuf[linebuf_len - 1] != '\n')
- {
- c = '\0';
- while (!ferror(fp) && !feof(fp))
- {
- c = fgetc(fp);
- if (c == '\n')
- {
- break;
- }
- }
- }
- else
- {
- linebuf[linebuf_len - 1] = '\0';
- }
+ struct smb_passwd *pwd = NULL;
+ FILE *fp = NULL;
+
+ if (name != NULL) {
+ DEBUG(10, ("get_smbpwd_entry: search by name: %s\n", name));
+ } else {
+ DEBUG(10, ("get_smbpwd_entry: search by smb_userid: %x\n", smb_userid));
+ }
+
+ /* Open the smbpassword file - not for update. */
+ fp = startsmbpwent(False);
+
+ if (fp == NULL) {
+ DEBUG(0, ("get_smbpwd_entry: unable to open password file.\n"));
+ return NULL;
+ }
+
+ /*
+ * Scan the file, a line at a time and check if the name
+ * or uid matches.
+ */
+
+ while ((pwd = getsmbpwent(fp)) != NULL) {
+ if (name != NULL) {
+ /* Search is by user name */
+ if (!strequal(pwd->smb_name, name))
+ continue;
+ DEBUG(10, ("get_smbpwd_entry: found by name: %s\n", name));
+ break;
+ } else {
+ /* Search is by user id */
+ if (pwd->smb_userid != smb_userid)
+ continue;
+ DEBUG(10, ("get_smbpwd_entry: found by smb_userid: %x\n", smb_userid));
+ break;
+ }
+ }
+
+ endsmbpwent(fp);
+ return pwd;
+}
-#ifdef DEBUG_PASSWORD
- DEBUG(100, ("add_smbpwd_entry: got line |%s|\n", linebuf));
-#endif
+/************************************************************************
+ Routine to add an entry to the smbpasswd file.
+*************************************************************************/
- if ((linebuf[0] == 0) && feof(fp))
- {
- DEBUG(4, ("add_smbpwd_entry: end of file reached\n"));
- break;
- }
-
- /*
- * The line we have should be of the form :-
- *
- * username:uid:[32hex bytes]:....other flags presently
- * ignored....
- *
- * or,
- *
- * username:uid:[32hex bytes]:[32hex bytes]:....ignored....
- *
- * if Windows NT compatible passwords are also present.
- */
-
- if (linebuf[0] == '#' || linebuf[0] == '\0')
- {
- DEBUG(6, ("add_smbpwd_entry: skipping comment or blank line\n"));
- continue;
- }
-
- p = (unsigned char *) strchr(linebuf, ':');
-
- if (p == NULL)
- {
- DEBUG(0, ("add_smbpwd_entry: malformed password entry (no :)\n"));
- continue;
- }
-
- /*
- * As 256 is shorter than a pstring we don't need to check
- * length here - if this ever changes....
- */
- strncpy(user_name, linebuf, PTR_DIFF(p, linebuf));
- user_name[PTR_DIFF(p, linebuf)] = '\0';
- if (strequal(user_name, pwd->smb_name))
- {
- DEBUG(6, ("add_smbpwd_entry: entry already exists\n"));
- return False;
- }
- }
-
- /* ok - entry doesn't exist. we can add it */
-
- /* Create a new smb passwd entry and set it to the given password. */
- /* The add user write needs to be atomic - so get the fd from
- the fp and do a raw write() call.
- */
- fd = fileno(fp);
-
- if((offpos = lseek(fd, 0, SEEK_END)) == -1)
- {
- DEBUG(0, ("add_smbpwd_entry(lseek): Failed to add entry for user %s to file %s. \
+BOOL add_smbpwd_entry(struct smb_passwd *newpwd)
+{
+ char *pfile = lp_smb_passwd_file();
+ struct smb_passwd *pwd = NULL;
+ FILE *fp = NULL;
+
+ int i;
+ int wr_len;
+
+ int fd;
+ int new_entry_length;
+ char *new_entry;
+ long offpos;
+ unsigned char *p;
+
+ /* Open the smbpassword file - for update. */
+ fp = startsmbpwent(True);
+
+ if (fp == NULL) {
+ DEBUG(0, ("add_smbpwd_entry: unable to open file.\n"));
+ return False;
+ }
+
+ /*
+ * Scan the file, a line at a time and check if the name matches.
+ */
+
+ while ((pwd = getsmbpwent(fp)) != NULL) {
+ if (strequal(newpwd->smb_name, pwd->smb_name)) {
+ DEBUG(0, ("add_smbpwd_entry: entry with name %s already exists\n", pwd->smb_name));
+ endsmbpwent(fp);
+ return False;
+ }
+ }
+
+ /* Ok - entry doesn't exist. We can add it */
+
+ /* Create a new smb passwd entry and set it to the given password. */
+ /*
+ * The add user write needs to be atomic - so get the fd from
+ * the fp and do a raw write() call.
+ */
+ fd = fileno(fp);
+
+ if((offpos = lseek(fd, 0, SEEK_END)) == -1) {
+ DEBUG(0, ("add_smbpwd_entry(lseek): Failed to add entry for user %s to file %s. \
Error was %s\n", pwd->smb_name, pfile, strerror(errno)));
+ endsmbpwent(fp);
+ return False;
+ }
- fclose(fp);
- pw_file_unlock(lockfd);
- return False;
- }
-
- new_entry_length = strlen(pwd->smb_name) + 1 + 15 + 1 + 32 + 1 + 32 + 1 + 2;
+ new_entry_length = strlen(pwd->smb_name) + 1 + 15 + 1 + 32 + 1 + 32 + 1 + 2;
- if((new_entry = (char *)malloc( new_entry_length )) == 0)
- {
- DEBUG(0, ("add_smbpwd_entry(malloc): Failed to add entry for user %s to file %s. \
-Error was %s\n",
- pwd->smb_name, pfile, strerror(errno)));
+ if((new_entry = (char *)malloc( new_entry_length )) == NULL) {
+ DEBUG(0, ("add_smbpwd_entry(malloc): Failed to add entry for user %s to file %s. \
+Error was %s\n", pwd->smb_name, pfile, strerror(errno)));
+ endsmbpwent(fp);
+ return False;
+ }
- fclose(fp);
- pw_file_unlock(lockfd);
- return False;
- }
+ sprintf(new_entry, "%s:%u:", pwd->smb_name, (unsigned)pwd->smb_userid);
+ p = (unsigned char *)&new_entry[strlen(new_entry)];
- sprintf(new_entry, "%s:%u:", pwd->smb_name, (unsigned)pwd->smb_userid);
- p = (unsigned char *)&new_entry[strlen(new_entry)];
+ for( i = 0; i < 16; i++) {
+ sprintf((char *)&p[i*2], "%02X", pwd->smb_passwd[i]);
+ }
- for( i = 0; i < 16; i++)
- {
- sprintf((char *)&p[i*2], "%02X", pwd->smb_passwd[i]);
- }
- p += 32;
+ p += 32;
- *p++ = ':';
+ *p++ = ':';
- for( i = 0; i < 16; i++)
- {
- sprintf((char *)&p[i*2], "%02X", pwd->smb_nt_passwd[i]);
- }
- p += 32;
+ for( i = 0; i < 16; i++) {
+ sprintf((char *)&p[i*2], "%02X", pwd->smb_nt_passwd[i]);
+ }
+ p += 32;
- *p++ = ':';
- sprintf((char *)p,"\n");
+ *p++ = ':';
+ sprintf((char *)p,"\n");
#ifdef DEBUG_PASSWORD
- DEBUG(100, ("add_smbpwd_entry(%d): new_entry_len %d entry_len %d made line |%s|\n",
+ DEBUG(100, ("add_smbpwd_entry(%d): new_entry_len %d entry_len %d made line |%s|\n",
fd, new_entry_length, strlen(new_entry), new_entry));
#endif
- if ((wr_len = write(fd, new_entry, strlen(new_entry))) != strlen(new_entry))
- {
- DEBUG(0, ("add_smbpwd_entry(write): %d Failed to add entry for user %s to file %s. \
+ if ((wr_len = write(fd, new_entry, strlen(new_entry))) != strlen(new_entry)) {
+ DEBUG(0, ("add_smbpwd_entry(write): %d Failed to add entry for user %s to file %s. \
Error was %s\n", wr_len, pwd->smb_name, pfile, strerror(errno)));
- /* Remove the entry we just wrote. */
- if(ftruncate(fd, offpos) == -1)
- {
- DEBUG(0, ("add_smbpwd_entry: ERROR failed to ftruncate file %s. \
+ /* Remove the entry we just wrote. */
+ if(ftruncate(fd, offpos) == -1) {
+ DEBUG(0, ("add_smbpwd_entry: ERROR failed to ftruncate file %s. \
Error was %s. Password file may be corrupt ! Please examine by hand !\n",
- pwd->smb_name, strerror(errno)));
- }
+ pwd->smb_name, strerror(errno)));
+ }
- fclose(fp);
- pw_file_unlock(lockfd);
- return False;
- }
+ endsmbpwent(fp);
+ return False;
+ }
- fclose(fp);
- pw_file_unlock(lockfd);
- return True;
+ endsmbpwent(fp);
+ return True;
}
-/*
- * Routine to search the smbpasswd file for an entry matching the username.
- * and then modify its password entry
- */
+
+/************************************************************************
+ Routine to search the smbpasswd file for an entry matching the username.
+ and then modify its password entry. We can't use the startsmbpwent()/
+ getsmbpwent()/endsmbpwent() interfaces here as we depend on looking
+ in the actual file to decide how much room we have to write data.
+************************************************************************/
+
BOOL mod_smbpwd_entry(struct smb_passwd* pwd)
{
- /* Static buffers we will return. */
- static pstring user_name;
-
- char linebuf[256];
- char readbuf[16 * 1024];
- unsigned char c;
- char ascii_p16[66];
- unsigned char *p = NULL;
- long linebuf_len = 0;
- FILE *fp;
- int lockfd;
- char *pfile = lp_smb_passwd_file();
- BOOL found_entry = False;
-
- long pwd_seekpos = 0;
-
- int i;
- int wr_len;
- int fd;
-
- if (!*pfile)
- {
- DEBUG(0, ("No SMB password file set\n"));
- return False;
- }
- DEBUG(10, ("mod_smbpwd_entry: opening file %s\n", pfile));
-
- fp = fopen(pfile, "r+");
-
- if (fp == NULL)
- {
- DEBUG(0, ("mod_smbpwd_entry: unable to open file %s\n", pfile));
- return False;
- }
- /* Set a 16k buffer to do more efficient reads */
- setvbuf(fp, readbuf, _IOFBF, sizeof(readbuf));
-
- if ((lockfd = pw_file_lock(pfile, F_RDLCK | F_WRLCK, 5)) < 0)
- {
- DEBUG(0, ("mod_smbpwd_entry: unable to lock file %s\n", pfile));
- fclose(fp);
- return False;
- }
- /* make sure it is only rw by the owner */
- chmod(pfile, 0600);
-
- /* We have a write lock on the file. */
- /*
- * Scan the file, a line at a time and check if the name matches.
- */
- while (!feof(fp))
- {
- pwd_seekpos = ftell(fp);
-
- linebuf[0] = '\0';
-
- fgets(linebuf, 256, fp);
- if (ferror(fp))
- {
- fclose(fp);
- pw_file_unlock(lockfd);
- return False;
- }
-
- /*
- * Check if the string is terminated with a newline - if not
- * then we must keep reading and discard until we get one.
- */
- linebuf_len = strlen(linebuf);
- if (linebuf[linebuf_len - 1] != '\n')
- {
- c = '\0';
- while (!ferror(fp) && !feof(fp))
- {
- c = fgetc(fp);
- if (c == '\n')
- {
- break;
- }
- }
- }
- else
- {
- linebuf[linebuf_len - 1] = '\0';
- }
+ /* Static buffers we will return. */
+ static pstring user_name;
+
+ char linebuf[256];
+ char readbuf[16 * 1024];
+ unsigned char c;
+ char ascii_p16[66];
+ unsigned char *p = NULL;
+ long linebuf_len = 0;
+ FILE *fp;
+ int lockfd;
+ char *pfile = lp_smb_passwd_file();
+ BOOL found_entry = False;
+
+ long pwd_seekpos = 0;
+
+ int i;
+ int wr_len;
+ int fd;
+
+ if (!*pfile) {
+ DEBUG(0, ("No SMB password file set\n"));
+ return False;
+ }
+ DEBUG(10, ("mod_smbpwd_entry: opening file %s\n", pfile));
+
+ fp = fopen(pfile, "r+");
+
+ if (fp == NULL) {
+ DEBUG(0, ("mod_smbpwd_entry: unable to open file %s\n", pfile));
+ return False;
+ }
+ /* Set a 16k buffer to do more efficient reads */
+ setvbuf(fp, readbuf, _IOFBF, sizeof(readbuf));
+
+ if ((lockfd = pw_file_lock(fileno(fp), F_RDLCK | F_WRLCK, 5)) < 0) {
+ DEBUG(0, ("mod_smbpwd_entry: unable to lock file %s\n", pfile));
+ fclose(fp);
+ return False;
+ }
+
+ /* Make sure it is only rw by the owner */
+ chmod(pfile, 0600);
+
+ /* We have a write lock on the file. */
+ /*
+ * Scan the file, a line at a time and check if the name matches.
+ */
+ while (!feof(fp)) {
+ pwd_seekpos = ftell(fp);
+
+ linebuf[0] = '\0';
+
+ fgets(linebuf, 256, fp);
+ if (ferror(fp)) {
+ fclose(fp);
+ pw_file_unlock(lockfd);
+ return False;
+ }
+
+ /*
+ * Check if the string is terminated with a newline - if not
+ * then we must keep reading and discard until we get one.
+ */
+ linebuf_len = strlen(linebuf);
+ if (linebuf[linebuf_len - 1] != '\n') {
+ c = '\0';
+ while (!ferror(fp) && !feof(fp)) {
+ c = fgetc(fp);
+ if (c == '\n') {
+ break;
+ }
+ }
+ } else {
+ linebuf[linebuf_len - 1] = '\0';
+ }
#ifdef DEBUG_PASSWORD
- DEBUG(100, ("mod_smbpwd_entry: got line |%s|\n", linebuf));
+ DEBUG(100, ("mod_smbpwd_entry: got line |%s|\n", linebuf));
#endif
- if ((linebuf[0] == 0) && feof(fp))
- {
- DEBUG(4, ("mod_smbpwd_entry: end of file reached\n"));
- break;
- }
-
- /*
- * The line we have should be of the form :-
- *
- * username:uid:[32hex bytes]:....other flags presently
- * ignored....
- *
- * or,
- *
- * username:uid:[32hex bytes]:[32hex bytes]:....ignored....
- *
- * if Windows NT compatible passwords are also present.
- */
-
- if (linebuf[0] == '#' || linebuf[0] == '\0')
- {
- DEBUG(6, ("mod_smbpwd_entry: skipping comment or blank line\n"));
- continue;
- }
-
- p = (unsigned char *) strchr(linebuf, ':');
-
- if (p == NULL)
- {
- DEBUG(0, ("mod_smbpwd_entry: malformed password entry (no :)\n"));
- continue;
- }
-
- /*
- * As 256 is shorter than a pstring we don't need to check
- * length here - if this ever changes....
- */
- strncpy(user_name, linebuf, PTR_DIFF(p, linebuf));
- user_name[PTR_DIFF(p, linebuf)] = '\0';
- if (strequal(user_name, pwd->smb_name))
- {
- found_entry = True;
- break;
- }
- }
-
- if (!found_entry) return False;
-
- DEBUG(6, ("mod_smbpwd_entry: entry exists\n"));
-
- /* User name matches - get uid and password */
- p++; /* Go past ':' */
-
- if (!isdigit(*p))
- {
- DEBUG(0, ("mod_smbpwd_entry: malformed password entry (uid not number)\n"));
- fclose(fp);
- pw_file_unlock(lockfd);
- return False;
- }
-
- while (*p && isdigit(*p))
- p++;
- if (*p != ':')
- {
- DEBUG(0, ("mod_smbpwd_entry: malformed password entry (no : after uid)\n"));
- fclose(fp);
- pw_file_unlock(lockfd);
- return False;
- }
- /*
- * Now get the password value - this should be 32 hex digits
- * which are the ascii representations of a 16 byte string.
- * Get two at a time and put them into the password.
- */
- p++;
-
- /* record exact password position */
- pwd_seekpos += PTR_DIFF(p, linebuf);
-
- if (*p == '*' || *p == 'X')
- {
- /* Password deliberately invalid - end here. */
- DEBUG(10, ("get_smbpwd_entry: entry invalidated for user %s\n", user_name));
- fclose(fp);
- pw_file_unlock(lockfd);
- return False;
- }
-
- if (linebuf_len < (PTR_DIFF(p, linebuf) + 33))
- {
- DEBUG(0, ("mod_smbpwd_entry: malformed password entry (passwd too short)\n"));
- fclose(fp);
- pw_file_unlock(lockfd);
- return (False);
- }
-
- if (p[32] != ':')
- {
- DEBUG(0, ("mod_smbpwd_entry: malformed password entry (no terminating :)\n"));
- fclose(fp);
- pw_file_unlock(lockfd);
- return False;
- }
-
- if (*p == '*' || *p == 'X')
- {
- fclose(fp);
- pw_file_unlock(lockfd);
- return False;
- }
- if (!strncasecmp((char *) p, "NO PASSWORD", 11))
- {
- fclose(fp);
- pw_file_unlock(lockfd);
- return False;
- }
-
- /* Now check if the NT compatible password is
- available. */
- p += 33; /* Move to the first character of the line after
- the lanman password. */
- if (linebuf_len < (PTR_DIFF(p, linebuf) + 33))
- {
- DEBUG(0, ("mod_smbpwd_entry: malformed password entry (passwd too short)\n"));
- fclose(fp);
- pw_file_unlock(lockfd);
- return (False);
- }
-
- if (p[32] != ':')
- {
- DEBUG(0, ("mod_smbpwd_entry: malformed password entry (no terminating :)\n"));
- fclose(fp);
- pw_file_unlock(lockfd);
- return False;
- }
-
- /* The following check is wrong - the NT hash is optional. */
-#if 0
- if (*p == '*' || *p == 'X')
- {
- fclose(fp);
- pw_file_unlock(lockfd);
- return False;
- }
-#endif
-
- /* whew. entry is correctly formed. */
-
- /*
- * Do an atomic write into the file at the position defined by
- * seekpos.
- */
-
- /* The mod user write needs to be atomic - so get the fd from
- the fp and do a raw write() call.
- */
-
- fd = fileno(fp);
-
- if (lseek(fd, pwd_seekpos - 1, SEEK_SET) != pwd_seekpos - 1)
- {
- DEBUG(1, ("mod_smbpwd_entry: seek fail on file %s.\n", pfile));
- fclose(fp);
- pw_file_unlock(lockfd);
- return False;
- }
-
- /* Sanity check - ensure the character is a ':' */
- if (read(fd, &c, 1) != 1)
- {
- DEBUG(1, ("mod_smbpwd_entry: read fail on file %s.\n", pfile));
- fclose(fp);
- pw_file_unlock(lockfd);
- return False;
- }
-
- if (c != ':')
- {
- DEBUG(1, ("mod_smbpwd_entry: check on passwd file %s failed.\n", pfile));
- fclose(fp);
- pw_file_unlock(lockfd);
- return False;
- }
+ if ((linebuf[0] == 0) && feof(fp)) {
+ DEBUG(4, ("mod_smbpwd_entry: end of file reached\n"));
+ break;
+ }
+
+ /*
+ * The line we have should be of the form :-
+ *
+ * username:uid:[32hex bytes]:....other flags presently
+ * ignored....
+ *
+ * or,
+ *
+ * username:uid:[32hex bytes]:[32hex bytes]:....ignored....
+ *
+ * if Windows NT compatible passwords are also present.
+ */
+
+ if (linebuf[0] == '#' || linebuf[0] == '\0') {
+ DEBUG(6, ("mod_smbpwd_entry: skipping comment or blank line\n"));
+ continue;
+ }
+
+ p = (unsigned char *) strchr(linebuf, ':');
+
+ if (p == NULL) {
+ DEBUG(0, ("mod_smbpwd_entry: malformed password entry (no :)\n"));
+ continue;
+ }
+
+ /*
+ * As 256 is shorter than a pstring we don't need to check
+ * length here - if this ever changes....
+ */
+ strncpy(user_name, linebuf, PTR_DIFF(p, linebuf));
+ user_name[PTR_DIFF(p, linebuf)] = '\0';
+ if (strequal(user_name, pwd->smb_name)) {
+ found_entry = True;
+ break;
+ }
+ }
+
+ if (!found_entry) return False;
+
+ DEBUG(6, ("mod_smbpwd_entry: entry exists\n"));
+
+ /* User name matches - get uid and password */
+ p++; /* Go past ':' */
+
+ if (!isdigit(*p)) {
+ DEBUG(0, ("mod_smbpwd_entry: malformed password entry (uid not number)\n"));
+ fclose(fp);
+ pw_file_unlock(lockfd);
+ return False;
+ }
+
+ while (*p && isdigit(*p))
+ p++;
+ if (*p != ':') {
+ DEBUG(0, ("mod_smbpwd_entry: malformed password entry (no : after uid)\n"));
+ fclose(fp);
+ pw_file_unlock(lockfd);
+ return False;
+ }
+
+ /*
+ * Now get the password value - this should be 32 hex digits
+ * which are the ascii representations of a 16 byte string.
+ * Get two at a time and put them into the password.
+ */
+ p++;
+
+ /* Record exact password position */
+ pwd_seekpos += PTR_DIFF(p, linebuf);
+
+ if (*p == '*' || *p == 'X') {
+ /* Password deliberately invalid - end here. */
+ DEBUG(10, ("get_smbpwd_entry: entry invalidated for user %s\n", user_name));
+ fclose(fp);
+ pw_file_unlock(lockfd);
+ return False;
+ }
+
+ if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) {
+ DEBUG(0, ("mod_smbpwd_entry: malformed password entry (passwd too short)\n"));
+ fclose(fp);
+ pw_file_unlock(lockfd);
+ return (False);
+ }
+
+ if (p[32] != ':') {
+ DEBUG(0, ("mod_smbpwd_entry: malformed password entry (no terminating :)\n"));
+ fclose(fp);
+ pw_file_unlock(lockfd);
+ return False;
+ }
+
+ if (*p == '*' || *p == 'X') {
+ fclose(fp);
+ pw_file_unlock(lockfd);
+ return False;
+ }
+
+ if (!strncasecmp((char *) p, "NO PASSWORD", 11)) {
+ fclose(fp);
+ pw_file_unlock(lockfd);
+ return False;
+ }
+
+ /* Now check if the NT compatible password is
+ available. */
+ p += 33; /* Move to the first character of the line after
+ the lanman password. */
+ if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) {
+ DEBUG(0, ("mod_smbpwd_entry: malformed password entry (passwd too short)\n"));
+ fclose(fp);
+ pw_file_unlock(lockfd);
+ return (False);
+ }
+
+ if (p[32] != ':') {
+ DEBUG(0, ("mod_smbpwd_entry: malformed password entry (no terminating :)\n"));
+ fclose(fp);
+ pw_file_unlock(lockfd);
+ return False;
+ }
+
+ /* Entry is correctly formed. */
+
+ /*
+ * Do an atomic write into the file at the position defined by
+ * seekpos.
+ */
+
+ /* The mod user write needs to be atomic - so get the fd from
+ the fp and do a raw write() call.
+ */
+
+ fd = fileno(fp);
+
+ if (lseek(fd, pwd_seekpos - 1, SEEK_SET) != pwd_seekpos - 1) {
+ DEBUG(0, ("mod_smbpwd_entry: seek fail on file %s.\n", pfile));
+ fclose(fp);
+ pw_file_unlock(lockfd);
+ return False;
+ }
+
+ /* Sanity check - ensure the character is a ':' */
+ if (read(fd, &c, 1) != 1) {
+ DEBUG(0, ("mod_smbpwd_entry: read fail on file %s.\n", pfile));
+ fclose(fp);
+ pw_file_unlock(lockfd);
+ return False;
+ }
+
+ if (c != ':') {
+ DEBUG(0, ("mod_smbpwd_entry: check on passwd file %s failed.\n", pfile));
+ fclose(fp);
+ pw_file_unlock(lockfd);
+ return False;
+ }
- /* Create the 32 byte representation of the new p16 */
- for (i = 0; i < 16; i++)
- {
- sprintf(&ascii_p16[i*2], "%02X", (uchar) pwd->smb_passwd[i]);
- }
- /* Add on the NT md4 hash */
- ascii_p16[32] = ':';
- wr_len = 65;
- if (pwd->smb_nt_passwd != NULL)
- {
- for (i = 0; i < 16; i++)
- {
- sprintf(&ascii_p16[(i*2)+33], "%02X", (uchar) pwd->smb_nt_passwd[i]);
- }
- }
- else
- {
- /* No NT hash - write out an 'invalid' string. */
- strcpy(&ascii_p16[33], "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
- }
+ /* Create the 32 byte representation of the new p16 */
+ for (i = 0; i < 16; i++) {
+ sprintf(&ascii_p16[i*2], "%02X", (uchar) pwd->smb_passwd[i]);
+ }
+
+ /* Add on the NT md4 hash */
+ ascii_p16[32] = ':';
+ wr_len = 65;
+ if (pwd->smb_nt_passwd != NULL) {
+ for (i = 0; i < 16; i++) {
+ sprintf(&ascii_p16[(i*2)+33], "%02X", (uchar) pwd->smb_nt_passwd[i]);
+ }
+ } else {
+ /* No NT hash - write out an 'invalid' string. */
+ strcpy(&ascii_p16[33], "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
+ }
#ifdef DEBUG_PASSWORD
- DEBUG(100,("mod_smbpwd_entry: "));
- dump_data(100, ascii_p16, wr_len);
+ DEBUG(100,("mod_smbpwd_entry: "));
+ dump_data(100, ascii_p16, wr_len);
#endif
- if (write(fd, ascii_p16, wr_len) != wr_len)
- {
- DEBUG(1, ("mod_smbpwd_entry: write failed in passwd file %s\n", pfile));
- fclose(fp);
- pw_file_unlock(lockfd);
- return False;
- }
-
- fclose(fp);
- pw_file_unlock(lockfd);
- return True;
+ if (write(fd, ascii_p16, wr_len) != wr_len) {
+ DEBUG(0, ("mod_smbpwd_entry: write failed in passwd file %s\n", pfile));
+ fclose(fp);
+ pw_file_unlock(lockfd);
+ return False;
+ }
+
+ fclose(fp);
+ pw_file_unlock(lockfd);
+ return True;
}
diff --git a/source3/rpc_client/cli_login.c b/source3/rpc_client/cli_login.c
new file mode 100644
index 0000000000..2033ea437e
--- /dev/null
+++ b/source3/rpc_client/cli_login.c
@@ -0,0 +1,395 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ NT Domain Authentication SMB / MSRPC client
+ Copyright (C) Andrew Tridgell 1994-1997
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1997
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+
+#ifdef SYSLOG
+#undef SYSLOG
+#endif
+
+#include "includes.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+
+
+#if 0
+ if (!cli_initialise(cli, t_idx))
+ {
+ DEBUG(1,("do_nt_session_open: cli_initialise failed\n"));
+ return False;
+ }
+
+ DEBUG(1,("do_nt_session_open: server connect initialisation\n"));
+
+ if (!server_connect_init(cli, t_idx, myhostname, dest_ip, dest_host))
+ {
+ uint8 err_cls;
+ uint32 err_num;
+ cli_error(cli, t_idx, &err_cls, &err_num);
+ DEBUG(1,("server_connect_init failed (%s)\n", cli_errstr(cli, t_idx)));
+
+ return False;
+ }
+
+ DEBUG(1,("do_nt_session_open: server connect initialisation succeeded\n"));
+
+ if (!cli_session_setup(cli, t_idx, "", "", 1, NULL, 0, workgroup))
+ {
+ uint8 err_cls;
+ uint32 err_num;
+ cli_error(cli, t_idx, &err_cls, &err_num);
+ DEBUG(1,("session setup failed (%s)\n", cli_errstr(cli, t_idx)));
+
+ return False;
+ }
+
+ DEBUG(1,("do_nt_session_open: server session setup succeeded\n"));
+
+ if (!cli_send_tconX(cli, t_idx, "IPC$", "IPC", "", 1))
+ {
+ uint8 err_cls;
+ uint32 err_num;
+ cli_error(cli, t_idx, &err_cls, &err_num);
+ DEBUG(1,("cli_send_tconX failed (%s)\n", cli_errstr(cli, t_idx)));
+
+ return False;
+ }
+
+ DEBUG(1,("do_nt_session_open: server IPC$ connection succeeded\n"));
+#endif
+
+
+/****************************************************************************
+experimental nt login.
+
+****************************************************************************/
+BOOL do_nt_session_open(struct cli_state *cli, int t_idx, uint16 *fnum,
+ char *dest_host, char *myhostname,
+ char *mach_acct,
+ char *username, char *workgroup,
+ uchar sess_key[16], DOM_CRED *clnt_cred)
+{
+ DOM_CHAL clnt_chal;
+ DOM_CHAL srv_chal;
+
+ DOM_CHAL auth2_srv_chal;
+
+ UTIME zerotime;
+
+ char nt_owf_mach_pwd[16];
+ char nt_owf_prev_mpd[16];
+
+ RPC_IFACE abstract;
+ RPC_IFACE transfer;
+
+ fstring mach_pwd;
+ fstring prev_mpd;
+ fstring dest_srv;
+
+ /******************** initialise ********************************/
+
+ zerotime.time = 0;
+
+ DEBUG(1,("do_nt_session_open: %d\n", __LINE__));
+
+ /******************* open the \PIPE\NETLOGON file *****************/
+
+ if (((*fnum) = cli_open(cli, t_idx, PIPE_NETLOGON, O_CREAT, DENY_NONE,
+ NULL, NULL, NULL)) == 0xffff)
+ {
+ DEBUG(1,("do_nt_session_open: cli_open failed\n"));
+ return False;
+ }
+
+ /**************** Set Named Pipe State ***************/
+ if (!rpc_pipe_set_hnd_state(cli, t_idx, PIPE_NETLOGON, *fnum, 0x4300))
+ {
+ DEBUG(1,("do_nt_session_open: pipe hnd state failed\n"));
+ return False;
+ }
+
+ /******************* bind request on \PIPE\NETLOGON *****************/
+
+ if (!rpc_pipe_bind(cli, t_idx, PIPE_NETLOGON, *fnum,
+ &abstract, &transfer,
+ False, NULL, NULL))
+ {
+ DEBUG(1,("do_nt_session_open: rpc bind failed\n"));
+ return False;
+ }
+
+ /************ Check workstation trust account *******************/
+
+ /* default machine password is lower-case machine name (really secure) */
+ fstrcpy(mach_pwd, myhostname);
+ strlower(mach_pwd);
+
+ /* default machine password is lower-case machine name (really secure) */
+ fstrcpy(prev_mpd, myhostname);
+ strlower(prev_mpd);
+
+ /******************* Request Challenge ********************/
+
+ SIVAL(clnt_chal.data, 0, 0x11111111);
+ SIVAL(clnt_chal.data, 4, 0x22222222);
+
+ strcpy(dest_srv, "\\\\");
+ strcat(dest_srv, dest_host);
+ strupper(dest_srv);
+
+ /* send a client challenge; receive a server challenge */
+ if (!do_net_req_chal(cli, t_idx, *fnum, dest_srv, myhostname, &clnt_chal, &srv_chal))
+ {
+ DEBUG(1,("do_nt_session_open: request challenge failed\n"));
+ return False;
+ }
+
+ /**************** Long-term Session key **************/
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("generating nt owf from initial machine pwd: %s\n", mach_pwd));
+#endif
+ nt_owf_gen( mach_pwd, nt_owf_mach_pwd);
+
+#ifdef DEBUG_PASSWORD
+ dump_data(6, nt_owf_mach_pwd, 16);
+#endif
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("generating nt owf from previous machine pwd: %s\n", prev_mpd));
+#endif
+ nt_owf_gen( mach_pwd, nt_owf_prev_mpd);
+
+#ifdef DEBUG_PASSWORD
+ dump_data(6, nt_owf_prev_mpd, 16);
+#endif
+
+ /* calculate the session key */
+ cred_session_key(&clnt_chal, &srv_chal, nt_owf_mach_pwd, sess_key);
+#if 0
+ cred_session_key(&clnt_chal, &srv_chal, nt_owf_prev_mpd, sess_key+8);
+#else
+ bzero(sess_key+8, 8);
+#endif
+
+ /******************* Authenticate 2 ********************/
+
+ /* calculate auth-2 credentials */
+ cred_create(sess_key, &clnt_chal, zerotime, &(clnt_cred->challenge));
+
+ /* send client auth-2 challenge; receive an auth-2 challenge */
+ if (!do_net_auth2(cli, t_idx, *fnum,
+ dest_srv, mach_acct,
+ SEC_CHAN_WKSTA, myhostname,
+ &(clnt_cred->challenge), 0x000001ff, &auth2_srv_chal))
+ {
+ DEBUG(1,("do_nt_session_open: request challenge failed\n"));
+ return False;
+ }
+
+ return True;
+}
+
+/****************************************************************************
+ server password set
+ ****************************************************************************/
+BOOL do_nt_srv_pwset(struct cli_state *cli, int t_idx, uint16 fnum,
+ uint8 sess_key[16], DOM_CRED *clnt_cred, DOM_CRED *rtn_cred,
+ char *new_mach_pwd,
+ char *dest_host, char *mach_acct, char *myhostname)
+{
+ /**************** Net Server Password Set **************/
+
+ DOM_CRED cred;
+ char nt_cypher[16];
+ uint8 mode = 1;
+ char nt_owf_new_mach_pwd[16];
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("generating nt owf from new machine pwd: %s\n", new_mach_pwd));
+#endif
+ nt_owf_gen(new_mach_pwd, nt_owf_new_mach_pwd);
+
+#ifdef DEBUG_PASSWORD
+dump_data(6, nt_owf_new_mach_pwd, 16);
+#endif
+
+ if (!obfuscate_pwd(nt_cypher, nt_owf_new_mach_pwd, mode))
+ {
+ DEBUG(5,("do_nt_srv_pwset: encrypt mach pwd failed\n"));
+ return False;
+ }
+
+ clnt_cred->timestamp.time = time(NULL);
+
+ memcpy(&cred, clnt_cred, sizeof(cred));
+
+ /* calculate credentials */
+ cred_create(sess_key, &(clnt_cred->challenge),
+ cred.timestamp,
+ &(cred.challenge));
+
+ /* send client srv_pwset challenge */
+ return do_net_srv_pwset(cli, t_idx, fnum, sess_key, clnt_cred,
+ dest_host, mach_acct, 2, myhostname,
+ &cred, rtn_cred,
+ nt_cypher);
+}
+
+/****************************************************************************
+ make interactive sam login info
+ ****************************************************************************/
+void make_nt_login_interactive(NET_ID_INFO_CTR *ctr,
+ uchar sess_key[16],
+ char *workgroup, char *myhostname,
+ uint32 smb_userid, char *username)
+{
+ /****************** SAM Info Preparation *******************/
+
+ char *smb_user_passwd = getpass("Enter NT Login Password:");
+
+ char lm_owf_user_pwd[16];
+ char nt_owf_user_pwd[16];
+
+ nt_lm_owf_gen(smb_user_passwd, nt_owf_user_pwd, lm_owf_user_pwd);
+
+#ifdef DEBUG_PASSWORD
+
+ DEBUG(100,("nt owf of user password: "));
+ dump_data(100, lm_owf_user_pwd, 16);
+
+ DEBUG(100,("nt owf of user password: "));
+ dump_data(100, nt_owf_user_pwd, 16);
+
+#endif
+
+ /* indicate an "interactive" login */
+ ctr->switch_value = 1;
+
+ /* this is used in both the SAM Logon and the SAM Logoff */
+ make_id_info1(&ctr->auth.id1, workgroup, 0,
+ smb_userid, 0,
+ username, myhostname,
+ sess_key, lm_owf_user_pwd, nt_owf_user_pwd);
+}
+
+/****************************************************************************
+experimental nt login.
+****************************************************************************/
+BOOL do_nt_login(struct cli_state *cli, int t_idx, uint16 fnum,
+ uint8 sess_key[16], DOM_CRED *clnt_cred, DOM_CRED *rtn_cred,
+ NET_ID_INFO_CTR *ctr, char *dest_host, char *myhostname,
+ NET_USER_INFO_3 *user_info3)
+{
+ DOM_CRED sam_logon_rtn_cred;
+ DOM_CRED cred;
+ fstring dest_srv;
+ fstring my_host_name;
+
+ DEBUG(5,("do_nt_login: %d\n", __LINE__));
+
+ /*********************** SAM Logon **********************/
+
+ clnt_cred->timestamp.time = time(NULL);
+
+ memcpy(&cred, clnt_cred, sizeof(cred));
+
+ /* calculate sam logon credentials */
+ cred_create(sess_key, &(clnt_cred->challenge),
+ cred.timestamp,
+ &(cred.challenge));
+
+ strcpy(dest_srv, "\\\\");
+ strcat(dest_srv, dest_host);
+ strupper(dest_srv);
+
+ fstrcpy(my_host_name, myhostname);
+ strupper(my_host_name);
+
+ /* send client sam-logon challenge */
+ return do_net_sam_logon(cli, t_idx, fnum, sess_key, clnt_cred,
+ dest_srv, my_host_name,
+ &cred, &sam_logon_rtn_cred,
+ ctr->switch_value, ctr, 3, user_info3,
+ rtn_cred);
+}
+
+/****************************************************************************
+nt sam logoff
+****************************************************************************/
+BOOL do_nt_logoff(struct cli_state *cli, int t_idx, uint16 fnum,
+ uint8 sess_key[16], DOM_CRED *clnt_cred, DOM_CRED *rtn_cred,
+ NET_ID_INFO_CTR *ctr, char *dest_host, char *myhostname)
+{
+ DOM_CRED sam_logoff_rtn_cred;
+ DOM_CRED cred;
+ fstring dest_srv;
+ fstring my_host_name;
+
+ DEBUG(5,("do_nt_logoff: %d\n", __LINE__));
+
+ /*********************** SAM Logoff *********************/
+
+ clnt_cred->timestamp.time = time(NULL);
+
+ memcpy(&cred, clnt_cred, sizeof(cred));
+
+ /* calculate sam logoff credentials */
+ cred_create(sess_key, &(clnt_cred->challenge),
+ cred.timestamp,
+ &(cred.challenge));
+
+ strcpy(dest_srv, "\\\\");
+ strcat(dest_srv, dest_host);
+ strupper(dest_srv);
+
+ fstrcpy(my_host_name, myhostname);
+ strupper(my_host_name);
+
+ /* send client sam-logoff challenge; receive a sam-logoff challenge */
+ return do_net_sam_logoff(cli, t_idx, fnum, sess_key, clnt_cred,
+ dest_srv, my_host_name,
+ &cred, &sam_logoff_rtn_cred,
+ ctr->switch_value, ctr, 3,
+ rtn_cred);
+}
+
+#if 0
+ /* free memory used in all rpc transactions, above */
+ cli_shutdown(cli, t_idx);
+#endif
+
+/****************************************************************************
+experimental nt login.
+****************************************************************************/
+void do_nt_session_close(struct cli_state *cli, int t_idx, uint16 fnum)
+{
+ /******************** close the \PIPE\NETLOGON file **************/
+ if (fnum != 0xffff)
+ {
+ cli_close(cli, t_idx, fnum, 0);
+ }
+
+}
+
+
diff --git a/source3/rpc_client/cli_lsarpc.c b/source3/rpc_client/cli_lsarpc.c
new file mode 100644
index 0000000000..6570903e79
--- /dev/null
+++ b/source3/rpc_client/cli_lsarpc.c
@@ -0,0 +1,255 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-1997,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ * Copyright (C) Paul Ashton 1997.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#ifdef SYSLOG
+#undef SYSLOG
+#endif
+
+#include "includes.h"
+
+extern int DEBUGLEVEL;
+
+
+/****************************************************************************
+do a LSA Open Policy
+****************************************************************************/
+BOOL do_lsa_open_policy(struct cli_state *cli, int t_idx, uint16 fnum,
+ char *server_name, POLICY_HND *hnd)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ LSA_Q_OPEN_POL 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 LSA_OPENPOLICY */
+
+ DEBUG(4,("LSA Open Policy\n"));
+
+ /* store the parameters */
+ make_q_open_pol(&q_o, server_name, 0, 0, 0x1);
+
+ /* turn parameters into data stream */
+ lsa_io_q_open_pol("", &q_o, &buf, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, t_idx, fnum, LSA_OPENPOLICY, &buf, &rbuf))
+ {
+ LSA_R_OPEN_POL r_o;
+ BOOL p;
+
+ lsa_io_r_open_pol("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("LSA_OPENPOLICY: %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 LSA Query Info Policy
+****************************************************************************/
+BOOL do_lsa_query_info_pol(struct cli_state *cli, int t_idx, uint16 fnum,
+ POLICY_HND *hnd, uint16 info_class,
+ fstring domain_name, fstring domain_sid)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ LSA_Q_QUERY_INFO q_q;
+ BOOL valid_response = False;
+
+ if (hnd == NULL || domain_name == NULL || domain_sid == 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_QUERYINFOPOLICY */
+
+ DEBUG(4,("LSA Query Info Policy\n"));
+
+ /* store the parameters */
+ make_q_query(&q_q, hnd, info_class);
+
+ /* turn parameters into data stream */
+ lsa_io_q_query("", &q_q, &buf, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, t_idx, fnum, LSA_QUERYINFOPOLICY, &buf, &rbuf))
+ {
+ LSA_R_QUERY_INFO r_q;
+ BOOL p;
+
+ lsa_io_r_query("", &r_q, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_q.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("LSA_QUERYINFOPOLICY: %s\n", get_nt_error_msg(r_q.status)));
+ p = False;
+ }
+
+ if (p && r_q.info_class != q_q.info_class)
+ {
+ /* report different info classes */
+ DEBUG(0,("LSA_QUERYINFOPOLICY: error info_class (q,r) differ - (%x,%x)\n",
+ q_q.info_class, r_q.info_class));
+ p = False;
+ }
+
+ if (p)
+ {
+ /* ok, at last: we're happy. */
+ switch (r_q.info_class)
+ {
+ case 3:
+ {
+ char *dom_name = unistrn2(r_q.dom.id3.uni_domain_name.buffer,
+ r_q.dom.id3.uni_domain_name.uni_str_len);
+ char *dom_sid = dom_sid_to_string(&(r_q.dom.id3.dom_sid.sid));
+ fstrcpy(domain_name, dom_name);
+ pstrcpy(domain_sid , dom_sid);
+
+ valid_response = True;
+ break;
+ }
+ case 5:
+ {
+ char *dom_name = unistrn2(r_q.dom.id5.uni_domain_name.buffer,
+ r_q.dom.id5.uni_domain_name.uni_str_len);
+ char *dom_sid = dom_sid_to_string(&(r_q.dom.id5.dom_sid.sid));
+ fstrcpy(domain_name, dom_name);
+ pstrcpy(domain_sid , dom_sid);
+
+ valid_response = True;
+ break;
+ }
+ default:
+ {
+ DEBUG(3,("LSA_QUERYINFOPOLICY: unknown info class\n"));
+ domain_name[0] = 0;
+ domain_sid [0] = 0;
+
+ break;
+ }
+ }
+ DEBUG(3,("LSA_QUERYINFOPOLICY (level %x): domain:%s domain sid:%s\n",
+ r_q.info_class, domain_name, domain_sid));
+ }
+ }
+
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
+
+ return valid_response;
+}
+
+/****************************************************************************
+do a LSA Close
+****************************************************************************/
+BOOL do_lsa_close(struct cli_state *cli, int t_idx, uint16 fnum, POLICY_HND *hnd)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ LSA_Q_CLOSE q_c;
+ BOOL valid_close = False;
+
+ if (hnd == NULL) return False;
+
+ /* create and send a MSRPC command with api LSA_OPENPOLICY */
+
+ prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
+ prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True );
+
+ DEBUG(4,("LSA Close\n"));
+
+ /* store the parameters */
+ make_lsa_q_close(&q_c, hnd);
+
+ /* turn parameters into data stream */
+ lsa_io_q_close("", &q_c, &buf, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, t_idx, fnum, LSA_CLOSE, &buf, &rbuf))
+ {
+ LSA_R_CLOSE r_c;
+ BOOL p;
+
+ lsa_io_r_close("", &r_c, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_c.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("LSA_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,("LSA_CLOSE: non-zero handle returned\n"));
+ }
+ }
+ }
+
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
+
+ return valid_close;
+}
diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c
new file mode 100644
index 0000000000..aafde8d775
--- /dev/null
+++ b/source3/rpc_client/cli_netlogon.c
@@ -0,0 +1,461 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-1997,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ * Copyright (C) Paul Ashton 1997.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#ifdef SYSLOG
+#undef SYSLOG
+#endif
+
+#include "includes.h"
+
+extern int DEBUGLEVEL;
+extern pstring username;
+extern pstring workgroup;
+
+#define CLIENT_TIMEOUT (30*1000)
+
+
+/****************************************************************************
+do a LSA Logon Control2
+****************************************************************************/
+BOOL do_net_logon_ctrl2(struct cli_state *cli, int t_idx, uint16 fnum,
+ char *host_name, uint32 status_level)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ NET_Q_LOGON_CTRL2 q_l;
+ BOOL valid_ctrl2 = False;
+ fstring acct_name;
+
+ prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
+ prs_init(&rbuf, 0, 4, SAFETY_MARGIN, True );
+
+ if (host_name == NULL) return False;
+
+ strcpy(acct_name, "\\\\");
+ strcat(acct_name, host_name);
+
+ /* create and send a MSRPC command with api NET_LOGON_CTRL2 */
+
+ DEBUG(4,("LSA Logon Control2 from %s status level:%x\n",
+ host_name, status_level));
+
+ /* store the parameters */
+ make_q_logon_ctrl2(&q_l, acct_name, status_level);
+
+ /* turn parameters into data stream */
+ net_io_q_logon_ctrl2("", &q_l, &buf, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, t_idx, fnum, NET_LOGON_CTRL2, &buf, &rbuf))
+ {
+ NET_R_LOGON_CTRL2 r_l;
+ BOOL p;
+
+ net_io_r_logon_ctrl2("", &r_l, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_l.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("NET_R_LOGON_CTRL: %s\n", get_nt_error_msg(r_l.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ valid_ctrl2 = True;
+ }
+ }
+
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
+
+
+ return valid_ctrl2;
+}
+
+/****************************************************************************
+do a LSA Authenticate 2
+****************************************************************************/
+BOOL do_net_auth2(struct cli_state *cli, int t_idx, uint16 fnum,
+ char *logon_srv, char *acct_name, uint16 sec_chan, char *comp_name,
+ DOM_CHAL *clnt_chal, uint32 neg_flags, DOM_CHAL *srv_chal)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ NET_Q_AUTH_2 q_a;
+ BOOL valid_chal = False;
+
+ prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
+ prs_init(&rbuf, 0, 4, SAFETY_MARGIN, True );
+
+ if (srv_chal == NULL || clnt_chal == NULL) return False;
+
+ /* create and send a MSRPC command with api NET_AUTH2 */
+
+ DEBUG(4,("LSA Authenticate 2: srv:%s acct:%s sc:%x mc: %s chal %s neg: %lx\n",
+ logon_srv, acct_name, sec_chan, comp_name,
+ credstr(clnt_chal->data), neg_flags));
+
+ /* store the parameters */
+ make_q_auth_2(&q_a, logon_srv, acct_name, sec_chan, comp_name,
+ clnt_chal, neg_flags);
+
+ /* turn parameters into data stream */
+ net_io_q_auth_2("", &q_a, &buf, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, t_idx, fnum, NET_AUTH2, &buf, &rbuf))
+ {
+ NET_R_AUTH_2 r_a;
+ BOOL p;
+
+ net_io_r_auth_2("", &r_a, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_a.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("NET_AUTH2: %s\n", get_nt_error_msg(r_a.status)));
+ p = False;
+ }
+
+ if (p && r_a.srv_flgs.neg_flags != q_a.clnt_flgs.neg_flags)
+ {
+ /* report different neg_flags */
+ DEBUG(0,("NET_AUTH2: error neg_flags (q,r) differ - (%lx,%lx)\n",
+ q_a.clnt_flgs.neg_flags, r_a.srv_flgs.neg_flags));
+ p = False;
+ }
+
+ if (p)
+ {
+ /* ok, at last: we're happy. return the challenge */
+ memcpy(srv_chal, r_a.srv_chal.data, sizeof(srv_chal->data));
+ valid_chal = True;
+ }
+ }
+
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
+
+
+ return valid_chal;
+}
+
+/****************************************************************************
+do a LSA Request Challenge
+****************************************************************************/
+BOOL do_net_req_chal(struct cli_state *cli, int t_idx, uint16 fnum,
+ char *desthost, char *myhostname,
+ DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ NET_Q_REQ_CHAL q_c;
+ BOOL valid_chal = False;
+
+ prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
+ prs_init(&rbuf, 0, 4, SAFETY_MARGIN, True );
+
+ if (srv_chal == NULL || clnt_chal == NULL) return False;
+
+ /* create and send a MSRPC command with api NET_REQCHAL */
+
+ DEBUG(4,("LSA Request Challenge from %s to %s: %s\n",
+ desthost, myhostname, credstr(clnt_chal->data)));
+
+ /* store the parameters */
+ make_q_req_chal(&q_c, desthost, myhostname, clnt_chal);
+
+ /* turn parameters into data stream */
+ net_io_q_req_chal("", &q_c, &buf, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, t_idx, fnum, NET_REQCHAL, &buf, &rbuf))
+ {
+ NET_R_REQ_CHAL r_c;
+ BOOL p;
+
+ net_io_r_req_chal("", &r_c, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_c.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("NET_REQ_CHAL: %s\n", get_nt_error_msg(r_c.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ /* ok, at last: we're happy. return the challenge */
+ memcpy(srv_chal, r_c.srv_chal.data, sizeof(srv_chal->data));
+ valid_chal = True;
+ }
+ }
+
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
+
+
+ return valid_chal;
+}
+
+/***************************************************************************
+do a LSA Server Password Set
+****************************************************************************/
+BOOL do_net_srv_pwset(struct cli_state *cli, int t_idx, uint16 fnum,
+ uchar sess_key[16], DOM_CRED *sto_clnt_cred,
+ char *logon_srv, char *mach_acct, uint16 sec_chan_type, char *comp_name,
+ DOM_CRED *clnt_cred, DOM_CRED *srv_cred,
+ uint8 nt_owf_new_mach_pwd[16])
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ NET_Q_SRV_PWSET q_s;
+ BOOL valid_cred = False;
+
+ prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
+ prs_init(&rbuf, 0, 4, SAFETY_MARGIN, True );
+
+ if (srv_cred == NULL || clnt_cred == NULL) return False;
+
+ /* create and send a MSRPC command with api NET_SRV_PWSET */
+
+ DEBUG(4,("LSA Server Password Set: srv:%s acct:%s sc: %d mc: %s clnt %s %lx\n",
+ logon_srv, mach_acct, sec_chan_type, comp_name,
+ credstr(clnt_cred->challenge.data), clnt_cred->timestamp.time));
+
+ /* store the parameters */
+ make_q_srv_pwset(&q_s,
+ sess_key,
+ logon_srv, mach_acct, sec_chan_type, comp_name,
+ clnt_cred,
+ nt_owf_new_mach_pwd);
+
+ /* turn parameters into data stream */
+ net_io_q_srv_pwset("", &q_s, &buf, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, t_idx, fnum, NET_SRVPWSET, &buf, &rbuf))
+ {
+ NET_R_SRV_PWSET r_s;
+ BOOL p;
+
+ net_io_r_srv_pwset("", &r_s, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_s.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("NET_R_SRV_PWSET: %s\n", get_nt_error_msg(r_s.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ if (clnt_deal_with_creds(sess_key, sto_clnt_cred, &(r_s.srv_cred)))
+ {
+ DEBUG(5, ("do_net_srv_pwset: server credential check OK\n"));
+ /* ok, at last: we're happy. return the challenge */
+ memcpy(srv_cred, &(r_s.srv_cred), sizeof(r_s.srv_cred));
+ valid_cred = True;
+ }
+ else
+ {
+ DEBUG(5, ("do_net_srv_pwset: server credential check failed\n"));
+ }
+ }
+ }
+
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
+
+
+ return valid_cred;
+}
+
+/***************************************************************************
+do a LSA SAM Logon
+****************************************************************************/
+BOOL do_net_sam_logon(struct cli_state *cli, int t_idx, uint16 fnum,
+ uchar sess_key[8], DOM_CRED *sto_clnt_cred,
+ char *logon_srv, char *comp_name,
+ DOM_CRED *clnt_cred, DOM_CRED *rtn_cred,
+ uint16 logon_level, NET_ID_INFO_CTR *ctr, uint16 validation_level,
+ NET_USER_INFO_3 *user_info3,
+ DOM_CRED *srv_cred)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ NET_Q_SAM_LOGON q_s;
+ BOOL valid_cred = False;
+
+ prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
+ prs_init(&rbuf, 0, 4, SAFETY_MARGIN, True );
+
+ if (srv_cred == NULL || clnt_cred == NULL || rtn_cred == NULL || user_info3 == NULL) return False;
+
+ /* create and send a MSRPC command with api NET_SAMLOGON */
+
+ DEBUG(4,("LSA SAM Logon: srv:%s mc:%s clnt %s %lx rtn: %s %lx ll: %d\n",
+ logon_srv, comp_name,
+ credstr(clnt_cred->challenge.data), clnt_cred->timestamp.time,
+ credstr(rtn_cred->challenge.data), rtn_cred ->timestamp.time,
+ logon_level));
+
+ /* store the parameters */
+ make_sam_info(&(q_s.sam_id), logon_srv, comp_name,
+ clnt_cred, rtn_cred,
+ logon_level, ctr, validation_level);
+
+ /* turn parameters into data stream */
+ net_io_q_sam_logon("", &q_s, &buf, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, t_idx, fnum, NET_SAMLOGON, &buf, &rbuf))
+ {
+ NET_R_SAM_LOGON r_s;
+ BOOL p;
+
+ r_s.user = user_info3;
+
+ net_io_r_sam_logon("", &r_s, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_s.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("NET_SAMLOGON: %s\n", get_nt_error_msg(r_s.status)));
+ p = False;
+ }
+
+ if (p && r_s.switch_value != 3)
+ {
+ /* report different switch_value */
+ DEBUG(0,("NET_SAMLOGON: switch_value of 3 expected %x\n",
+ r_s.switch_value));
+ p = False;
+ }
+
+ if (p)
+ {
+ if (clnt_deal_with_creds(sess_key, sto_clnt_cred, &(r_s.srv_creds)))
+ {
+ DEBUG(5, ("do_net_sam_logon: server credential check OK\n"));
+ /* ok, at last: we're happy. return the challenge */
+ memcpy(srv_cred, &(r_s.srv_creds), sizeof(r_s.srv_creds));
+ valid_cred = True;
+ }
+ else
+ {
+ DEBUG(5, ("do_net_sam_logon: server credential check failed\n"));
+ }
+ }
+ }
+
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
+
+ return valid_cred;
+}
+
+/***************************************************************************
+do a LSA SAM Logoff
+****************************************************************************/
+BOOL do_net_sam_logoff(struct cli_state *cli, int t_idx, uint16 fnum,
+ uchar sess_key[8], DOM_CRED *sto_clnt_cred,
+ char *logon_srv, char *comp_name,
+ DOM_CRED *clnt_cred, DOM_CRED *rtn_cred,
+ uint16 logon_level, NET_ID_INFO_CTR *ctr, uint16 validation_level,
+ DOM_CRED *srv_cred)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ NET_Q_SAM_LOGOFF q_s;
+ BOOL valid_cred = False;
+
+ prs_init(&buf , 1024, 4, SAFETY_MARGIN, False);
+ prs_init(&rbuf, 0, 4, SAFETY_MARGIN, True );
+
+ if (srv_cred == NULL || clnt_cred == NULL || rtn_cred == NULL) return False;
+
+ /* create and send a MSRPC command with api NET_SAMLOGON */
+
+ DEBUG(4,("LSA SAM Logoff: srv:%s mc:%s clnt %s %lx rtn: %s %lx ll: %d\n",
+ logon_srv, comp_name,
+ credstr(clnt_cred->challenge.data), clnt_cred->timestamp.time,
+ credstr(rtn_cred->challenge.data), rtn_cred ->timestamp.time,
+ logon_level));
+
+ /* store the parameters */
+ make_sam_info(&(q_s.sam_id), logon_srv, comp_name,
+ clnt_cred, rtn_cred,
+ logon_level, ctr, validation_level);
+
+ /* turn parameters into data stream */
+ net_io_q_sam_logoff("", &q_s, &buf, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, t_idx, fnum, NET_SAMLOGOFF, &buf, &rbuf))
+ {
+ NET_R_SAM_LOGOFF r_s;
+ BOOL p;
+
+ net_io_r_sam_logoff("", &r_s, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_s.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("NET_SAMLOGOFF: %s\n", get_nt_error_msg(r_s.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ if (clnt_deal_with_creds(sess_key, sto_clnt_cred, &(r_s.srv_creds)))
+ {
+ DEBUG(5, ("do_net_sam_logoff: server credential check OK\n"));
+ /* ok, at last: we're happy. return the challenge */
+ memcpy(srv_cred, &(r_s.srv_creds), sizeof(r_s.srv_creds));
+ valid_cred = True;
+ }
+ else
+ {
+ DEBUG(5, ("do_net_sam_logoff: server credential check failed\n"));
+ }
+ }
+ }
+
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
+
+
+ return valid_cred;
+}
+
+
diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c
new file mode 100644
index 0000000000..625b774167
--- /dev/null
+++ b/source3/rpc_client/cli_pipe.c
@@ -0,0 +1,683 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-1998,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
+ * Copyright (C) Paul Ashton 1998.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#ifdef SYSLOG
+#undef SYSLOG
+#endif
+
+#include "includes.h"
+
+extern int DEBUGLEVEL;
+
+
+extern struct pipe_id_info pipe_names[];
+
+/********************************************************************
+ rpc pipe call id
+ ********************************************************************/
+uint32 get_rpc_call_id(void)
+{
+ static uint32 call_id = 1;
+ return ++call_id;
+}
+
+/*******************************************************************
+ uses SMBreadX to get rest of rpc data
+ ********************************************************************/
+static BOOL rpc_read(struct cli_state *cli, int t_idx, uint16 fnum,
+ prs_struct *rdata, uint32 data_to_read)
+{
+ uint32 data_offset = rdata->data->data_used;
+ int size = 512;
+ int num_read;
+ char *data = rdata->data->data;
+ uint32 err;
+ data += rdata->data->data_used;
+
+ if (data_offset + data_to_read > rdata->data->data_size)
+ {
+ mem_grow_data(&rdata->data, True, rdata->data->data_used + data_to_read);
+ DEBUG(5,("rpc_read: grow buffer to %d\n", rdata->data->data_used));
+ }
+
+ do /* read data using SMBreadX */
+ {
+ if (size > data_to_read) size = data_to_read;
+
+ if (data_offset + size > rdata->data->data_size)
+ {
+ mem_grow_data(&rdata->data, True, rdata->data->data_used + size);
+ DEBUG(5,("rpc_read: grow buffer to %d\n", rdata->data->data_used));
+ }
+
+ num_read = cli_readx(cli, t_idx, fnum, data, data_offset, size);
+
+ DEBUG(5,("rpc_read: read offset: %d read: %d to read: %d\n",
+ data_offset, num_read, data_to_read));
+
+ data_to_read -= num_read;
+ data_offset += num_read;
+ data += num_read;
+
+ if (cli_error(cli, NULL, &err)) return False;
+
+ } while (num_read > 0 && data_to_read > 0); /* && err == (0x80000000 | STATUS_BUFFER_OVERFLOW)); */
+
+ mem_realloc_data(rdata->data, rdata->data->data_used);
+ rdata->data->offset.end = rdata->data->data_used;
+
+ DEBUG(5,("rpc_read: data supposedly left to read:0x%x\n", data_to_read));
+
+ return data_to_read == 0;
+}
+
+/****************************************************************************
+ checks the header
+ ****************************************************************************/
+static BOOL rpc_check_hdr(prs_struct *rdata, uint8 *pkt_type,
+ BOOL *first, BOOL *last, uint32 *len)
+{
+ RPC_HDR rhdr;
+
+ smb_io_rpc_hdr ("rpc_hdr ", &rhdr , rdata, 0);
+
+ if (!rdata->offset || rdata->offset != 0x10)
+ {
+ DEBUG(5,("cli_pipe: error in rpc header\n"));
+ return False;
+ }
+
+ (*first ) = IS_BITS_SET_ALL(rhdr.flags, RPC_FLG_FIRST);
+ (*last ) = IS_BITS_SET_ALL(rhdr.flags, RPC_FLG_LAST );
+ (*len ) = rhdr.frag_len - rdata->data->data_used;
+ (*pkt_type) = rhdr.pkt_type;
+
+ return True;
+}
+
+/****************************************************************************
+ send data on an rpc pipe, which *must* be in one fragment.
+ receive response data from an rpc pipe, which may be large...
+
+ read the first fragment: unfortunately have to use SMBtrans for the first
+ bit, then SMBreadX for subsequent bits.
+
+ if first fragment received also wasn't the last fragment, continue
+ getting fragments until we _do_ receive the last fragment.
+
+ [note: from a data abstraction viewpoint, this function is marginally
+ complicated by the return side of cli_api_pipe getting in the way
+ (i.e, the SMB header stuff). the proper way to do this is to split
+ cli_api_pipe down into receive / transmit. oh, and split cli_readx
+ down. in other words, state-based (kernel) techniques...]
+
+ ****************************************************************************/
+BOOL rpc_api_pipe(struct cli_state *cli, int t_idx,
+ uint16 cmd, uint16 fnum,
+ prs_struct *param , prs_struct *data,
+ prs_struct *rparam, prs_struct *rdata)
+{
+ uint32 len;
+
+ uint16 setup[2]; /* only need 2 uint16 setup parameters */
+ uint32 err;
+ uint8 pkt_type = 0xff;
+ BOOL first = True;
+ BOOL last = True;
+
+ /* prepare return data and params */
+
+ /* create setup parameters. */
+ setup[0] = cmd;
+ setup[1] = fnum; /* pipe file handle. got this from an SMBcreateX. */
+
+ /* send the data: receive a response. */
+ if (!cli_api_pipe(cli, t_idx, "\\PIPE\\\0\0\0", 8,
+
+ param != NULL ? param->data->data_used : 0,
+ data != NULL ? data ->data->data_used : 0,
+ 2,
+
+ 0,
+ data != NULL ? 1024 : 0 ,
+
+ param != NULL ? param->data->data : NULL,
+ data != NULL ? data ->data->data : NULL,
+ setup,
+
+ rparam != NULL ? rparam->data : NULL,
+ rdata != NULL ? rdata ->data : NULL))
+ {
+ DEBUG(5, ("cli_pipe: return critical error\n"));
+ return False;
+ }
+
+ if (cli_error(cli, NULL, &err)) return False;
+
+ if (rdata->data->data == NULL) return False;
+
+ /**** parse the header: check it's a response record */
+
+ rdata->data->offset.start = 0;
+ rdata->data->offset.end = rdata->data->data_used;
+ rdata->offset = 0;
+
+ if (!rpc_check_hdr(rdata, &pkt_type, &first, &last, &len)) return False;
+
+ if (pkt_type == RPC_RESPONSE)
+ {
+ RPC_HDR_RR rhdr_rr;
+ smb_io_rpc_hdr_rr("rpc_hdr_rr", &rhdr_rr, rdata, 0);
+ }
+
+ if (first && last)
+ {
+ DEBUG(6,("rpc_api_pipe: fragment first and last both set\n"));
+ return True;
+ }
+
+ /* check if data to be sent back was too large for one SMB. */
+ /* err status is only informational: the _real_ check is on the length */
+ if (len < rdata->data->data_used) /* || err == (0x80000000 | STATUS_BUFFER_OVERFLOW)) */
+ {
+ if (!rpc_read(cli, t_idx, fnum, rdata, len)) return False;
+ }
+
+ /* only one rpc fragment, and it has been read */
+ if (first && last) return True;
+
+ while (!last) /* read more fragments until we get the last one */
+ {
+ RPC_HDR rhdr;
+ RPC_HDR_RR rhdr_rr;
+ int num_read;
+ prs_struct hps;
+
+ prs_init(&hps, 0x18, 4, 0, True);
+
+ num_read = cli_readx(cli, t_idx, fnum, hps.data->data, 0, 0x18);
+ DEBUG(5,("rpc_api_pipe: read header (size:%d)\n", num_read));
+
+ if (num_read != 0x18) return False;
+
+ smb_io_rpc_hdr ("rpc_hdr ", &rhdr , &hps, 0);
+ smb_io_rpc_hdr_rr("rpc_hdr_rr", &rhdr_rr, &hps, 0);
+
+ prs_mem_free(&hps);
+
+ if (cli_error(cli, NULL, &err)) return False;
+
+ first = IS_BITS_SET_ALL(rhdr.flags, RPC_FLG_FIRST);
+ last = IS_BITS_SET_ALL(rhdr.flags, RPC_FLG_LAST );
+
+ if (first)
+ {
+ DEBUG(4,("rpc_api_pipe: wierd rpc header received\n"));
+ return False;
+ }
+
+ len = rhdr.frag_len - hps.offset;
+ if (!rpc_read(cli, t_idx, fnum, rdata, len)) return False;
+ }
+
+ return True;
+}
+
+/*******************************************************************
+ creates a DCE/RPC bind request
+
+ - initialises the parse structure.
+ - dynamically allocates the header data structure
+ - caller is expected to free the header data structure once used.
+
+ ********************************************************************/
+static BOOL create_rpc_bind_req(prs_struct *rhdr,
+ prs_struct *rhdr_rb,
+ prs_struct *auth_req,
+ RPC_IFACE *abstract, RPC_IFACE *transfer,
+ char *my_name, char *domain)
+{
+ RPC_HDR_RB hdr_rb;
+ RPC_HDR hdr;
+ RPC_AUTH_NTLMSSP_REQ ntlmssp_req;
+
+ /* create the bind request RPC_HDR_RB */
+ make_rpc_hdr_rb(&hdr_rb,
+ 0x1630, 0x1630, 0x0,
+ 0x1, 0x0, 0x1,
+ abstract, transfer);
+
+ /* stream the bind request data */
+ smb_io_rpc_hdr_rb("", &hdr_rb, rhdr_rb, 0);
+ mem_realloc_data(rhdr_rb->data, rhdr_rb->offset);
+
+ if (auth_req != NULL)
+ {
+ make_rpc_auth_ntlmssp_req(&ntlmssp_req,
+ "NTLMSSP", 0x1,
+ 0x0000b2b3,
+ my_name, domain);
+ smb_io_rpc_auth_ntlmssp_req("", &ntlmssp_req, auth_req, 0);
+ mem_realloc_data(auth_req->data, auth_req->offset);
+ }
+
+ /* create the request RPC_HDR */
+ make_rpc_hdr(&hdr, RPC_BIND, 0x0, get_rpc_call_id(),
+ rhdr_rb->offset,
+ auth_req != NULL ? auth_req->offset : 0);
+
+ smb_io_rpc_hdr("hdr" , &hdr , rhdr, 0);
+ mem_realloc_data(rhdr->data, rhdr->offset);
+
+ if (rhdr->data == NULL || rhdr_rb->data == NULL) return False;
+
+ /***/
+ /*** link rpc header, bind acknowledgment and authentication responses ***/
+ /***/
+
+ rhdr->data->offset.start = 0;
+ rhdr->data->offset.end = rhdr->offset;
+ rhdr->data->next = rhdr_rb->data;
+
+ if (auth_req != NULL)
+ {
+ rhdr_rb->data->offset.start = rhdr->offset;
+ rhdr_rb->data->offset.end = rhdr->offset + rhdr_rb->offset;
+ rhdr_rb->data->next = auth_req->data;
+
+ auth_req->data->offset.start = rhdr->offset + rhdr_rb->offset;
+ auth_req->data->offset.end = rhdr->offset + auth_req->offset + rhdr_rb->offset;
+ auth_req->data->next = NULL;
+ }
+ else
+ {
+ rhdr_rb->data->offset.start = rhdr->offset;
+ rhdr_rb->data->offset.end = rhdr->offset + rhdr_rb->offset;
+ rhdr_rb->data->next = NULL;
+ }
+
+ return True;
+}
+
+
+/*******************************************************************
+ creates a DCE/RPC bind request
+
+ - initialises the parse structure.
+ - dynamically allocates the header data structure
+ - caller is expected to free the header data structure once used.
+
+ ********************************************************************/
+static BOOL create_rpc_request(prs_struct *rhdr, uint8 op_num, int data_len)
+{
+ RPC_HDR_RR hdr_rr;
+ RPC_HDR hdr;
+
+ DEBUG(5,("create_rpc_request: opnum: 0x%x data_len: 0x%x\n",
+ op_num, data_len));
+
+ /* create the rpc header RPC_HDR */
+ make_rpc_hdr (&hdr , RPC_REQUEST, RPC_FLG_FIRST | RPC_FLG_LAST,
+ get_rpc_call_id(), data_len + 0x18, 0);
+
+ /* create the rpc request RPC_HDR_RR */
+ make_rpc_hdr_rr(&hdr_rr, data_len, op_num);
+
+ /* stream-time... */
+ smb_io_rpc_hdr ("hdr" , &hdr , rhdr, 0);
+ smb_io_rpc_hdr_rr("hdr_rr", &hdr_rr, rhdr, 0);
+
+ if (rhdr->data == NULL || rhdr->offset != 0x18) return False;
+
+ rhdr->data->offset.start = 0;
+ rhdr->data->offset.end = rhdr->offset;
+
+ return True;
+}
+
+
+/****************************************************************************
+ send a request on an rpc pipe.
+ ****************************************************************************/
+BOOL rpc_api_pipe_req(struct cli_state *cli, int t_idx, uint16 fnum,
+ uint8 op_num,
+ prs_struct *data, prs_struct *rdata)
+{
+ /* fudge this, at the moment: create the header; memcpy the data. oops. */
+ prs_struct rparam;
+ prs_struct hdr;
+ int data_len;
+ BOOL ret;
+
+ data_len = data->offset + 0x18;
+ data->data->offset.end = data->offset;
+
+ prs_init(&hdr , data_len, 4, SAFETY_MARGIN, False);
+ prs_init(&rparam, 0 , 4, 0 , True );
+
+ create_rpc_request(&hdr, op_num, data_len);
+
+ mem_realloc_data(hdr.data, data_len);
+ hdr.data->offset.end = data_len;
+ mem_buf_copy(mem_data(&(hdr.data), 0x18), data->data, 0, data->offset);
+
+ ret = rpc_api_pipe(cli, t_idx, 0x0026, fnum, NULL, &hdr, &rparam, rdata);
+
+ prs_mem_free(&rparam);
+ prs_mem_free(&hdr);
+
+ return ret;
+}
+
+
+/****************************************************************************
+do an rpc bind
+****************************************************************************/
+BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, int t_idx,
+ char *pipe_name, uint16 fnum, uint16 device_state)
+{
+ prs_struct param;
+ prs_struct rdata;
+ prs_struct rparam;
+ BOOL state_set = False;
+ uint16 setup[2]; /* only need 2 uint16 setup parameters */
+
+ if (pipe_name == NULL) return False;
+
+ prs_init(&param , 2, 4, 0 , False);
+ prs_init(&rdata , 0, 4, SAFETY_MARGIN, True );
+ prs_init(&rparam, 0, 4, SAFETY_MARGIN, True );
+
+ param.data->offset.start = 0;
+ param.data->offset.end = 2;
+
+ DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
+ fnum, pipe_name, device_state));
+
+ /* create data parameters: device state */
+ SSVAL(param.data->data, 0, device_state);
+
+ /* create setup parameters. */
+ setup[0] = 0x0001;
+ setup[1] = fnum; /* pipe file handle. got this from an SMBcreateX. */
+
+ /* send the data on \PIPE\ */
+ if (cli_api_pipe(cli, t_idx, "\\PIPE\\\0\0\0", 8,
+
+ 2, 0, 2,
+
+ 0, 1024,
+
+ param.data->data, NULL, setup,
+
+ rparam.data, rdata.data))
+ {
+ DEBUG(5, ("Set Handle state: return OK\n"));
+ state_set = True;
+ }
+
+ prs_mem_free(&param );
+ prs_mem_free(&rparam);
+ prs_mem_free(&rdata );
+
+ return state_set;
+}
+
+/****************************************************************************
+ check the rpc bind acknowledge response
+****************************************************************************/
+static BOOL valid_pipe_name(char *pipe_name,
+ RPC_IFACE *abstract, RPC_IFACE *transfer)
+{
+ int pipe_idx = 0;
+
+ while (pipe_names[pipe_idx].client_pipe != NULL)
+ {
+ if (strcmp(pipe_name, pipe_names[pipe_idx].client_pipe ) == 0)
+ {
+ DEBUG(5,("Bind Abstract Syntax: "));
+ dump_data(5, (uchar*)&(pipe_names[pipe_idx].abstr_syntax), sizeof(pipe_names[pipe_idx].abstr_syntax));
+ DEBUG(5,("Bind Transfer Syntax: "));
+ dump_data(5, (uchar*)&(pipe_names[pipe_idx].trans_syntax), sizeof(pipe_names[pipe_idx].trans_syntax));
+
+ /* copy the required syntaxes out so we can do the right bind */
+ memcpy(transfer, &(pipe_names[pipe_idx].trans_syntax), sizeof(pipe_names[pipe_idx].trans_syntax));
+ memcpy(abstract, &(pipe_names[pipe_idx].abstr_syntax), sizeof(pipe_names[pipe_idx].abstr_syntax));
+
+ return True;
+ }
+ pipe_idx++;
+ };
+
+ DEBUG(5,("Bind RPC Pipe[%s] unsupported\n", pipe_name));
+ return False;
+}
+
+/****************************************************************************
+ check the rpc bind acknowledge response
+****************************************************************************/
+static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, char *pipe_name, RPC_IFACE *transfer)
+{
+ int i = 0;
+
+ while ((pipe_names[i].client_pipe != NULL))
+ {
+ DEBUG(6,("bind_rpc_pipe: searching pipe name: client:%s server:%s\n",
+ pipe_names[i].client_pipe , pipe_names[i].server_pipe ));
+
+ if ((strcmp(pipe_name, pipe_names[i].client_pipe ) == 0))
+ {
+ if (strcmp(hdr_ba->addr.str, pipe_names[i].server_pipe ) == 0)
+ {
+ DEBUG(5,("bind_rpc_pipe: server pipe_name found: %s\n",
+ pipe_names[i].server_pipe ));
+ break;
+ }
+ else
+ {
+ DEBUG(2,("bind_rpc_pipe: pipe_name %s != expected pipe %s\n",
+ pipe_names[i].server_pipe , hdr_ba->addr.str));
+ return False;
+ }
+ }
+ else
+ {
+ i++;
+ }
+ }
+
+ if (pipe_names[i].server_pipe == NULL)
+ {
+ DEBUG(2,("bind_rpc_pipe: pipe name %s unsupported\n", hdr_ba->addr.str));
+ return False;
+ }
+
+ /* check the transfer syntax */
+ if (!((hdr_ba->transfer.version == transfer->version) &&
+ (memcmp(hdr_ba->transfer.data, transfer->data,
+ sizeof(transfer->version)) ==0)))
+ {
+ DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
+ return False;
+ }
+
+ /* lkclXXXX only accept one result: check the result(s) */
+ if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0)
+ {
+ DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
+ hdr_ba->res.num_results,
+ hdr_ba->res.reason));
+ }
+
+ DEBUG(5,("bind_rpc_pipe: accepted!\n"));
+ return True;
+}
+
+/****************************************************************************
+do an rpc bind
+****************************************************************************/
+BOOL rpc_pipe_bind(struct cli_state *cli, int t_idx, char *pipe_name, uint16 fnum,
+ RPC_IFACE *abstract, RPC_IFACE *transfer, BOOL ntlmssp_auth,
+ char *my_name, char *domain)
+{
+ prs_struct hdr;
+ prs_struct hdr_rb;
+ prs_struct auth_req;
+ prs_struct data;
+ prs_struct rdata;
+ prs_struct rparam;
+
+ BOOL valid_ack = False;
+
+ if (pipe_name == NULL || abstract == NULL || transfer == NULL) return False;
+
+ DEBUG(5,("Bind RPC Pipe[%x]: %s\n", fnum, pipe_name));
+
+ if (!valid_pipe_name(pipe_name, abstract, transfer)) return False;
+
+ prs_init(&hdr , 0x10 , 4, 0x0 , False);
+ prs_init(&hdr_rb , 1024 , 4, SAFETY_MARGIN, False);
+ prs_init(&auth_req, ntlmssp_auth ? 1024 : 0, 4, SAFETY_MARGIN, False);
+
+ prs_init(&rdata , 0 , 4, SAFETY_MARGIN, True );
+ prs_init(&rparam, 0 , 4, SAFETY_MARGIN, True );
+
+ create_rpc_bind_req(&hdr, &hdr_rb, ntlmssp_auth ? &auth_req : NULL,
+ abstract, transfer,
+ my_name, domain);
+
+ /* this is a hack due to limitations in rpc_api_pipe */
+ prs_init(&data, mem_buf_len(hdr.data), 4, 0x0, False);
+ mem_buf_copy(data.data->data, hdr.data, 0, mem_buf_len(hdr.data));
+
+ /* send data on \PIPE\. receive a response */
+ if (rpc_api_pipe(cli, t_idx, 0x0026, fnum, NULL, &data, &rparam, &rdata))
+ {
+ RPC_HDR_BA hdr_ba;
+
+ DEBUG(5, ("rpc_api_pipe: return OK\n"));
+
+ smb_io_rpc_hdr_ba("", &hdr_ba, &rdata, 0);
+
+ if (rdata.offset != 0) valid_ack = check_bind_response(&hdr_ba, pipe_name, transfer);
+ }
+
+ prs_mem_free(&data );
+ prs_mem_free(&hdr );
+ prs_mem_free(&hdr_rb );
+ prs_mem_free(&auth_req);
+ prs_mem_free(&rdata );
+ prs_mem_free(&rparam );
+
+ return valid_ack;
+}
+
+/****************************************************************************
+ open a session
+ ****************************************************************************/
+BOOL do_session_open(struct cli_state *cli, int t_idx,
+ char *pipe_name, uint16 *fnum)
+{
+ RPC_IFACE abstract;
+ RPC_IFACE transfer;
+
+
+ /******************* open the pipe *****************/
+ if (((*fnum) = cli_open(cli, t_idx, pipe_name, O_CREAT|O_RDONLY, DENY_NONE,
+ NULL, NULL, NULL)) == 0xffff)
+ {
+ DEBUG(1,("do_session_open: cli_open failed\n"));
+ return False;
+ }
+
+ /**************** Set Named Pipe State ***************/
+ if (!rpc_pipe_set_hnd_state(cli, t_idx, pipe_name, (*fnum), 0x4300))
+ {
+ DEBUG(1,("do_session_open: pipe hnd state failed\n"));
+ return False;
+ }
+
+ /******************* bind request on pipe *****************/
+ if (!rpc_pipe_bind(cli, t_idx, pipe_name, (*fnum),
+ &abstract, &transfer,
+ False, NULL, NULL))
+ {
+ DEBUG(1,("do_session_open: rpc bind failed\n"));
+ return False;
+ }
+
+ return True;
+}
+
+
+/****************************************************************************
+ open an encrypted session
+ ****************************************************************************/
+BOOL do_ntlm_session_open(struct cli_state *cli, int t_idx,
+ char *pipe_name, uint16 *fnum,
+ char *my_name, char *domain)
+{
+ RPC_IFACE abstract;
+ RPC_IFACE transfer;
+
+ /******************* open the pipe *****************/
+ if (((*fnum) = cli_open(cli, t_idx, pipe_name, O_CREAT|O_RDONLY, DENY_NONE,
+ NULL, NULL, NULL)) == 0xffff)
+ {
+ DEBUG(1,("do_ntlm_session_open: cli_open failed\n"));
+ return False;
+ }
+
+ /**************** Set Named Pipe State ***************/
+ if (!rpc_pipe_set_hnd_state(cli, t_idx, pipe_name, (*fnum), 0x4300))
+ {
+ DEBUG(1,("do_ntlm_session_open: pipe hnd state failed\n"));
+ return False;
+ }
+
+ /******************* bind request on pipe *****************/
+ if (!rpc_pipe_bind(cli, t_idx, pipe_name, (*fnum),
+ &abstract, &transfer,
+ True, my_name, domain))
+ {
+ DEBUG(1,("do_ntlm_session_open: rpc bind failed\n"));
+ return False;
+ }
+
+ return True;
+}
+
+
+/****************************************************************************
+close the session
+****************************************************************************/
+void do_session_close(struct cli_state *cli, int t_idx, uint16 fnum)
+{
+ if (fnum != 0xffff)
+ {
+ cli_close(cli, t_idx, fnum, 0);
+ }
+}
+
diff --git a/source3/rpc_client/cli_samr.c b/source3/rpc_client/cli_samr.c
new file mode 100644
index 0000000000..7a04d8ec35
--- /dev/null
+++ b/source3/rpc_client/cli_samr.c
@@ -0,0 +1,695 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ NT Domain Authentication SMB / MSRPC client
+ Copyright (C) Andrew Tridgell 1994-1997
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1997
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+
+#ifdef SYSLOG
+#undef SYSLOG
+#endif
+
+#include "includes.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+
+
+
+/****************************************************************************
+do a SAMR query user groups
+****************************************************************************/
+BOOL get_samr_query_usergroups(struct cli_state *cli, int t_idx, uint16 fnum,
+ 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, t_idx, fnum,
+ pol_open_domain,
+ 0x02011b, user_rid,
+ &pol_open_user))
+ {
+ return False;
+ }
+
+ /* send user groups query */
+ if (!do_samr_query_usergroups(cli, t_idx, fnum,
+ &pol_open_user,
+ num_groups, gid))
+ {
+ DEBUG(5,("do_samr_query_usergroups: error in query user groups\n"));
+ }
+
+ return do_samr_close(cli, t_idx, fnum, &pol_open_user);
+}
+
+/****************************************************************************
+do a SAMR query user info
+****************************************************************************/
+BOOL get_samr_query_userinfo(struct cli_state *cli, int t_idx, uint16 fnum,
+ 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;
+
+ bzero(usr, sizeof(*usr));
+
+ /* send open domain (on user sid) */
+ if (!do_samr_open_user(cli, t_idx, fnum,
+ pol_open_domain,
+ 0x02011b, user_rid,
+ &pol_open_user))
+ {
+ return False;
+ }
+
+ /* send user info query */
+ if (!do_samr_query_userinfo(cli, t_idx, fnum,
+ &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, t_idx, fnum, &pol_open_user);
+}
+
+/****************************************************************************
+do a SAMR unknown 0x8 command
+****************************************************************************/
+BOOL do_samr_unknown_8(struct cli_state *cli, int t_idx, uint16 fnum,
+ POLICY_HND *domain_pol, uint16 switch_value)
+{
+ prs_struct data;
+ prs_struct rdata;
+
+ SAMR_Q_UNKNOWN_8 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 || fnum == 0xffff) return False;
+
+ /* store the parameters */
+ make_samr_q_unknown_8(&q_e, domain_pol, switch_value);
+
+ /* turn parameters into data stream */
+ samr_io_q_unknown_8("", &q_e, &data, 0);
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, t_idx, fnum, SAMR_UNKNOWN_8, &data, &rdata))
+ {
+#if 0
+
+ SAMR_R_UNKNOWN_8 r_e;
+ BOOL p;
+
+ samr_io_r_unknown_8("", &r_e, &rdata, 0);
+
+ p = rdata.offset != 0;
+ if (p && r_e.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("SAMR_R_UNKNOWN_8: %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, int t_idx, uint16 fnum,
+ POLICY_HND *pol, uint16 num_entries, uint16 unk_0,
+ uint16 acb_mask, uint16 unk_1, uint32 size,
+ struct acct_info sam[MAX_SAM_ENTRIES],
+ 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 || sam == NULL || num_sam_users == NULL || fnum == 0xffff) 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, t_idx, fnum, 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));
+ }
+ 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
+ {
+ bzero(sam[i].acct_name, 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, int t_idx, uint16 fnum,
+ 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 || fnum == 0xffff) 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, t_idx, fnum, 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, int t_idx, uint16 fnum,
+ 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 || fnum == 0xffff) 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, t_idx, fnum, 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, int t_idx, uint16 fnum,
+ POLICY_HND *connect_pol, uint32 rid, char *sid,
+ POLICY_HND *domain_pol)
+{
+ 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 );
+
+ DEBUG(4,("SAMR Open Domain. SID:%s RID:%x\n", sid, rid));
+
+ if (connect_pol == NULL || sid == NULL || domain_pol == NULL || fnum == 0xffff) 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, t_idx, fnum, 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, int t_idx, uint16 fnum,
+ 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 ||
+ fnum == 0xffff) 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, t_idx, fnum, 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, int t_idx, uint16 fnum,
+ 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|| fnum == 0xffff) 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, t_idx, fnum, 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, int t_idx, uint16 fnum,
+ 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|| fnum == 0xffff) 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, t_idx, fnum, 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, int t_idx, uint16 fnum, 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, t_idx, fnum, 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;
+}
+
diff --git a/source3/rpc_client/cli_srvsvc.c b/source3/rpc_client/cli_srvsvc.c
new file mode 100644
index 0000000000..dcedeb3a54
--- /dev/null
+++ b/source3/rpc_client/cli_srvsvc.c
@@ -0,0 +1,411 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-1997,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ * Copyright (C) Paul Ashton 1997.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#ifdef SYSLOG
+#undef SYSLOG
+#endif
+
+#include "includes.h"
+
+extern int DEBUGLEVEL;
+
+/****************************************************************************
+do a server net conn enum
+****************************************************************************/
+BOOL do_srv_net_srv_conn_enum(struct cli_state *cli, int t_idx, uint16 fnum,
+ 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, t_idx, fnum, 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, int t_idx, uint16 fnum,
+ 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, t_idx, fnum, 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, int t_idx, uint16 fnum,
+ 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, t_idx, fnum, 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, int t_idx, uint16 fnum,
+ 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, t_idx, fnum, 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, int t_idx, uint16 fnum,
+ 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, t_idx, fnum, 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;
+}
+
diff --git a/source3/rpc_client/cli_wkssvc.c b/source3/rpc_client/cli_wkssvc.c
new file mode 100644
index 0000000000..f5a4c203e0
--- /dev/null
+++ b/source3/rpc_client/cli_wkssvc.c
@@ -0,0 +1,90 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-1997,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ * Copyright (C) Paul Ashton 1997.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#ifdef SYSLOG
+#undef SYSLOG
+#endif
+
+#include "includes.h"
+
+extern int DEBUGLEVEL;
+
+/****************************************************************************
+do a WKS Open Policy
+****************************************************************************/
+BOOL do_wks_query_info(struct cli_state *cli, int t_idx, uint16 fnum,
+ 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, t_idx, fnum, 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;
+}
+
diff --git a/source3/rpc_client/ntclienttrust.c b/source3/rpc_client/ntclienttrust.c
new file mode 100644
index 0000000000..38cbedae78
--- /dev/null
+++ b/source3/rpc_client/ntclienttrust.c
@@ -0,0 +1,167 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ NT Domain Authentication SMB / MSRPC client
+ Copyright (C) Andrew Tridgell 1994-1997
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1997
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef SYSLOG
+#undef SYSLOG
+#endif
+
+#include "includes.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+
+
+/************************************************************************
+ check workstation trust account status
+ ************************************************************************/
+BOOL trust_account_check(struct in_addr dest_ip, char *dest_host,
+ char *myhostname, char *domain, fstring mach_acct,
+ fstring new_mach_pwd)
+{
+ pstring tmp;
+ fstring mach_pwd;
+ struct cli_state cli_trust;
+ uchar lm_owf_mach_pwd[16];
+ uchar nt_owf_mach_pwd[16];
+ uchar lm_sess_pwd[24];
+ uchar nt_sess_pwd[24];
+
+ BOOL right_error_code = False;
+ uint8 err_cls;
+ uint32 err_num;
+
+ char *start_mach_pwd;
+ char *change_mach_pwd;
+
+ /* initial machine password */
+ fstrcpy(mach_pwd, myhostname);
+ strlower(mach_pwd);
+
+ sprintf(tmp, "Enter Workstation Trust Account password for [%s].\nDefault is [%s].\nPassword:",
+ mach_acct, mach_pwd);
+
+ start_mach_pwd = (char*)getpass(tmp);
+
+ if (start_mach_pwd[0] != 0)
+ {
+ fstrcpy(mach_pwd, start_mach_pwd);
+ }
+
+ sprintf(tmp, "Enter new Workstation Trust Account password for [%s]\nPress Return to leave at old value.\nNew Password:",
+ mach_acct);
+
+ change_mach_pwd = (char*)getpass(tmp);
+
+ if (change_mach_pwd[0] != 0)
+ {
+ fstrcpy(new_mach_pwd, change_mach_pwd);
+ }
+ else
+ {
+ DEBUG(1,("trust_account_check: password change not requested\n"));
+ change_mach_pwd[0] = 0;
+ }
+
+ DEBUG(1,("initialise cli_trust connection\n"));
+
+ if (!cli_initialise(&cli_trust))
+ {
+ DEBUG(1,("cli_initialise failed for cli_trust\n"));
+ return False;
+ }
+
+ DEBUG(1,("server connect for cli_trust\n"));
+
+ if (!server_connect_init(&cli_trust, myhostname, dest_ip, dest_host))
+ {
+ cli_error(&cli_trust, &err_cls, &err_num);
+ DEBUG(1,("server_connect_init failed (%s)\n", cli_errstr(&cli_trust)));
+
+ cli_shutdown(&cli_trust);
+ return False;
+ }
+
+ DEBUG(1,("server connect cli_trust succeeded\n"));
+
+ nt_lm_owf_gen(mach_pwd, nt_owf_mach_pwd, lm_owf_mach_pwd);
+
+ DEBUG(5,("generating nt owf from initial machine pwd: %s\n", mach_pwd));
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("client cryptkey: "));
+ dump_data(100, cli_trust.cryptkey, sizeof(cli_trust.cryptkey));
+#endif
+
+ SMBencrypt(nt_owf_mach_pwd, cli_trust.cryptkey, nt_sess_pwd);
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("nt_owf_mach_pwd: "));
+ dump_data(100, nt_owf_mach_pwd, sizeof(lm_owf_mach_pwd));
+ DEBUG(100,("nt_sess_pwd: "));
+ dump_data(100, nt_sess_pwd, sizeof(nt_sess_pwd));
+#endif
+
+ SMBencrypt(lm_owf_mach_pwd, cli_trust.cryptkey, lm_sess_pwd);
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("lm_owf_mach_pwd: "));
+ dump_data(100, lm_owf_mach_pwd, sizeof(lm_owf_mach_pwd));
+ DEBUG(100,("lm_sess_pwd: "));
+ dump_data(100, lm_sess_pwd, sizeof(lm_sess_pwd));
+#endif
+
+ right_error_code = False;
+
+ if (cli_session_setup(&cli_trust, mach_acct,
+ nt_owf_mach_pwd, sizeof(nt_owf_mach_pwd),
+ nt_owf_mach_pwd, sizeof(nt_owf_mach_pwd), domain))
+ {
+ DEBUG(0,("cli_session_setup: NO ERROR! AAAGH! BUG IN SERVER DETECTED!!!\n"));
+ cli_shutdown(&cli_trust);
+
+ return False;
+ }
+
+ cli_error(&cli_trust, &err_cls, &err_num);
+
+ if (err_num == (0xC0000000 | NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT))
+ {
+ DEBUG(1,("cli_send_tconX: valid workstation trust account exists\n"));
+ right_error_code = True;
+ }
+
+ if (err_num == (0xC0000000 | NT_STATUS_NO_SUCH_USER))
+ {
+ DEBUG(1,("cli_send_tconX: workstation trust account does not exist\n"));
+ right_error_code = False;
+ }
+
+ if (!right_error_code)
+ {
+ DEBUG(1,("server_validate failed (%s)\n", cli_errstr(&cli_trust)));
+ }
+
+ cli_shutdown(&cli_trust);
+ return right_error_code;
+}
+
+
diff --git a/source3/rpc_parse/parse_lsa.c b/source3/rpc_parse/parse_lsa.c
new file mode 100644
index 0000000000..6eb42fc749
--- /dev/null
+++ b/source3/rpc_parse/parse_lsa.c
@@ -0,0 +1,567 @@
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-1997,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ * Copyright (C) Paul Ashton 1997.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+
+
+/*******************************************************************
+creates a LSA_TRANS_NAME structure.
+********************************************************************/
+void make_lsa_trans_name(LSA_TRANS_NAME *trn, 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(&(trn->uni_name), name, len_name);
+ trn->domain_idx = idx;
+}
+
+/*******************************************************************
+reads or writes a LSA_TRANS_NAME structure.
+********************************************************************/
+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);
+ smb_io_unistr2("uni_name", &(trn->uni_name), trn->hdr_name.buffer, ps, depth);
+
+ prs_uint32("domain_idx ", ps, depth, &(trn->domain_idx ));
+}
+
+/*******************************************************************
+reads or writes a DOM_R_REF structure.
+********************************************************************/
+void lsa_io_dom_r_ref(char *desc, DOM_R_REF *r_r, prs_struct *ps, int depth)
+{
+ int i;
+
+ 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("buffer_dom_name", ps, depth, &(r_r->buffer_dom_name)); /* undocumented domain name 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_io_unihdr2("", &(r_r->hdr_dom_name), ps, depth); /* domain name unicode string header */
+
+ for (i = 0; i < r_r->num_ref_doms_1-1; i++)
+ {
+ smb_io_unihdr2("", &(r_r->hdr_ref_dom[i]), ps, depth);
+ }
+
+ smb_io_unistr("", &(r_r->uni_dom_name), ps, depth); /* domain name unicode string */
+
+ for (i = 0; i < r_r->num_ref_doms_2; i++)
+ {
+ smb_io_dom_sid2("", &(r_r->ref_dom[i]), ps, depth); /* referenced domain SIDs */
+ }
+}
+
+/*******************************************************************
+makes an LSA_OBJ_ATTR structure.
+********************************************************************/
+void make_lsa_obj_attr(LSA_OBJ_ATTR *attr, uint32 attributes, uint32 sec_qos)
+{
+ if (attr == NULL) return;
+
+ DEBUG(5,("make_lsa_obj_attr\n"));
+
+ attr->len = 0x18; /* length of object attribute block, in bytes */
+ attr->ptr_root_dir = 0;
+ attr->ptr_obj_name = 0;
+ attr->attributes = attributes;
+ attr->ptr_sec_desc = 0;
+ attr->sec_qos = sec_qos;
+}
+
+/*******************************************************************
+reads or writes an LSA_OBJ_ATTR structure.
+********************************************************************/
+void lsa_io_obj_attr(char *desc, LSA_OBJ_ATTR *attr, prs_struct *ps, int depth)
+{
+ int start;
+
+ if (attr == NULL) return;
+
+ prs_debug(ps, depth, desc, "lsa_io_obj_attr");
+ depth++;
+
+ prs_align(ps);
+
+ start = ps->offset;
+
+ /* these pointers had _better_ be zero, because we don't know
+ what they point to!
+ */
+ prs_uint32("len" , ps, depth, &(attr->len )); /* 0x18 - length (in bytes) inc. the length field. */
+ prs_uint32("ptr_root_dir", ps, depth, &(attr->ptr_root_dir)); /* 0 - root directory (pointer) */
+ prs_uint32("ptr_obj_name", ps, depth, &(attr->ptr_obj_name)); /* 0 - object name (pointer) */
+ prs_uint32("attributes" , ps, depth, &(attr->attributes )); /* 0 - attributes (undocumented) */
+ prs_uint32("ptr_sec_desc", ps, depth, &(attr->ptr_sec_desc)); /* 0 - security descriptior (pointer) */
+ prs_uint32("sec_qos" , ps, depth, &(attr->sec_qos )); /* 0 - security quality of service */
+
+ if (attr->len != ps->offset - start)
+ {
+ DEBUG(3,("lsa_io_obj_attr: length %lx does not match size %lx\n",
+ attr->len, ps->offset - start));
+ }
+}
+/*******************************************************************
+makes an LSA_Q_OPEN_POL structure.
+********************************************************************/
+void make_q_open_pol(LSA_Q_OPEN_POL *r_q, char *server_name,
+ uint32 attributes, uint32 sec_qos,
+ uint32 desired_access)
+{
+ if (r_q == NULL) return;
+
+ DEBUG(5,("make_open_pol\n"));
+
+ r_q->ptr = 1; /* undocumented pointer */
+
+ make_unistr2 (&(r_q->uni_server_name), server_name, strlen(server_name));
+ make_lsa_obj_attr(&(r_q->attr ), attributes, sec_qos);
+
+ r_q->des_access = desired_access;
+}
+
+/*******************************************************************
+reads or writes an LSA_Q_OPEN_POL structure.
+********************************************************************/
+void lsa_io_q_open_pol(char *desc, LSA_Q_OPEN_POL *r_q, prs_struct *ps, int depth)
+{
+ if (r_q == NULL) return;
+
+ prs_debug(ps, depth, desc, "lsa_io_q_open_pol");
+ depth++;
+
+ prs_uint32("ptr ", ps, depth, &(r_q->ptr ));
+
+ smb_io_unistr2 ("", &(r_q->uni_server_name), r_q->ptr, ps, depth);
+ lsa_io_obj_attr("", &(r_q->attr ), ps, depth);
+
+ prs_uint32("des_access", ps, depth, &(r_q->des_access));
+}
+
+/*******************************************************************
+reads or writes an LSA_R_OPEN_POL structure.
+********************************************************************/
+void lsa_io_r_open_pol(char *desc, LSA_R_OPEN_POL *r_p, prs_struct *ps, int depth)
+{
+ if (r_p == NULL) return;
+
+ prs_debug(ps, depth, desc, "lsa_io_r_open_pol");
+ depth++;
+
+
+ smb_io_pol_hnd("", &(r_p->pol), ps, depth);
+
+ prs_uint32("status", ps, depth, &(r_p->status));
+}
+
+/*******************************************************************
+makes an LSA_Q_QUERY_INFO structure.
+********************************************************************/
+void make_q_query(LSA_Q_QUERY_INFO *q_q, POLICY_HND *hnd, uint16 info_class)
+{
+ if (q_q == NULL || hnd == NULL) return;
+
+ DEBUG(5,("make_q_query\n"));
+
+ memcpy(&(q_q->pol), hnd, sizeof(q_q->pol));
+
+ q_q->info_class = info_class;
+}
+
+/*******************************************************************
+reads or writes an LSA_Q_QUERY_INFO structure.
+********************************************************************/
+void lsa_io_q_query(char *desc, LSA_Q_QUERY_INFO *q_q, prs_struct *ps, int depth)
+{
+ if (q_q == NULL) return;
+
+ prs_debug(ps, depth, desc, "lsa_io_q_query");
+ depth++;
+
+ smb_io_pol_hnd("", &(q_q->pol), ps, depth);
+
+ prs_uint16("info_class", ps, depth, &(q_q->info_class));
+}
+
+/*******************************************************************
+reads or writes an LSA_Q_ENUM_TRUST_DOM structure.
+********************************************************************/
+void lsa_io_q_enum_trust_dom(char *desc, LSA_Q_ENUM_TRUST_DOM *q_e, prs_struct *ps, int depth)
+{
+ if (q_e == NULL) return;
+
+ prs_debug(ps, depth, desc, "lsa_io_q_enum_trust_dom");
+ depth++;
+
+
+ smb_io_pol_hnd("", &(q_e->pol), ps, depth);
+
+ prs_uint32("enum_context ", ps, depth, &(q_e->enum_context ));
+ prs_uint32("preferred_len", ps, depth, &(q_e->preferred_len));
+}
+
+/*******************************************************************
+makes an LSA_R_ENUM_TRUST_DOM structure.
+********************************************************************/
+void make_r_enum_trust_dom(LSA_R_ENUM_TRUST_DOM *r_e,
+ uint32 enum_context, char *domain_name, char *domain_sid,
+ uint32 status)
+{
+ if (r_e == NULL) return;
+
+ DEBUG(5,("make_r_enum_trust_dom\n"));
+
+ r_e->enum_context = enum_context;
+
+ if (status == 0)
+ {
+ int len_domain_name = strlen(domain_name);
+
+ r_e->num_domains = 1;
+ r_e->ptr_enum_domains = 1;
+ r_e->num_domains2 = 1;
+
+ make_uni_hdr2(&(r_e->hdr_domain_name ), len_domain_name, len_domain_name, 4);
+ make_unistr2 (&(r_e->uni_domain_name ), domain_name, len_domain_name);
+ make_dom_sid2(&(r_e->other_domain_sid), domain_sid);
+ }
+ else
+ {
+ r_e->num_domains = 0;
+ r_e->ptr_enum_domains = 0;
+ }
+
+ r_e->status = status;
+}
+
+/*******************************************************************
+reads or writes an LSA_R_ENUM_TRUST_DOM structure.
+********************************************************************/
+void lsa_io_r_enum_trust_dom(char *desc, LSA_R_ENUM_TRUST_DOM *r_e, prs_struct *ps, int depth)
+{
+ if (r_e == NULL) return;
+
+ prs_debug(ps, depth, desc, "lsa_io_r_enum_trust_dom");
+ depth++;
+
+ prs_uint32("enum_context ", ps, depth, &(r_e->enum_context ));
+ prs_uint32("num_domains ", ps, depth, &(r_e->num_domains ));
+ prs_uint32("ptr_enum_domains", ps, depth, &(r_e->ptr_enum_domains));
+
+ if (r_e->ptr_enum_domains != 0)
+ {
+ prs_uint32("num_domains2", ps, depth, &(r_e->num_domains2));
+ smb_io_unihdr2 ("", &(r_e->hdr_domain_name ), ps, depth);
+ smb_io_unistr2 ("", &(r_e->uni_domain_name ), r_e->hdr_domain_name.buffer, ps, depth);
+ smb_io_dom_sid2("", &(r_e->other_domain_sid), ps, depth);
+ }
+
+ prs_uint32("status", ps, depth, &(r_e->status));
+}
+
+/*******************************************************************
+makes an LSA_Q_CLOSE structure.
+********************************************************************/
+void make_lsa_q_close(LSA_Q_CLOSE *q_c, POLICY_HND *hnd)
+{
+ if (q_c == NULL || hnd == NULL) return;
+
+ DEBUG(5,("make_lsa_q_close\n"));
+
+ memcpy(&(q_c->pol), hnd, sizeof(q_c->pol));
+}
+
+
+/*******************************************************************
+reads or writes an LSA_Q_CLOSE structure.
+********************************************************************/
+void lsa_io_q_close(char *desc, LSA_Q_CLOSE *q_c, prs_struct *ps, int depth)
+{
+ if (q_c == NULL) return;
+
+ prs_debug(ps, depth, desc, "lsa_io_q_close");
+ depth++;
+
+ smb_io_pol_hnd("", &(q_c->pol), ps, depth);
+}
+
+/*******************************************************************
+makes an LSA_R_CLOSE structure.
+********************************************************************/
+void make_lsa_r_close(LSA_R_CLOSE *q_r, POLICY_HND *hnd)
+{
+ if (q_r == NULL || hnd == NULL) return;
+
+ DEBUG(5,("make_lsa_r_close\n"));
+
+ memcpy(&(q_r->pol), hnd, sizeof(q_r->pol));
+}
+
+
+/*******************************************************************
+reads or writes an LSA_R_CLOSE structure.
+********************************************************************/
+void lsa_io_r_close(char *desc, LSA_R_CLOSE *r_c, prs_struct *ps, int depth)
+{
+ if (r_c == NULL) return;
+
+ prs_debug(ps, depth, desc, "lsa_io_r_close");
+ depth++;
+
+ smb_io_pol_hnd("", &(r_c->pol), ps, depth);
+
+ prs_uint32("status", ps, depth, &(r_c->status));
+}
+
+/*******************************************************************
+reads or writes an LSA_Q_QUERY_INFO structure.
+********************************************************************/
+void lsa_io_r_query(char *desc, LSA_R_QUERY_INFO *r_q, prs_struct *ps, int depth)
+{
+ if (r_q == NULL) return;
+
+ prs_debug(ps, depth, desc, "lsa_io_r_query");
+ depth++;
+
+ prs_uint32("undoc_buffer", ps, depth, &(r_q->undoc_buffer));
+
+ if (r_q->undoc_buffer != 0)
+ {
+ prs_uint16("info_class", ps, depth, &(r_q->info_class));
+
+ switch (r_q->info_class)
+ {
+ case 3:
+ {
+ smb_io_dom_query_3("", &(r_q->dom.id3), ps, depth);
+ break;
+ }
+ case 5:
+ {
+ smb_io_dom_query_5("", &(r_q->dom.id3), ps, depth);
+ break;
+ }
+ default:
+ {
+ /* PANIC! */
+ break;
+ }
+ }
+ }
+
+ prs_uint32("status", ps, depth, &(r_q->status));
+}
+
+/*******************************************************************
+reads or writes a LSA_SID_ENUM structure.
+********************************************************************/
+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));
+
+ for (i = 0; i < sen->num_entries; i++)
+ {
+ fstring temp;
+ sprintf(temp, "ptr_sid[%d]", i);
+ prs_uint32(temp, ps, depth, &(sen->ptr_sid[i])); /* domain SID pointers to be looked up. */
+ }
+
+ for (i = 0; i < sen->num_entries; i++)
+ {
+ fstring temp;
+ sprintf(temp, "sid[%d]", i);
+ smb_io_dom_sid2(temp, &(sen->sid[i]), ps, depth); /* domain SIDs to be looked up. */
+ }
+}
+
+/*******************************************************************
+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_hnd), 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.
+********************************************************************/
+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));
+ prs_uint32("num_entries2 ", ps, depth, &(trn->num_entries2));
+
+ for (i = 0; i < trn->num_entries; i++)
+ {
+ fstring temp;
+ sprintf(temp, "ptr_name[%d] ", i);
+ prs_uint32(temp, ps, depth, &(trn->ptr_name[i])); /* pointer to translated name */
+ }
+
+ for (i = 0; i < trn->num_entries2; i++)
+ {
+ if (trn->ptr_name[i] != 0)
+ {
+ fstring temp;
+ sprintf(temp, "name[%d] ", i);
+ lsa_io_trans_name(temp, &(trn->name[i2]), ps, depth); /* translated name */
+ 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_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_hnd), 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 */
+
+ for (i = 0; i < q_r->num_entries; i++)
+ {
+ smb_io_dom_name("", &(q_r->lookup_name[i]), ps, depth); /* names to be looked up */
+ }
+
+ 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));
+
+ 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));
+}
+
diff --git a/source3/rpc_parse/parse_misc.c b/source3/rpc_parse/parse_misc.c
new file mode 100644
index 0000000000..225754903f
--- /dev/null
+++ b/source3/rpc_parse/parse_misc.c
@@ -0,0 +1,981 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-1997,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ * Copyright (C) Paul Ashton 1997.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+
+extern int DEBUGLEVEL;
+
+
+
+/*******************************************************************
+reads or writes a UTIME type.
+********************************************************************/
+void smb_io_utime(char *desc, UTIME *t, prs_struct *ps, int depth)
+{
+ if (t == NULL) return;
+
+ prs_debug(ps, depth, desc, "smb_io_utime");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32 ("time", ps, depth, &(t->time));
+}
+
+/*******************************************************************
+reads or writes an NTTIME structure.
+********************************************************************/
+void smb_io_time(char *desc, NTTIME *nttime, prs_struct *ps, int depth)
+{
+ if (nttime == NULL) return;
+
+ prs_debug(ps, depth, desc, "smb_io_time");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("low ", ps, depth, &(nttime->low )); /* low part */
+ prs_uint32("high", ps, depth, &(nttime->high)); /* high part */
+}
+
+/*******************************************************************
+reads or writes a LOOKUP_LEVEL structure.
+********************************************************************/
+void smb_io_lookup_level(char *desc, LOOKUP_LEVEL *level, prs_struct *ps, int depth)
+{
+ if (level == NULL) return;
+
+ prs_debug(ps, depth, desc, "smb_io_lookup_level");
+ depth++;
+
+ prs_align(ps);
+ prs_uint16("value", ps, depth, &(level->value));
+ prs_align(ps);
+}
+
+/*******************************************************************
+gets an enumeration handle from an ENUM_HND structure.
+********************************************************************/
+uint32 get_enum_hnd(ENUM_HND *enh)
+{
+ return (enh && enh->ptr_hnd != 0) ? enh->handle : 0;
+}
+
+/*******************************************************************
+makes an ENUM_HND structure.
+********************************************************************/
+void make_enum_hnd(ENUM_HND *enh, uint32 hnd)
+{
+ if (enh == NULL) return;
+
+ DEBUG(5,("smb_io_enum_hnd\n"));
+
+ enh->ptr_hnd = (hnd != 0) ? 1 : 0;
+ enh->handle = hnd;
+}
+
+/*******************************************************************
+reads or writes an ENUM_HND structure.
+********************************************************************/
+void smb_io_enum_hnd(char *desc, ENUM_HND *hnd, prs_struct *ps, int depth)
+{
+ if (hnd == NULL) return;
+
+ prs_debug(ps, depth, desc, "smb_io_enum_hnd");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("ptr_hnd", ps, depth, &(hnd->ptr_hnd)); /* pointer */
+ if (hnd->ptr_hnd != 0)
+ {
+ prs_uint32("handle ", ps, depth, &(hnd->handle )); /* enum handle */
+ }
+}
+
+/*******************************************************************
+creates a DOM_SID structure.
+
+BIG NOTE: this function only does SIDS where the identauth is not >= 2^32
+identauth >= 2^32 can be detected because it will be specified in hex
+
+********************************************************************/
+void make_dom_sid(DOM_SID *sid, char *str_sid)
+{
+ pstring domsid;
+ int identauth;
+ char *p;
+
+ if (sid == NULL) return;
+
+ if (domsid == NULL)
+ {
+ DEBUG(4,("netlogon domain SID: none\n"));
+ sid->sid_rev_num = 0;
+ sid->num_auths = 0;
+ return;
+ }
+
+ pstrcpy(domsid, str_sid);
+
+ DEBUG(4,("make_dom_sid %d SID: %s\n", __LINE__, domsid));
+
+ /* assume, but should check, that domsid starts "S-" */
+ p = strtok(domsid+2,"-");
+ sid->sid_rev_num = atoi(p);
+
+ /* identauth in decimal should be < 2^32 */
+ /* identauth in hex should be >= 2^32 */
+ identauth = atoi(strtok(0,"-"));
+
+ DEBUG(4,("netlogon rev %d\n", sid->sid_rev_num));
+ DEBUG(4,("netlogon %s ia %d\n", p, identauth));
+
+ sid->id_auth[0] = 0;
+ sid->id_auth[1] = 0;
+ sid->id_auth[2] = (identauth & 0xff000000) >> 24;
+ sid->id_auth[3] = (identauth & 0x00ff0000) >> 16;
+ sid->id_auth[4] = (identauth & 0x0000ff00) >> 8;
+ sid->id_auth[5] = (identauth & 0x000000ff);
+
+ sid->num_auths = 0;
+
+ while ((p = strtok(0, "-")) != NULL && sid->num_auths < MAXSUBAUTHS)
+ {
+ sid->sub_auths[sid->num_auths++] = atoi(p);
+ }
+
+ DEBUG(4,("make_dom_sid: %d SID: %s\n", __LINE__, domsid));
+}
+
+/*******************************************************************
+reads or writes a DOM_SID structure.
+********************************************************************/
+void smb_io_dom_sid(char *desc, DOM_SID *sid, prs_struct *ps, int depth)
+{
+ int i;
+
+ if (sid == NULL) return;
+
+ prs_debug(ps, depth, desc, "smb_io_dom_sid");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint8 ("sid_rev_num", ps, depth, &(sid->sid_rev_num));
+ prs_uint8 ("num_auths ", ps, depth, &(sid->num_auths));
+
+ for (i = 0; i < 6; i++)
+ {
+ fstring tmp;
+ sprintf(tmp, "id_auth[%d] ", i);
+ prs_uint8 (tmp, ps, depth, &(sid->id_auth[i]));
+ }
+
+ /* oops! XXXX should really issue a warning here... */
+ if (sid->num_auths > MAXSUBAUTHS) sid->num_auths = MAXSUBAUTHS;
+
+ prs_uint32s(False, "sub_auths ", ps, depth, sid->sub_auths, sid->num_auths);
+}
+
+/*******************************************************************
+creates a DOM_SID2 structure.
+********************************************************************/
+void make_dom_sid2(DOM_SID2 *sid, char *str_sid)
+{
+ make_dom_sid(&(sid->sid), str_sid);
+ sid->num_auths = sid->sid.num_auths;
+}
+
+/*******************************************************************
+reads or writes a DOM_SID2 structure.
+********************************************************************/
+void smb_io_dom_sid2(char *desc, DOM_SID2 *sid, prs_struct *ps, int depth)
+{
+ if (sid == NULL) return;
+
+ prs_debug(ps, depth, desc, "smb_io_dom_sid2");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("num_auths", ps, depth, &(sid->num_auths));
+
+ smb_io_dom_sid("sid", &(sid->sid), ps, depth);
+}
+
+/*******************************************************************
+creates a STRHDR structure.
+********************************************************************/
+void make_str_hdr(STRHDR *hdr, int max_len, int len, uint32 buffer)
+{
+ hdr->str_max_len = max_len;
+ hdr->str_str_len = len;
+ hdr->buffer = buffer;
+}
+
+/*******************************************************************
+reads or writes a STRHDR structure.
+********************************************************************/
+void smb_io_strhdr(char *desc, STRHDR *hdr, prs_struct *ps, int depth)
+{
+ if (hdr == NULL) return;
+
+ prs_debug(ps, depth, desc, "smb_io_strhdr");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint16("str_str_len", ps, depth, &(hdr->str_str_len));
+ prs_uint16("str_max_len", ps, depth, &(hdr->str_max_len));
+ prs_uint32("buffer ", ps, depth, &(hdr->buffer ));
+
+ /* oops! XXXX maybe issue a warning that this is happening... */
+ if (hdr->str_max_len > MAX_STRINGLEN) hdr->str_max_len = MAX_STRINGLEN;
+ if (hdr->str_str_len > MAX_STRINGLEN) hdr->str_str_len = MAX_STRINGLEN;
+}
+
+/*******************************************************************
+creates a UNIHDR structure.
+********************************************************************/
+void make_uni_hdr(UNIHDR *hdr, int max_len, int len, uint32 buffer)
+{
+ hdr->uni_max_len = 2 * max_len;
+ hdr->uni_str_len = 2 * len;
+ hdr->buffer = buffer;
+}
+
+/*******************************************************************
+reads or writes a UNIHDR structure.
+********************************************************************/
+void smb_io_unihdr(char *desc, UNIHDR *hdr, prs_struct *ps, int depth)
+{
+ if (hdr == NULL) return;
+
+ prs_debug(ps, depth, desc, "smb_io_unihdr");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint16("uni_str_len", ps, depth, &(hdr->uni_str_len));
+ prs_uint16("uni_max_len", ps, depth, &(hdr->uni_max_len));
+ prs_uint32("buffer ", ps, depth, &(hdr->buffer ));
+
+ /* oops! XXXX maybe issue a warning that this is happening... */
+ if (hdr->uni_max_len > MAX_UNISTRLEN) hdr->uni_max_len = MAX_UNISTRLEN;
+ if (hdr->uni_str_len > MAX_UNISTRLEN) hdr->uni_str_len = MAX_UNISTRLEN;
+}
+
+/*******************************************************************
+creates a UNIHDR2 structure.
+********************************************************************/
+void make_uni_hdr2(UNIHDR2 *hdr, int max_len, int len, uint16 terminate)
+{
+ make_uni_hdr(&(hdr->unihdr), max_len, len, terminate);
+ hdr->buffer = len > 0 ? 1 : 0;
+}
+
+/*******************************************************************
+reads or writes a UNIHDR2 structure.
+********************************************************************/
+void smb_io_unihdr2(char *desc, UNIHDR2 *hdr2, prs_struct *ps, int depth)
+{
+ if (hdr2 == NULL) return;
+
+ prs_debug(ps, depth, desc, "smb_io_unihdr2");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_unihdr("hdr", &(hdr2->unihdr), ps, depth);
+ prs_uint32("buffer", ps, depth, &(hdr2->buffer));
+}
+
+/*******************************************************************
+creates a UNISTR structure.
+********************************************************************/
+void make_unistr(UNISTR *str, char *buf)
+{
+ /* store the string (null-terminated copy) */
+ struni2(str->buffer, buf);
+}
+
+/*******************************************************************
+reads or writes a UNISTR structure.
+XXXX NOTE: UNISTR structures NEED to be null-terminated.
+********************************************************************/
+void smb_io_unistr(char *desc, UNISTR *uni, prs_struct *ps, int depth)
+{
+ if (uni == NULL) return;
+
+ prs_debug(ps, depth, desc, "smb_io_unistr");
+ depth++;
+
+ prs_align(ps);
+ prs_unistr("unistr", ps, depth, uni);
+}
+
+/*******************************************************************
+creates a UNINOTSTR2 structure.
+********************************************************************/
+void make_uninotstr2(UNINOTSTR2 *str, char *buf, int len)
+{
+ /* set up string lengths. add one if string is not null-terminated */
+ str->uni_max_len = (len+1)*2;
+ str->undoc = 0;
+ str->uni_buf_len = (len+1)*2;
+
+ /* store the string (null-terminated copy) */
+ struni2(str->buffer, buf);
+}
+
+/*******************************************************************
+reads or writes a UNINOTSTR2 structure.
+XXXX NOTE: UNISTR2 structures need NOT be null-terminated.
+ the uni_str_len member tells you how long the string is;
+ the uni_max_len member tells you how large the buffer is.
+********************************************************************/
+void smb_io_uninotstr2(char *desc, UNINOTSTR2 *uni2, uint32 buffer, prs_struct *ps, int depth)
+{
+ if (uni2 == NULL) return;
+
+ if (buffer)
+ {
+ prs_debug(ps, depth, desc, "smb_io_uninotstr2");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("uni_max_len", ps, depth, &(uni2->uni_max_len));
+ prs_uint32("undoc ", ps, depth, &(uni2->undoc ));
+ prs_uint32("uni_buf_len", ps, depth, &(uni2->uni_buf_len));
+
+ /* oops! XXXX maybe issue a warning that this is happening... */
+ if (uni2->uni_max_len > MAX_UNISTRLEN) uni2->uni_max_len = MAX_UNISTRLEN;
+ if (uni2->uni_buf_len > MAX_UNISTRLEN) uni2->uni_buf_len = MAX_UNISTRLEN;
+
+ /* buffer advanced by indicated length of string
+ NOT by searching for null-termination */
+ prs_uninotstr2(True, "buffer ", ps, depth, uni2);
+ }
+ else
+ {
+ prs_debug(ps, depth, desc, "smb_io_uninotstr2 - NULL");
+ depth++;
+ bzero(uni2, sizeof(*uni2));
+ }
+}
+
+/*******************************************************************
+creates a UNISTR2 structure: sets up the buffer, too
+********************************************************************/
+void make_buf_unistr2(UNISTR2 *str, uint32 *ptr, char *buf)
+{
+ if (buf != NULL)
+ {
+ *ptr = 1;
+ make_unistr2(str, buf, strlen(buf));
+ }
+ else
+ {
+ *ptr = 0;
+ make_unistr2(str, "", 0);
+ }
+}
+
+/*******************************************************************
+copies a UNISTR2 structure.
+********************************************************************/
+void copy_unistr2(UNISTR2 *str, UNISTR2 *from)
+{
+ /* set up string lengths. add one if string is not null-terminated */
+ str->uni_max_len = from->uni_max_len;
+ str->undoc = from->undoc;
+ str->uni_str_len = from->uni_str_len;
+
+ /* copy the string */
+ memcpy(str->buffer, from->buffer, sizeof(from->buffer));
+}
+
+/*******************************************************************
+creates a STRING2 structure.
+********************************************************************/
+void make_string2(STRING2 *str, char *buf, int len)
+{
+ /* set up string lengths. add one if string is not null-terminated */
+ str->str_max_len = len+1;
+ str->undoc = 0;
+ str->str_str_len = len+1;
+
+ /* store the string */
+ memcpy(str->buffer, buf, len);
+}
+
+/*******************************************************************
+reads or writes a STRING2 structure.
+XXXX NOTE: STRING2 structures need NOT be null-terminated.
+ the str_str_len member tells you how long the string is;
+ the str_max_len member tells you how large the buffer is.
+********************************************************************/
+void smb_io_string2(char *desc, STRING2 *str2, uint32 buffer, prs_struct *ps, int depth)
+{
+ if (str2 == NULL) return;
+
+ if (buffer)
+ {
+ prs_debug(ps, depth, desc, "smb_io_string2");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("str_max_len", ps, depth, &(str2->str_max_len));
+ prs_uint32("undoc ", ps, depth, &(str2->undoc ));
+ prs_uint32("str_str_len", ps, depth, &(str2->str_str_len));
+
+ /* oops! XXXX maybe issue a warning that this is happening... */
+ if (str2->str_max_len > MAX_STRINGLEN) str2->str_max_len = MAX_STRINGLEN;
+ if (str2->str_str_len > MAX_STRINGLEN) str2->str_str_len = MAX_STRINGLEN;
+
+ /* buffer advanced by indicated length of string
+ NOT by searching for null-termination */
+ prs_string2(True, "buffer ", ps, depth, str2);
+ }
+ else
+ {
+ prs_debug(ps, depth, desc, "smb_io_string2 - NULL");
+ depth++;
+ bzero(str2, sizeof(*str2));
+ }
+}
+
+/*******************************************************************
+creates a UNISTR2 structure.
+********************************************************************/
+void make_unistr2(UNISTR2 *str, char *buf, int len)
+{
+ /* set up string lengths. add one if string is not null-terminated */
+ str->uni_max_len = len+1;
+ str->undoc = 0;
+ str->uni_str_len = len+1;
+
+ /* store the string (null-terminated 8 bit chars into 16 bit chars) */
+ struni2(str->buffer, buf);
+}
+
+/*******************************************************************
+reads or writes a UNISTR2 structure.
+XXXX NOTE: UNISTR2 structures need NOT be null-terminated.
+ the uni_str_len member tells you how long the string is;
+ the uni_max_len member tells you how large the buffer is.
+********************************************************************/
+void smb_io_unistr2(char *desc, UNISTR2 *uni2, uint32 buffer, prs_struct *ps, int depth)
+{
+ if (uni2 == NULL) return;
+
+ if (buffer)
+ {
+ prs_debug(ps, depth, desc, "smb_io_unistr2");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("uni_max_len", ps, depth, &(uni2->uni_max_len));
+ prs_uint32("undoc ", ps, depth, &(uni2->undoc ));
+ prs_uint32("uni_str_len", ps, depth, &(uni2->uni_str_len));
+
+ /* oops! XXXX maybe issue a warning that this is happening... */
+ if (uni2->uni_max_len > MAX_UNISTRLEN) uni2->uni_max_len = MAX_UNISTRLEN;
+ if (uni2->uni_str_len > MAX_UNISTRLEN) uni2->uni_str_len = MAX_UNISTRLEN;
+
+ /* buffer advanced by indicated length of string
+ NOT by searching for null-termination */
+ prs_unistr2(True, "buffer ", ps, depth, uni2);
+ }
+ else
+ {
+ prs_debug(ps, depth, desc, "smb_io_unistr2 - NULL");
+ depth++;
+ bzero(uni2, sizeof(*uni2));
+ }
+}
+
+/*******************************************************************
+creates a DOM_RID2 structure.
+********************************************************************/
+void make_dom_rid2(DOM_RID2 *rid2, uint32 rid)
+{
+ rid2->type = 0x5;
+ rid2->undoc = 0x5;
+ rid2->rid = rid;
+ rid2->rid_idx = 0;
+}
+
+/*******************************************************************
+reads or writes a DOM_RID2 structure.
+********************************************************************/
+void smb_io_dom_rid2(char *desc, DOM_RID2 *rid2, prs_struct *ps, int depth)
+{
+ if (rid2 == NULL) return;
+
+ prs_debug(ps, depth, desc, "smb_io_dom_rid2");
+ depth++;
+
+ prs_align(ps);
+
+ /* should be value 5, so enforce it */
+ rid2->type = 5;
+
+ /* should be value 5, so enforce it */
+ rid2->undoc = 5;
+
+ prs_uint32("type ", ps, depth, &(rid2->type));
+ prs_uint32("undoc ", ps, depth, &(rid2->undoc ));
+ prs_uint32("rid ", ps, depth, &(rid2->rid ));
+ prs_uint32("rid_idx", ps, depth, &(rid2->rid_idx ));
+}
+
+/*******************************************************************
+creates a DOM_RID3 structure.
+********************************************************************/
+void make_dom_rid3(DOM_RID3 *rid3, uint32 rid)
+{
+ rid3->rid = rid;
+ rid3->type1 = 0x1;
+ rid3->ptr_type = 0x1; /* non-zero, basically. */
+ rid3->type2 = 0x1;
+}
+
+/*******************************************************************
+reads or writes a DOM_RID3 structure.
+********************************************************************/
+void smb_io_dom_rid3(char *desc, DOM_RID3 *rid3, prs_struct *ps, int depth)
+{
+ if (rid3 == NULL) return;
+
+ prs_debug(ps, depth, desc, "smb_io_dom_rid3");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("rid ", ps, depth, &(rid3->rid ));
+ prs_uint32("type1 ", ps, depth, &(rid3->type1 ));
+ prs_uint32("ptr_type", ps, depth, &(rid3->ptr_type));
+ prs_uint32("type2 ", ps, depth, &(rid3->type2 ));
+}
+
+/*******************************************************************
+creates a DOM_RID4 structure.
+********************************************************************/
+void make_dom_rid4(DOM_RID4 *rid4, uint16 unknown, uint16 attr, uint32 rid)
+{
+ rid4->unknown = unknown;
+ rid4->attr = attr;
+ rid4->rid = rid;
+}
+
+/*******************************************************************
+reads or writes a DOM_RID4 structure.
+********************************************************************/
+void smb_io_dom_rid4(char *desc, DOM_RID4 *rid4, prs_struct *ps, int depth)
+{
+ if (rid4 == NULL) return;
+
+ prs_debug(ps, depth, desc, "smb_io_dom_rid4. XXXX !check size of unknown! XXXX");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("unknown", ps, depth, &(rid4->unknown));
+ prs_uint16("attr ", ps, depth, &(rid4->attr ));
+ prs_uint32("rid ", ps, depth, &(rid4->rid ));
+}
+
+/*******************************************************************
+makes a DOM_CLNT_SRV structure.
+********************************************************************/
+void make_clnt_srv(DOM_CLNT_SRV *log, char *logon_srv, char *comp_name)
+{
+ if (log == NULL) return;
+
+ DEBUG(5,("make_clnt_srv: %d\n", __LINE__));
+
+ if (logon_srv != NULL)
+ {
+ log->undoc_buffer = 1;
+ make_unistr2(&(log->uni_logon_srv), logon_srv, strlen(logon_srv));
+ }
+ else
+ {
+ log->undoc_buffer = 0;
+ }
+
+ if (comp_name != NULL)
+ {
+ log->undoc_buffer2 = 1;
+ make_unistr2(&(log->uni_comp_name), comp_name, strlen(comp_name));
+ }
+ else
+ {
+ log->undoc_buffer2 = 0;
+ }
+}
+
+/*******************************************************************
+reads or writes a DOM_CLNT_SRV structure.
+********************************************************************/
+void smb_io_clnt_srv(char *desc, DOM_CLNT_SRV *log, prs_struct *ps, int depth)
+{
+ if (log == NULL) return;
+
+ prs_debug(ps, depth, desc, "smb_io_clnt_srv");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("undoc_buffer ", ps, depth, &(log->undoc_buffer ));
+ if (log->undoc_buffer != 0)
+ {
+ smb_io_unistr2("unistr2", &(log->uni_logon_srv), log->undoc_buffer, ps, depth);
+ }
+
+ prs_align(ps);
+
+ prs_uint32("undoc_buffer2", ps, depth, &(log->undoc_buffer2));
+ if (log->undoc_buffer2 != 0)
+ {
+ smb_io_unistr2("unistr2", &(log->uni_comp_name), log->undoc_buffer2, ps, depth);
+ }
+}
+
+/*******************************************************************
+makes a DOM_LOG_INFO structure.
+********************************************************************/
+void make_log_info(DOM_LOG_INFO *log, char *logon_srv, char *acct_name,
+ uint16 sec_chan, char *comp_name)
+{
+ if (log == NULL) return;
+
+ DEBUG(5,("make_log_info %d\n", __LINE__));
+
+ log->undoc_buffer = 1;
+
+ make_unistr2(&(log->uni_logon_srv), logon_srv, strlen(logon_srv));
+ make_unistr2(&(log->uni_acct_name), acct_name, strlen(acct_name));
+
+ log->sec_chan = sec_chan;
+
+ make_unistr2(&(log->uni_comp_name), comp_name, strlen(comp_name));
+}
+
+/*******************************************************************
+reads or writes a DOM_LOG_INFO structure.
+********************************************************************/
+void smb_io_log_info(char *desc, DOM_LOG_INFO *log, prs_struct *ps, int depth)
+{
+ if (log == NULL) return;
+
+ prs_debug(ps, depth, desc, "smb_io_log_info");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("undoc_buffer", ps, depth, &(log->undoc_buffer));
+
+ smb_io_unistr2("unistr2", &(log->uni_logon_srv), True, ps, depth);
+ smb_io_unistr2("unistr2", &(log->uni_acct_name), True, ps, depth);
+
+ prs_uint16("sec_chan", ps, depth, &(log->sec_chan));
+
+ smb_io_unistr2("unistr2", &(log->uni_comp_name), True, ps, depth);
+}
+
+/*******************************************************************
+reads or writes a DOM_CHAL structure.
+********************************************************************/
+void smb_io_chal(char *desc, DOM_CHAL *chal, prs_struct *ps, int depth)
+{
+ if (chal == NULL) return;
+
+ prs_debug(ps, depth, desc, "smb_io_chal");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint8s (False, "data", ps, depth, chal->data, 8);
+}
+
+/*******************************************************************
+reads or writes a DOM_CRED structure.
+********************************************************************/
+void smb_io_cred(char *desc, DOM_CRED *cred, prs_struct *ps, int depth)
+{
+ if (cred == NULL) return;
+
+ prs_debug(ps, depth, desc, "smb_io_cred");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_chal ("", &(cred->challenge), ps, depth);
+ smb_io_utime("", &(cred->timestamp), ps, depth);
+}
+
+/*******************************************************************
+makes a DOM_CLNT_INFO2 structure.
+********************************************************************/
+void make_clnt_info2(DOM_CLNT_INFO2 *clnt,
+ char *logon_srv, char *comp_name,
+ DOM_CRED *clnt_cred)
+{
+ if (clnt == NULL) return;
+
+ DEBUG(5,("make_clnt_info: %d\n", __LINE__));
+
+ make_clnt_srv(&(clnt->login), logon_srv, comp_name);
+
+ if (clnt_cred != NULL)
+ {
+ clnt->ptr_cred = 1;
+ memcpy(&(clnt->cred), clnt_cred, sizeof(clnt->cred));
+ }
+ else
+ {
+ clnt->ptr_cred = 0;
+ }
+}
+
+/*******************************************************************
+reads or writes a DOM_CLNT_INFO2 structure.
+********************************************************************/
+void smb_io_clnt_info2(char *desc, DOM_CLNT_INFO2 *clnt, prs_struct *ps, int depth)
+{
+ if (clnt == NULL) return;
+
+ prs_debug(ps, depth, desc, "smb_io_clnt_info2");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_clnt_srv("", &(clnt->login), ps, depth);
+
+ prs_align(ps);
+
+ prs_uint32("ptr_cred", ps, depth, &(clnt->ptr_cred));
+ smb_io_cred ("", &(clnt->cred ), ps, depth);
+}
+
+/*******************************************************************
+makes a DOM_CLNT_INFO structure.
+********************************************************************/
+void make_clnt_info(DOM_CLNT_INFO *clnt,
+ char *logon_srv, char *acct_name,
+ uint16 sec_chan, char *comp_name,
+ DOM_CRED *cred)
+{
+ if (clnt == NULL || cred == NULL) return;
+
+ DEBUG(5,("make_clnt_info\n"));
+
+ make_log_info(&(clnt->login), logon_srv, acct_name, sec_chan, comp_name);
+ memcpy(&(clnt->cred), cred, sizeof(clnt->cred));
+}
+
+/*******************************************************************
+reads or writes a DOM_CLNT_INFO structure.
+********************************************************************/
+void smb_io_clnt_info(char *desc, DOM_CLNT_INFO *clnt, prs_struct *ps, int depth)
+{
+ if (clnt == NULL) return;
+
+ prs_debug(ps, depth, desc, "smb_io_clnt_info");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_log_info("", &(clnt->login), ps, depth);
+ smb_io_cred ("", &(clnt->cred ), ps, depth);
+}
+
+/*******************************************************************
+makes a DOM_LOGON_ID structure.
+********************************************************************/
+void make_logon_id(DOM_LOGON_ID *log, uint32 log_id_low, uint32 log_id_high)
+{
+ if (log == NULL) return;
+
+ DEBUG(5,("make_logon_id: %d\n", __LINE__));
+
+ log->low = log_id_low;
+ log->high = log_id_high;
+}
+
+/*******************************************************************
+reads or writes a DOM_LOGON_ID structure.
+********************************************************************/
+void smb_io_logon_id(char *desc, DOM_LOGON_ID *log, prs_struct *ps, int depth)
+{
+ if (log == NULL) return;
+
+ prs_debug(ps, depth, desc, "smb_io_logon_id");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("low ", ps, depth, &(log->low ));
+ prs_uint32("high", ps, depth, &(log->high));
+}
+
+/*******************************************************************
+makes an ARC4_OWF structure.
+********************************************************************/
+void make_arc4_owf(ARC4_OWF *hash, uint8 data[16])
+{
+ if (hash == NULL) return;
+
+ DEBUG(5,("make_arc4_owf: %d\n", __LINE__));
+
+ if (data != NULL)
+ {
+ memcpy(hash->data, data, sizeof(hash->data));
+ }
+ else
+ {
+ bzero(hash->data, sizeof(hash->data));
+ }
+}
+
+/*******************************************************************
+reads or writes an ARC4_OWF structure.
+********************************************************************/
+void smb_io_arc4_owf(char *desc, ARC4_OWF *hash, prs_struct *ps, int depth)
+{
+ if (hash == NULL) return;
+
+ prs_debug(ps, depth, desc, "smb_io_arc4_owf");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint8s (False, "data", ps, depth, hash->data, 16);
+}
+
+/*******************************************************************
+reads or writes a DOM_GID structure.
+********************************************************************/
+void smb_io_gid(char *desc, DOM_GID *gid, prs_struct *ps, int depth)
+{
+ if (gid == NULL) return;
+
+ prs_debug(ps, depth, desc, "smb_io_gid");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("g_rid", ps, depth, &(gid->g_rid));
+ prs_uint32("attr ", ps, depth, &(gid->attr ));
+}
+
+/*******************************************************************
+reads or writes an POLICY_HND structure.
+********************************************************************/
+void smb_io_pol_hnd(char *desc, POLICY_HND *pol, prs_struct *ps, int depth)
+{
+ if (pol == NULL) return;
+
+ prs_debug(ps, depth, desc, "smb_io_pol_hnd");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint8s (False, "data", ps, depth, pol->data, POL_HND_SIZE);
+}
+
+/*******************************************************************
+reads or writes a dom query structure.
+********************************************************************/
+void smb_io_dom_query_3(char *desc, DOM_QUERY_3 *d_q, prs_struct *ps, int depth)
+{
+ smb_io_dom_query("", d_q, ps, depth);
+}
+
+/*******************************************************************
+reads or writes a dom query structure.
+********************************************************************/
+void smb_io_dom_query_5(char *desc, DOM_QUERY_3 *d_q, prs_struct *ps, int depth)
+{
+ smb_io_dom_query("", d_q, ps, depth);
+}
+
+/*******************************************************************
+reads or writes a dom query structure.
+********************************************************************/
+void smb_io_dom_query(char *desc, DOM_QUERY *d_q, prs_struct *ps, int depth)
+{
+ if (d_q == NULL) return;
+
+ prs_debug(ps, depth, desc, "smb_io_dom_query");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint16("uni_dom_max_len", ps, depth, &(d_q->uni_dom_max_len)); /* domain name string length * 2 */
+ prs_uint16("uni_dom_str_len", ps, depth, &(d_q->uni_dom_str_len)); /* domain name string length * 2 */
+
+ prs_uint32("buffer_dom_name", ps, depth, &(d_q->buffer_dom_name)); /* undocumented domain name string buffer pointer */
+ prs_uint32("buffer_dom_sid ", ps, depth, &(d_q->buffer_dom_sid )); /* undocumented domain SID string buffer pointer */
+
+ smb_io_unistr2("unistr2", &(d_q->uni_domain_name), d_q->buffer_dom_name, ps, depth); /* domain name (unicode string) */
+
+ if (d_q->buffer_dom_sid != 0)
+ {
+ smb_io_dom_sid2("", &(d_q->dom_sid), ps, depth); /* domain SID */
+ }
+ else
+ {
+ bzero(&(d_q->dom_sid), sizeof(d_q->dom_sid));
+ }
+}
+
+/*******************************************************************
+reads or writes a DOM_NAME structure.
+********************************************************************/
+void smb_io_dom_name(char *desc, DOM_NAME *name, prs_struct *ps, int depth)
+{
+ if (name == NULL) return;
+
+ prs_debug(ps, depth, desc, "smb_io_dom_name");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("uni_str_len", ps, depth, &(name->uni_str_len));
+
+ /* don't know if len is specified by uni_str_len member... */
+ /* assume unicode string is unicode-null-terminated, instead */
+
+ smb_io_unistr("", &(name->str), ps, depth);
+}
+
+
diff --git a/source3/rpc_parse/parse_net.c b/source3/rpc_parse/parse_net.c
new file mode 100644
index 0000000000..69d6ac08ed
--- /dev/null
+++ b/source3/rpc_parse/parse_net.c
@@ -0,0 +1,1147 @@
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-1997,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ * Copyright (C) Paul Ashton 1997.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void net_io_neg_flags(char *desc, NEG_FLAGS *neg, prs_struct *ps, int depth)
+{
+ if (neg == NULL) return;
+
+ prs_debug(ps, depth, desc, "net_io_neg_flags");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("neg_flags", ps, depth, &(neg->neg_flags));
+}
+
+/*******************************************************************
+creates a NETLOGON_INFO_3 structure.
+********************************************************************/
+void make_netinfo_3(NETLOGON_INFO_3 *info, uint32 flags, uint32 logon_attempts)
+{
+ info->flags = flags;
+ info->logon_attempts = logon_attempts;
+ info->reserved_1 = 0x0;
+ info->reserved_2 = 0x0;
+ info->reserved_3 = 0x0;
+ info->reserved_4 = 0x0;
+ info->reserved_5 = 0x0;
+}
+
+/*******************************************************************
+reads or writes a NETLOGON_INFO_3 structure.
+********************************************************************/
+void net_io_netinfo_3(char *desc, NETLOGON_INFO_3 *info, prs_struct *ps, int depth)
+{
+ if (info == NULL) return;
+
+ prs_debug(ps, depth, desc, "net_io_netinfo_3");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("flags ", ps, depth, &(info->flags ));
+ prs_uint32("logon_attempts", ps, depth, &(info->logon_attempts));
+ prs_uint32("reserved_1 ", ps, depth, &(info->reserved_1 ));
+ prs_uint32("reserved_2 ", ps, depth, &(info->reserved_2 ));
+ prs_uint32("reserved_3 ", ps, depth, &(info->reserved_3 ));
+ prs_uint32("reserved_4 ", ps, depth, &(info->reserved_4 ));
+ prs_uint32("reserved_5 ", ps, depth, &(info->reserved_5 ));
+}
+
+
+/*******************************************************************
+creates a NETLOGON_INFO_1 structure.
+********************************************************************/
+void make_netinfo_1(NETLOGON_INFO_1 *info, uint32 flags, uint32 pdc_status)
+{
+ info->flags = flags;
+ info->pdc_status = pdc_status;
+}
+
+/*******************************************************************
+reads or writes a NETLOGON_INFO_1 structure.
+********************************************************************/
+void net_io_netinfo_1(char *desc, NETLOGON_INFO_1 *info, prs_struct *ps, int depth)
+{
+ if (info == NULL) return;
+
+ prs_debug(ps, depth, desc, "net_io_netinfo_1");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("flags ", ps, depth, &(info->flags ));
+ prs_uint32("pdc_status", ps, depth, &(info->pdc_status));
+}
+
+/*******************************************************************
+creates a NETLOGON_INFO_2 structure.
+********************************************************************/
+void make_netinfo_2(NETLOGON_INFO_2 *info, uint32 flags, uint32 pdc_status,
+ uint32 tc_status, char *trusted_dc_name)
+{
+ int len_dc_name = strlen(trusted_dc_name);
+ info->flags = flags;
+ info->pdc_status = pdc_status;
+ info->ptr_trusted_dc_name = 1;
+ info->tc_status = tc_status;
+
+ if (trusted_dc_name != NULL)
+ {
+ make_unistr2(&(info->uni_trusted_dc_name), trusted_dc_name, len_dc_name);
+ }
+ else
+ {
+ make_unistr2(&(info->uni_trusted_dc_name), "", 1);
+ }
+}
+
+/*******************************************************************
+reads or writes a NETLOGON_INFO_2 structure.
+********************************************************************/
+void net_io_netinfo_2(char *desc, NETLOGON_INFO_2 *info, prs_struct *ps, int depth)
+{
+ if (info == NULL) return;
+
+ prs_debug(ps, depth, desc, "net_io_netinfo_2");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("flags ", ps, depth, &(info->flags ));
+ prs_uint32("pdc_status ", ps, depth, &(info->pdc_status ));
+ prs_uint32("ptr_trusted_dc_name", ps, depth, &(info->ptr_trusted_dc_name));
+ prs_uint32("tc_status ", ps, depth, &(info->tc_status ));
+
+ if (info->ptr_trusted_dc_name != 0)
+ {
+ smb_io_unistr2("unistr2", &(info->uni_trusted_dc_name), info->ptr_trusted_dc_name, ps, depth);
+ }
+
+ prs_align(ps);
+}
+
+/*******************************************************************
+makes an NET_Q_LOGON_CTRL2 structure.
+********************************************************************/
+void make_q_logon_ctrl2(NET_Q_LOGON_CTRL2 *q_l, char *server_name,
+ uint32 function_code)
+{
+ if (q_l == NULL) return;
+
+ DEBUG(5,("make_q_logon_ctrl2\n"));
+
+ q_l->ptr = 1; /* undocumented pointer */
+ make_unistr2 (&(q_l->uni_server_name), server_name, strlen(server_name));
+
+ q_l->function_code = function_code; /* should only be 0x1 */
+ q_l->query_level = function_code; /* should only be 0x1 */
+ q_l->switch_value = function_code; /* should only be 0x1 */
+}
+
+/*******************************************************************
+reads or writes an NET_Q_LOGON_CTRL2 structure.
+********************************************************************/
+void net_io_q_logon_ctrl2(char *desc, NET_Q_LOGON_CTRL2 *q_l, prs_struct *ps, int depth)
+{
+ if (q_l == NULL) return;
+
+ prs_debug(ps, depth, desc, "net_io_q_logon_ctrl2");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("ptr ", ps, depth, &(q_l->ptr ));
+
+ smb_io_unistr2 ("", &(q_l->uni_server_name), q_l->ptr, ps, depth);
+
+ prs_align(ps);
+
+ prs_uint32("function_code", ps, depth, &(q_l->function_code));
+ prs_uint32("query_level ", ps, depth, &(q_l->query_level ));
+ prs_uint32("switch_value ", ps, depth, &(q_l->switch_value ));
+}
+
+/*******************************************************************
+makes an NET_R_LOGON_CTRL2 structure.
+********************************************************************/
+void make_r_logon_ctrl2(NET_R_LOGON_CTRL2 *r_l, uint32 query_level,
+ uint32 flags, uint32 pdc_status, uint32 logon_attempts,
+ uint32 tc_status, char *trusted_domain_name)
+{
+ if (r_l == NULL) return;
+
+ DEBUG(5,("make_r_logon_ctrl2\n"));
+
+ r_l->switch_value = query_level; /* should only be 0x1 */
+
+ switch (query_level)
+ {
+ case 1:
+ {
+ r_l->ptr = 1; /* undocumented pointer */
+ make_netinfo_1(&(r_l->logon.info1), flags, pdc_status);
+ r_l->status = 0;
+
+ break;
+ }
+ case 2:
+ {
+ r_l->ptr = 1; /* undocumented pointer */
+ make_netinfo_2(&(r_l->logon.info2), flags, pdc_status,
+ tc_status, trusted_domain_name);
+ r_l->status = 0;
+
+ break;
+ }
+ case 3:
+ {
+ r_l->ptr = 1; /* undocumented pointer */
+ make_netinfo_3(&(r_l->logon.info3), flags, logon_attempts);
+ r_l->status = 0;
+
+ break;
+ }
+ default:
+ {
+ DEBUG(2,("make_r_logon_ctrl2: unsupported switch value %d\n",
+ r_l->switch_value));
+ r_l->ptr = 0; /* undocumented pointer */
+
+ /* take a guess at an error code... */
+ r_l->status = NT_STATUS_INVALID_INFO_CLASS;
+
+ break;
+ }
+ }
+}
+
+/*******************************************************************
+reads or writes an NET_R_LOGON_CTRL2 structure.
+********************************************************************/
+void net_io_r_logon_ctrl2(char *desc, NET_R_LOGON_CTRL2 *r_l, prs_struct *ps, int depth)
+{
+ if (r_l == NULL) return;
+
+ prs_debug(ps, depth, desc, "net_io_r_logon_ctrl2");
+ depth++;
+
+ prs_uint32("switch_value ", ps, depth, &(r_l->switch_value ));
+ prs_uint32("ptr ", ps, depth, &(r_l->ptr ));
+
+ if (r_l->ptr != 0)
+ {
+ switch (r_l->switch_value)
+ {
+ case 1:
+ {
+ net_io_netinfo_1("", &(r_l->logon.info1), ps, depth);
+ break;
+ }
+ case 2:
+ {
+ net_io_netinfo_2("", &(r_l->logon.info2), ps, depth);
+ break;
+ }
+ case 3:
+ {
+ net_io_netinfo_3("", &(r_l->logon.info3), ps, depth);
+ break;
+ }
+ default:
+ {
+ DEBUG(2,("net_io_r_logon_ctrl2: unsupported switch value %d\n",
+ r_l->switch_value));
+ break;
+ }
+ }
+ }
+
+ prs_uint32("status ", ps, depth, &(r_l->status ));
+}
+
+/*******************************************************************
+makes an NET_R_TRUST_DOM_LIST structure.
+********************************************************************/
+void make_r_trust_dom(NET_R_TRUST_DOM_LIST *r_t,
+ uint32 num_doms, char *dom_name)
+{
+ int i = 0;
+
+ if (r_t == NULL) return;
+
+ DEBUG(5,("make_r_trust_dom\n"));
+
+ for (i = 0; i < MAX_TRUST_DOMS; i++)
+ {
+ r_t->uni_trust_dom_name[i].uni_str_len = 0;
+ r_t->uni_trust_dom_name[i].uni_max_len = 0;
+ }
+ if (num_doms > MAX_TRUST_DOMS) num_doms = MAX_TRUST_DOMS;
+
+ for (i = 0; i < num_doms; i++)
+ {
+ fstring domain_name;
+ fstrcpy(domain_name, dom_name);
+ strupper(domain_name);
+ make_unistr2(&(r_t->uni_trust_dom_name[i]), domain_name, strlen(domain_name));
+ /* the use of UNISTR2 here is non-standard. */
+ r_t->uni_trust_dom_name[i].undoc = 0x1;
+ }
+
+ r_t->status = 0;
+}
+
+/*******************************************************************
+reads or writes an NET_R_TRUST_DOM_LIST structure.
+********************************************************************/
+void net_io_r_trust_dom(char *desc, NET_R_TRUST_DOM_LIST *r_t, prs_struct *ps, int depth)
+{
+ int i;
+ if (r_t == NULL) return;
+
+ prs_debug(ps, depth, desc, "net_io_r_trust_dom");
+ depth++;
+
+ for (i = 0; i < MAX_TRUST_DOMS; i++)
+ {
+ if (r_t->uni_trust_dom_name[i].uni_str_len == 0) break;
+ smb_io_unistr2("", &(r_t->uni_trust_dom_name[i]), True, ps, depth);
+ }
+
+ prs_uint32("status", ps, depth, &(r_t->status));
+}
+
+/*******************************************************************
+makes an NET_Q_TRUST_DOM_LIST structure.
+********************************************************************/
+void make_q_trust_dom(NET_Q_TRUST_DOM_LIST *q_l, char *server_name,
+ uint32 function_code)
+{
+ if (q_l == NULL) return;
+
+ DEBUG(5,("make_q_trust_dom\n"));
+
+ make_unistr2 (&(q_l->uni_server_name), server_name, strlen(server_name));
+
+ q_l->function_code = function_code; /* should only be 0x31 */
+}
+
+/*******************************************************************
+reads or writes an NET_Q_TRUST_DOM_LIST structure.
+********************************************************************/
+void net_io_q_trust_dom(char *desc, NET_Q_TRUST_DOM_LIST *q_l, prs_struct *ps, int depth)
+{
+ if (q_l == NULL) return;
+
+ prs_debug(ps, depth, desc, "net_io_q_trust_dom");
+ depth++;
+
+ prs_uint32("ptr ", ps, depth, &(q_l->ptr ));
+ smb_io_unistr2 ("", &(q_l->uni_server_name), q_l->ptr, ps, depth);
+
+ prs_align(ps);
+
+ prs_uint32("function_code", ps, depth, &(q_l->function_code));
+}
+
+/*******************************************************************
+makes an NET_Q_REQ_CHAL structure.
+********************************************************************/
+void make_q_req_chal(NET_Q_REQ_CHAL *q_c,
+ char *logon_srv, char *logon_clnt,
+ DOM_CHAL *clnt_chal)
+{
+ if (q_c == NULL) return;
+
+ DEBUG(5,("make_q_req_chal: %d\n", __LINE__));
+
+ q_c->undoc_buffer = 1; /* don't know what this buffer is */
+
+ make_unistr2(&(q_c->uni_logon_srv ), logon_srv , strlen(logon_srv ));
+ make_unistr2(&(q_c->uni_logon_clnt), logon_clnt, strlen(logon_clnt));
+
+ memcpy(q_c->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data));
+
+ DEBUG(5,("make_q_req_chal: %d\n", __LINE__));
+}
+
+/*******************************************************************
+reads or writes an NET_Q_REQ_CHAL structure.
+********************************************************************/
+void net_io_q_req_chal(char *desc, NET_Q_REQ_CHAL *q_c, prs_struct *ps, int depth)
+{
+ int old_align;
+ if (q_c == NULL) return;
+
+ prs_debug(ps, depth, desc, "net_io_q_req_chal");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("undoc_buffer", ps, depth, &(q_c->undoc_buffer));
+
+ smb_io_unistr2("", &(q_c->uni_logon_srv), True, ps, depth); /* logon server unicode string */
+ smb_io_unistr2("", &(q_c->uni_logon_clnt), True, ps, depth); /* logon client unicode string */
+
+ old_align = ps->align;
+ ps->align = 0;
+ /* client challenge is _not_ aligned after the unicode strings */
+ smb_io_chal("", &(q_c->clnt_chal), ps, depth); /* client challenge */
+ ps->align = old_align;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void net_io_r_req_chal(char *desc, NET_R_REQ_CHAL *r_c, prs_struct *ps, int depth)
+{
+ if (r_c == NULL) return;
+
+ prs_debug(ps, depth, desc, "net_io_r_req_chal");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_chal("", &(r_c->srv_chal), ps, depth); /* server challenge */
+
+ prs_uint32("status", ps, depth, &(r_c->status));
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void make_q_auth_2(NET_Q_AUTH_2 *q_a,
+ char *logon_srv, char *acct_name, uint16 sec_chan, char *comp_name,
+ DOM_CHAL *clnt_chal, uint32 clnt_flgs)
+{
+ if (q_a == NULL) return;
+
+ DEBUG(5,("make_q_auth_2: %d\n", __LINE__));
+
+ make_log_info(&(q_a->clnt_id), logon_srv, acct_name, sec_chan, comp_name);
+ memcpy(q_a->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data));
+ q_a->clnt_flgs.neg_flags = clnt_flgs;
+
+ DEBUG(5,("make_q_auth_2: %d\n", __LINE__));
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void net_io_q_auth_2(char *desc, NET_Q_AUTH_2 *q_a, prs_struct *ps, int depth)
+{
+ int old_align;
+ if (q_a == NULL) return;
+
+ prs_debug(ps, depth, desc, "net_io_q_auth_2");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_log_info ("", &(q_a->clnt_id), ps, depth); /* client identification info */
+ /* client challenge is _not_ aligned */
+ old_align = ps->align;
+ ps->align = 0;
+ smb_io_chal ("", &(q_a->clnt_chal), ps, depth); /* client-calculated credentials */
+ ps->align = old_align;
+ net_io_neg_flags("", &(q_a->clnt_flgs), ps, depth);
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void net_io_r_auth_2(char *desc, NET_R_AUTH_2 *r_a, prs_struct *ps, int depth)
+{
+ if (r_a == NULL) return;
+
+ prs_debug(ps, depth, desc, "net_io_r_auth_2");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_chal ("", &(r_a->srv_chal), ps, depth); /* server challenge */
+ net_io_neg_flags("", &(r_a->srv_flgs), ps, depth);
+
+ prs_uint32("status", ps, depth, &(r_a->status));
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void make_q_srv_pwset(NET_Q_SRV_PWSET *q_s, char sess_key[16],
+ char *logon_srv, char *acct_name, uint16 sec_chan, char *comp_name,
+ DOM_CRED *cred, char nt_cypher[16])
+{
+ if (q_s == NULL || cred == NULL) return;
+
+ DEBUG(5,("make_q_srv_pwset\n"));
+
+ make_clnt_info(&(q_s->clnt_id), logon_srv, acct_name, sec_chan, comp_name, cred);
+
+ memcpy(q_s->pwd, nt_cypher, sizeof(q_s->pwd));
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void net_io_q_srv_pwset(char *desc, NET_Q_SRV_PWSET *q_s, prs_struct *ps, int depth)
+{
+ if (q_s == NULL) return;
+
+ prs_debug(ps, depth, desc, "net_io_q_srv_pwset");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_clnt_info("", &(q_s->clnt_id), ps, depth); /* client identification/authentication info */
+ prs_uint8s (False, "pwd", ps, depth, q_s->pwd, 16); /* new password - undocumented */
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void net_io_r_srv_pwset(char *desc, NET_R_SRV_PWSET *r_s, prs_struct *ps, int depth)
+{
+ if (r_s == NULL) return;
+
+ prs_debug(ps, depth, desc, "net_io_r_srv_pwset");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_cred("", &(r_s->srv_cred), ps, depth); /* server challenge */
+
+ prs_uint32("status", ps, depth, &(r_s->status));
+}
+
+
+/*************************************************************************
+ make DOM_SID2 array from a string containing multiple sids
+ *************************************************************************/
+static int make_dom_sid2s(char *sids_str, DOM_SID2 *sids, int max_sids)
+{
+ char *ptr;
+ pstring s2;
+ int count;
+
+ DEBUG(4,("make_dom_sid2s: %s\n", sids_str));
+
+ if (sids_str == NULL || *sids_str == 0) return 0;
+
+ for (count = 0, ptr = sids_str; next_token(&ptr, s2, NULL) && count < max_sids; count++)
+ {
+ make_dom_sid2(&sids[count], s2);
+ }
+
+ return count;
+}
+
+/*******************************************************************
+makes a NET_ID_INFO_1 structure.
+********************************************************************/
+void make_id_info1(NET_ID_INFO_1 *id, char *domain_name,
+ uint32 param_ctrl, uint32 log_id_low, uint32 log_id_high,
+ char *user_name, char *wksta_name,
+ char sess_key[16],
+ unsigned char lm_cypher[16], unsigned char nt_cypher[16])
+{
+ int len_domain_name = strlen(domain_name);
+ int len_user_name = strlen(user_name );
+ int len_wksta_name = strlen(wksta_name );
+
+ unsigned char arc4_lm_owf[16];
+ unsigned char arc4_nt_owf[16];
+
+ if (id == NULL) return;
+
+ DEBUG(5,("make_id_info1: %d\n", __LINE__));
+
+ id->ptr_id_info1 = 1;
+
+ make_uni_hdr(&(id->hdr_domain_name), len_domain_name, len_domain_name, 4);
+
+ id->param_ctrl = param_ctrl;
+ make_logon_id(&(id->logon_id), log_id_low, log_id_high);
+
+ make_uni_hdr(&(id->hdr_user_name ), len_user_name , len_user_name , 4);
+ make_uni_hdr(&(id->hdr_wksta_name ), len_wksta_name , len_wksta_name , 4);
+
+#ifdef USE_ARCFOUR
+
+ if (lm_cypher && nt_cypher)
+ {
+ void arcfour(uint8 key[16], uint8 out[16], uint8 in[16]);
+ unsigned char arc4_key[16];
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("lm cypher:"));
+ dump_data(100, lm_cypher, 16);
+
+ DEBUG(100,("nt cypher:"));
+ dump_data(100, nt_cypher, 16);
+#endif
+
+ memset(arc4_key, 0, 16);
+ memcpy(arc4_key, sess_key, 16);
+
+ arcfour(arc4_key, arc4_lm_owf, lm_cypher);
+ arcfour(arc4_key, arc4_nt_owf, nt_cypher);
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("arcfour encrypt of lm owf password:"));
+ dump_data(100, arc4_lm_owf, 16);
+
+ DEBUG(100,("arcfour encrypt of nt owf password:"));
+ dump_data(100, arc4_nt_owf, 16);
+#endif
+ /* set up pointers to cypher blocks */
+ lm_cypher = arc4_lm_owf;
+ nt_cypher = arc4_nt_owf;
+ }
+
+#else
+
+ if (lm_cypher)
+ {
+ /* oops. can only send what-ever-it-is direct */
+ memcpy(arc4_lm_owf, lm_cypher, 16);
+ lm_cypher = arc4_lm_owf;
+ }
+ if (nt_cypher)
+ {
+ /* oops. can only send what-ever-it-is direct */
+ memcpy(arc4_nt_owf, nt_cypher, 16);
+ nt_cypher = arc4_nt_owf;
+ }
+
+#endif
+
+ make_arc4_owf(&(id->arc4_lm_owf), lm_cypher);
+ make_arc4_owf(&(id->arc4_nt_owf), nt_cypher);
+
+ make_unistr2(&(id->uni_domain_name), domain_name, len_domain_name);
+ make_unistr2(&(id->uni_user_name ), user_name , len_user_name );
+ make_unistr2(&(id->uni_wksta_name ), wksta_name , len_wksta_name );
+}
+
+/*******************************************************************
+reads or writes an NET_ID_INFO_1 structure.
+********************************************************************/
+void net_io_id_info1(char *desc, NET_ID_INFO_1 *id, prs_struct *ps, int depth)
+{
+ if (id == NULL) return;
+
+ prs_debug(ps, depth, desc, "net_io_id_info1");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("ptr_id_info1", ps, depth, &(id->ptr_id_info1));
+
+ if (id->ptr_id_info1 != 0)
+ {
+ smb_io_unihdr("unihdr", &(id->hdr_domain_name), ps, depth);
+
+ prs_uint32("param_ctrl", ps, depth, &(id->param_ctrl));
+ smb_io_logon_id("", &(id->logon_id), ps, depth);
+
+ smb_io_unihdr("unihdr", &(id->hdr_user_name ), ps, depth);
+ smb_io_unihdr("unihdr", &(id->hdr_wksta_name ), ps, depth);
+
+ smb_io_arc4_owf("", &(id->arc4_lm_owf), ps, depth);
+ smb_io_arc4_owf("", &(id->arc4_nt_owf), ps, depth);
+
+ smb_io_unistr2("unistr2", &(id->uni_domain_name), id->hdr_domain_name.buffer, ps, depth);
+ smb_io_unistr2("unistr2", &(id->uni_user_name ), id->hdr_user_name.buffer, ps, depth);
+ smb_io_unistr2("unistr2", &(id->uni_wksta_name ), id->hdr_wksta_name.buffer, ps, depth);
+ }
+}
+
+/*******************************************************************
+makes a NET_ID_INFO_2 structure.
+********************************************************************/
+void make_id_info2(NET_ID_INFO_2 *id, char *domain_name,
+ uint32 param_ctrl, uint32 log_id_low, uint32 log_id_high,
+ char *user_name, char *wksta_name,
+ unsigned char lm_challenge[8],
+ unsigned char lm_chal_resp[24],
+ unsigned char nt_chal_resp[24])
+{
+ int len_domain_name = strlen(domain_name);
+ int len_user_name = strlen(user_name );
+ int len_wksta_name = strlen(wksta_name );
+
+ unsigned char arc4_lm_owf[24];
+ unsigned char arc4_nt_owf[24];
+
+ if (id == NULL) return;
+
+ DEBUG(5,("make_id_info2: %d\n", __LINE__));
+
+ id->ptr_id_info2 = 1;
+
+ make_uni_hdr(&(id->hdr_domain_name), len_domain_name, len_domain_name, 4);
+
+ id->param_ctrl = param_ctrl;
+ make_logon_id(&(id->logon_id), log_id_low, log_id_high);
+
+ make_uni_hdr(&(id->hdr_user_name ), len_user_name , len_user_name , 4);
+ make_uni_hdr(&(id->hdr_wksta_name ), len_wksta_name , len_wksta_name , 4);
+
+ if (nt_chal_resp)
+ {
+ /* oops. can only send what-ever-it-is direct */
+ memcpy(arc4_nt_owf, nt_chal_resp, 24);
+ nt_chal_resp = arc4_nt_owf;
+ }
+ if (lm_chal_resp)
+ {
+ /* oops. can only send what-ever-it-is direct */
+ memcpy(arc4_lm_owf, lm_chal_resp, 24);
+ lm_chal_resp = arc4_lm_owf;
+ }
+
+ memcpy(&(id->lm_chal), lm_challenge, sizeof(id->lm_chal));
+ make_str_hdr(&(id->hdr_nt_chal_resp), 24, 24, nt_chal_resp != NULL ? 1 : 0);
+ make_str_hdr(&(id->hdr_lm_chal_resp), 24, 24, lm_chal_resp != NULL ? 1 : 0);
+
+ make_unistr2(&(id->uni_domain_name), domain_name, len_domain_name);
+ make_unistr2(&(id->uni_user_name ), user_name , len_user_name );
+ make_unistr2(&(id->uni_wksta_name ), wksta_name , len_wksta_name );
+
+ make_string2(&(id->nt_chal_resp ), nt_chal_resp , nt_chal_resp != NULL ? 24 : 0);
+ make_string2(&(id->lm_chal_resp ), lm_chal_resp , lm_chal_resp != NULL ? 24 : 0);
+}
+
+/*******************************************************************
+reads or writes an NET_ID_INFO_1 structure.
+********************************************************************/
+void net_io_id_info2(char *desc, NET_ID_INFO_2 *id, prs_struct *ps, int depth)
+{
+ if (id == NULL) return;
+
+ prs_debug(ps, depth, desc, "net_io_id_info2");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("ptr_id_info2", ps, depth, &(id->ptr_id_info2));
+
+ if (id->ptr_id_info2 != 0)
+ {
+ smb_io_unihdr("unihdr", &(id->hdr_domain_name), ps, depth);
+
+ prs_uint32("param_ctrl", ps, depth, &(id->param_ctrl));
+ smb_io_logon_id("", &(id->logon_id), ps, depth);
+
+ smb_io_unihdr("unihdr", &(id->hdr_user_name ), ps, depth);
+ smb_io_unihdr("unihdr", &(id->hdr_wksta_name ), ps, depth);
+
+ prs_uint8s (False, "lm_chal", ps, depth, id->lm_chal, 8); /* lm 8 byte challenge */
+
+ smb_io_strhdr("hdr_nt_chal_resp", &(id->hdr_nt_chal_resp ), ps, depth);
+ smb_io_strhdr("hdr_lm_chal_resp", &(id->hdr_lm_chal_resp ), ps, depth);
+
+ smb_io_unistr2("uni_domain_name", &(id->uni_domain_name), id->hdr_domain_name .buffer, ps, depth);
+ smb_io_unistr2("uni_user_name ", &(id->uni_user_name ), id->hdr_user_name .buffer, ps, depth);
+ smb_io_unistr2("uni_wksta_name ", &(id->uni_wksta_name ), id->hdr_wksta_name .buffer, ps, depth);
+ smb_io_string2("nt_chal_resp" , &(id->nt_chal_resp) , id->hdr_nt_chal_resp.buffer, ps, depth);
+ smb_io_string2("lm_chal_resp" , &(id->lm_chal_resp) , id->hdr_lm_chal_resp.buffer, ps, depth);
+ }
+}
+
+
+/*******************************************************************
+makes a DOM_SAM_INFO structure.
+********************************************************************/
+void make_sam_info(DOM_SAM_INFO *sam,
+ char *logon_srv, char *comp_name, DOM_CRED *clnt_cred,
+ DOM_CRED *rtn_cred, uint16 logon_level,
+ NET_ID_INFO_CTR *ctr, uint16 validation_level)
+{
+ if (sam == NULL) return;
+
+ DEBUG(5,("make_sam_info: %d\n", __LINE__));
+
+ make_clnt_info2(&(sam->client), logon_srv, comp_name, clnt_cred);
+
+ if (rtn_cred != NULL)
+ {
+ sam->ptr_rtn_cred = 1;
+ memcpy(&(sam->rtn_cred), rtn_cred, sizeof(sam->rtn_cred));
+ }
+ else
+ {
+ sam->ptr_rtn_cred = 0;
+ }
+
+ sam->logon_level = logon_level;
+ sam->ctr = ctr;
+ sam->validation_level = validation_level;
+}
+
+/*******************************************************************
+reads or writes a DOM_SAM_INFO structure.
+********************************************************************/
+void net_io_id_info_ctr(char *desc, NET_ID_INFO_CTR *ctr, prs_struct *ps, int depth)
+{
+ if (ctr == NULL) return;
+
+ prs_debug(ps, depth, desc, "smb_io_sam_info");
+ depth++;
+
+ /* don't 4-byte align here! */
+
+ prs_uint16("switch_value ", ps, depth, &(ctr->switch_value));
+
+ switch (ctr->switch_value)
+ {
+ case 1:
+ {
+ net_io_id_info1("", &(ctr->auth.id1), ps, depth);
+ break;
+ }
+ case 2:
+ {
+ net_io_id_info2("", &(ctr->auth.id2), ps, depth);
+ break;
+ }
+ default:
+ {
+ /* PANIC! */
+ DEBUG(4,("smb_io_sam_info: unknown switch_value!\n"));
+ break;
+ }
+ }
+}
+
+/*******************************************************************
+reads or writes a DOM_SAM_INFO structure.
+********************************************************************/
+void smb_io_sam_info(char *desc, DOM_SAM_INFO *sam, prs_struct *ps, int depth)
+{
+ if (sam == NULL) return;
+
+ prs_debug(ps, depth, desc, "smb_io_sam_info");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_clnt_info2("", &(sam->client ), ps, depth);
+
+ prs_uint32("ptr_rtn_cred ", ps, depth, &(sam->ptr_rtn_cred));
+ smb_io_cred ("", &(sam->rtn_cred), ps, depth);
+
+ prs_uint16("logon_level ", ps, depth, &(sam->logon_level ));
+
+ if (sam->logon_level != 0 && sam->ctr != NULL)
+ {
+ net_io_id_info_ctr("logon_info", sam->ctr, ps, depth);
+ }
+
+ prs_uint16("validation_level", ps, depth, &(sam->validation_level));
+}
+
+/*************************************************************************
+ make_net_user_info3
+ *************************************************************************/
+void make_net_user_info3(NET_USER_INFO_3 *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 *logon_script,
+ char *profile_path,
+ char *home_dir,
+ char *dir_drive,
+
+ uint16 logon_count,
+ uint16 bad_pw_count,
+
+ uint32 user_id,
+ uint32 group_id,
+ uint32 num_groups,
+ DOM_GID *gids,
+ uint32 user_flgs,
+
+ char sess_key[16],
+
+ char *logon_srv,
+ char *logon_dom,
+
+ char *dom_sid,
+ char *other_sids)
+{
+ /* only cope with one "other" sid, right now. */
+ /* need to count the number of space-delimited sids */
+ int i;
+ int num_other_sids = 0;
+
+ int len_user_name = strlen(user_name );
+ int len_full_name = strlen(full_name );
+ int len_logon_script = strlen(logon_script);
+ int len_profile_path = strlen(profile_path);
+ int len_home_dir = strlen(home_dir );
+ int len_dir_drive = strlen(dir_drive );
+
+ int len_logon_srv = strlen(logon_srv);
+ int len_logon_dom = strlen(logon_dom);
+
+ usr->ptr_user_info = 1; /* yes, we're bothering to put USER_INFO data here */
+
+ 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 , 4);
+ make_uni_hdr(&(usr->hdr_full_name ), len_full_name , len_full_name , 4);
+ make_uni_hdr(&(usr->hdr_logon_script), len_logon_script, len_logon_script, 4);
+ make_uni_hdr(&(usr->hdr_profile_path), len_profile_path, len_profile_path, 4);
+ make_uni_hdr(&(usr->hdr_home_dir ), len_home_dir , len_home_dir , 4);
+ make_uni_hdr(&(usr->hdr_dir_drive ), len_dir_drive , len_dir_drive , 4);
+
+ usr->logon_count = logon_count;
+ usr->bad_pw_count = bad_pw_count;
+
+ usr->user_id = user_id;
+ usr->group_id = group_id;
+ usr->num_groups = num_groups;
+ usr->buffer_groups = 1; /* indicates fill in groups, below, even if there are none */
+ usr->user_flgs = user_flgs;
+
+ if (sess_key != NULL)
+ {
+ memcpy(usr->user_sess_key, sess_key, sizeof(usr->user_sess_key));
+ }
+ else
+ {
+ bzero(usr->user_sess_key, sizeof(usr->user_sess_key));
+ }
+
+ make_uni_hdr(&(usr->hdr_logon_srv), len_logon_srv, len_logon_srv, 4);
+ make_uni_hdr(&(usr->hdr_logon_dom), len_logon_dom, len_logon_dom, 4);
+
+ usr->buffer_dom_id = dom_sid ? 1 : 0; /* yes, we're bothering to put a domain SID in */
+
+ bzero(usr->padding, sizeof(usr->padding));
+
+ num_other_sids = make_dom_sid2s(other_sids, usr->other_sids, LSA_MAX_SIDS);
+
+ usr->num_other_sids = num_other_sids;
+ usr->buffer_other_sids = num_other_sids != 0 ? 1 : 0;
+
+ 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_logon_script), logon_script, len_logon_script);
+ make_unistr2(&(usr->uni_profile_path), profile_path, len_profile_path);
+ make_unistr2(&(usr->uni_home_dir ), home_dir , len_home_dir );
+ make_unistr2(&(usr->uni_dir_drive ), dir_drive , len_dir_drive );
+
+ usr->num_groups2 = num_groups;
+ for (i = 0; i < num_groups; i++)
+ {
+ usr->gids[i] = gids[i];
+ }
+
+ make_unistr2(&(usr->uni_logon_srv), logon_srv, len_logon_srv);
+ make_unistr2(&(usr->uni_logon_dom), logon_dom, len_logon_dom);
+
+ make_dom_sid2(&(usr->dom_sid), dom_sid);
+ /* "other" sids are set up above */
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void net_io_user_info3(char *desc, NET_USER_INFO_3 *usr, prs_struct *ps, int depth)
+{
+ int i;
+
+ if (usr == NULL) return;
+
+ prs_debug(ps, depth, desc, "lsa_io_lsa_user_info");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("ptr_user_info ", ps, depth, &(usr->ptr_user_info));
+
+ if (usr->ptr_user_info != 0)
+ {
+ smb_io_time("time", &(usr->logon_time) , ps, depth); /* logon time */
+ smb_io_time("time", &(usr->logoff_time) , ps, depth); /* logoff time */
+ smb_io_time("time", &(usr->kickoff_time) , ps, depth); /* kickoff time */
+ smb_io_time("time", &(usr->pass_last_set_time) , ps, depth); /* password last set time */
+ smb_io_time("time", &(usr->pass_can_change_time) , ps, depth); /* password can change time */
+ smb_io_time("time", &(usr->pass_must_change_time), ps, depth); /* password must change time */
+
+ smb_io_unihdr("unihdr", &(usr->hdr_user_name) , ps, depth); /* username unicode string header */
+ smb_io_unihdr("unihdr", &(usr->hdr_full_name) , ps, depth); /* user's full name unicode string header */
+ smb_io_unihdr("unihdr", &(usr->hdr_logon_script), ps, depth); /* logon script unicode string header */
+ smb_io_unihdr("unihdr", &(usr->hdr_profile_path), ps, depth); /* profile path unicode string header */
+ smb_io_unihdr("unihdr", &(usr->hdr_home_dir) , ps, depth); /* home directory unicode string header */
+ smb_io_unihdr("unihdr", &(usr->hdr_dir_drive) , ps, depth); /* home directory drive unicode string header */
+
+ prs_uint16("logon_count ", ps, depth, &(usr->logon_count )); /* logon count */
+ prs_uint16("bad_pw_count ", ps, depth, &(usr->bad_pw_count)); /* bad password count */
+
+ prs_uint32("user_id ", ps, depth, &(usr->user_id )); /* User ID */
+ prs_uint32("group_id ", ps, depth, &(usr->group_id )); /* Group ID */
+ prs_uint32("num_groups ", ps, depth, &(usr->num_groups )); /* num groups */
+ prs_uint32("buffer_groups ", ps, depth, &(usr->buffer_groups)); /* undocumented buffer pointer to groups. */
+ prs_uint32("user_flgs ", ps, depth, &(usr->user_flgs )); /* user flags */
+
+ prs_uint8s (False, "user_sess_key", ps, depth, usr->user_sess_key, 16); /* unused user session key */
+
+ smb_io_unihdr("unihdr", &(usr->hdr_logon_srv), ps, depth); /* logon server unicode string header */
+ smb_io_unihdr("unihdr", &(usr->hdr_logon_dom), ps, depth); /* logon domain unicode string header */
+
+ prs_uint32("buffer_dom_id ", ps, depth, &(usr->buffer_dom_id)); /* undocumented logon domain id pointer */
+ prs_uint8s (False, "padding ", ps, depth, usr->padding, 40); /* unused padding bytes? */
+
+ prs_uint32("num_other_sids", ps, depth, &(usr->num_other_sids)); /* 0 - num_sids */
+ prs_uint32("buffer_other_sids", ps, depth, &(usr->buffer_other_sids)); /* NULL - undocumented pointer to SIDs. */
+
+ smb_io_unistr2("unistr2", &(usr->uni_user_name) , usr->hdr_user_name .buffer, ps, depth); /* username unicode string */
+ smb_io_unistr2("unistr2", &(usr->uni_full_name) , usr->hdr_full_name .buffer, ps, depth); /* user's full name unicode string */
+ smb_io_unistr2("unistr2", &(usr->uni_logon_script), usr->hdr_logon_script.buffer, ps, depth); /* logon script unicode string */
+ smb_io_unistr2("unistr2", &(usr->uni_profile_path), usr->hdr_profile_path.buffer, ps, depth); /* profile path unicode string */
+ smb_io_unistr2("unistr2", &(usr->uni_home_dir) , usr->hdr_home_dir .buffer, ps, depth); /* home directory unicode string */
+ smb_io_unistr2("unistr2", &(usr->uni_dir_drive) , usr->hdr_dir_drive .buffer, ps, depth); /* home directory drive unicode string */
+
+ prs_align(ps);
+ prs_uint32("num_groups2 ", ps, depth, &(usr->num_groups2)); /* num groups */
+ for (i = 0; i < usr->num_groups2; i++)
+ {
+ smb_io_gid("", &(usr->gids[i]), ps, depth); /* group info */
+ }
+
+ smb_io_unistr2("unistr2", &( usr->uni_logon_srv), usr->hdr_logon_srv.buffer, ps, depth); /* logon server unicode string */
+ smb_io_unistr2("unistr2", &( usr->uni_logon_dom), usr->hdr_logon_srv.buffer, ps, depth); /* logon domain unicode string */
+
+ smb_io_dom_sid2("", &(usr->dom_sid), ps, depth); /* domain SID */
+
+ for (i = 0; i < usr->num_other_sids; i++)
+ {
+ smb_io_dom_sid2("", &(usr->other_sids[i]), ps, depth); /* other domain SIDs */
+ }
+ }
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void net_io_q_sam_logon(char *desc, NET_Q_SAM_LOGON *q_l, prs_struct *ps, int depth)
+{
+ if (q_l == NULL) return;
+
+ prs_debug(ps, depth, desc, "net_io_q_sam_logon");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_sam_info("", &(q_l->sam_id), ps, depth); /* domain SID */
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void net_io_r_sam_logon(char *desc, NET_R_SAM_LOGON *r_l, prs_struct *ps, int depth)
+{
+ if (r_l == NULL) return;
+
+ prs_debug(ps, depth, desc, "net_io_r_sam_logon");
+ depth++;
+
+ prs_uint32("buffer_creds", ps, depth, &(r_l->buffer_creds)); /* undocumented buffer pointer */
+ smb_io_cred("", &(r_l->srv_creds), ps, depth); /* server credentials. server time stamp appears to be ignored. */
+
+ prs_uint16("switch_value", ps, depth, &(r_l->switch_value));
+ prs_align(ps);
+
+ if (r_l->switch_value != 0)
+ {
+ net_io_user_info3("", r_l->user, ps, depth);
+ }
+
+ prs_uint32("auth_resp ", ps, depth, &(r_l->auth_resp)); /* 1 - Authoritative response; 0 - Non-Auth? */
+
+ prs_uint32("status ", ps, depth, &(r_l->status));
+
+ prs_align(ps);
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void net_io_q_sam_logoff(char *desc, NET_Q_SAM_LOGOFF *q_l, prs_struct *ps, int depth)
+{
+ if (q_l == NULL) return;
+
+ prs_debug(ps, depth, desc, "net_io_q_sam_logoff");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_sam_info("", &(q_l->sam_id), ps, depth); /* domain SID */
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void net_io_r_sam_logoff(char *desc, NET_R_SAM_LOGOFF *r_l, prs_struct *ps, int depth)
+{
+ if (r_l == NULL) return;
+
+ prs_debug(ps, depth, desc, "net_io_r_sam_logoff");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("buffer_creds", ps, depth, &(r_l->buffer_creds)); /* undocumented buffer pointer */
+ smb_io_cred("", &(r_l->srv_creds), ps, depth); /* server credentials. server time stamp appears to be ignored. */
+
+ prs_uint32("status ", ps, depth, &(r_l->status));
+}
+
+
diff --git a/source3/rpc_parse/parse_prs.c b/source3/rpc_parse/parse_prs.c
new file mode 100644
index 0000000000..799bd1cc94
--- /dev/null
+++ b/source3/rpc_parse/parse_prs.c
@@ -0,0 +1,290 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Samba memory buffer functions
+ Copyright (C) Andrew Tridgell 1992-1997
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1997
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+extern int DEBUGLEVEL;
+
+#include "includes.h"
+
+
+/*******************************************************************
+ debug output for parsing info.
+
+ XXXX side-effect of this function is to increase the debug depth XXXX
+
+ ********************************************************************/
+void prs_debug(prs_struct *ps, int depth, char *desc, char *fn_name)
+{
+ DEBUG(5+depth, ("%s%06x %s %s\n", tab_depth(depth), ps->offset, fn_name, desc));
+}
+
+/*******************************************************************
+ initialise a parse structure
+ ********************************************************************/
+void prs_init(prs_struct *ps, uint32 size,
+ uint8 align, uint32 margin,
+ BOOL io)
+{
+ ps->io = io;
+ ps->align = align;
+ ps->offset = 0;
+
+ ps->data = NULL;
+ mem_buf_init(&(ps->data), margin);
+
+ if (size != 0)
+ {
+ mem_alloc_data(ps->data, size);
+ ps->data->offset.start = 0;
+ ps->data->offset.end = 0xffffffff;
+ }
+}
+
+/*******************************************************************
+ initialise a parse structure
+ ********************************************************************/
+void prs_mem_free(prs_struct *ps)
+{
+ mem_buf_free(&(ps->data));
+}
+
+/*******************************************************************
+ align a pointer to a multiple of align_offset bytes. looks like it
+ will work for offsets of 0, 2 and 4...
+ ********************************************************************/
+void prs_align(prs_struct *ps)
+{
+ int mod = ps->offset & (ps->align-1);
+ if (ps->align != 0 && mod != 0)
+ {
+ ps->offset += ps->align - mod;
+ }
+}
+
+/*******************************************************************
+ attempt, if appropriate, to grow a data buffer.
+
+ depends on the data stream mode (io)
+ ********************************************************************/
+BOOL prs_grow(prs_struct *ps)
+{
+ return mem_grow_data(&(ps->data), ps->io, ps->offset);
+}
+
+
+/*******************************************************************
+ stream a uint8
+ ********************************************************************/
+BOOL prs_uint8(char *name, prs_struct *ps, int depth, uint8 *data8)
+{
+ char *q = mem_data(&(ps->data), ps->offset);
+ if (q == NULL) return False;
+
+ DBG_RW_CVAL(name, depth, ps->offset, ps->io, q, *data8)
+ ps->offset += 1;
+
+ return True;
+}
+
+/*******************************************************************
+ stream a uint16
+ ********************************************************************/
+BOOL prs_uint16(char *name, prs_struct *ps, int depth, uint16 *data16)
+{
+ char *q = mem_data(&(ps->data), ps->offset);
+ if (q == NULL) return False;
+
+ DBG_RW_SVAL(name, depth, ps->offset, ps->io, q, *data16)
+ ps->offset += 2;
+
+ return True;
+}
+
+/*******************************************************************
+ stream a uint32
+ ********************************************************************/
+BOOL prs_uint32(char *name, prs_struct *ps, int depth, uint32 *data32)
+{
+ char *q = mem_data(&(ps->data), ps->offset);
+ if (q == NULL) return False;
+
+ DBG_RW_IVAL(name, depth, ps->offset, ps->io, q, *data32)
+ ps->offset += 4;
+
+ return True;
+}
+
+
+/******************************************************************
+ stream an array of uint8s. length is number of uint8s
+ ********************************************************************/
+BOOL prs_uint8s(BOOL charmode, char *name, prs_struct *ps, int depth, uint8 *data8s, int len)
+{
+ char *q = mem_data(&(ps->data), ps->offset);
+ if (q == NULL) return False;
+
+ DBG_RW_PCVAL(charmode, name, depth, ps->offset, ps->io, q, data8s, len)
+ ps->offset += len;
+
+ return True;
+}
+
+/******************************************************************
+ stream an array of uint16s. length is number of uint16s
+ ********************************************************************/
+BOOL prs_uint16s(BOOL charmode, char *name, prs_struct *ps, int depth, uint16 *data16s, int len)
+{
+ char *q = mem_data(&(ps->data), ps->offset);
+ if (q == NULL) return False;
+
+ DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, q, data16s, len)
+ ps->offset += len * sizeof(uint16);
+
+ return True;
+}
+
+/******************************************************************
+ stream an array of uint32s. length is number of uint32s
+ ********************************************************************/
+BOOL prs_uint32s(BOOL charmode, char *name, prs_struct *ps, int depth, uint32 *data32s, int len)
+{
+ char *q = mem_data(&(ps->data), ps->offset);
+ if (q == NULL) return False;
+
+ DBG_RW_PIVAL(charmode, name, depth, ps->offset, ps->io, q, data32s, len)
+ ps->offset += len * sizeof(uint32);
+
+ return True;
+}
+
+/******************************************************************
+ stream a "not" unicode string, length/buffer specified separately,
+ in byte chars
+ ********************************************************************/
+BOOL prs_uninotstr2(BOOL charmode, char *name, prs_struct *ps, int depth, UNINOTSTR2 *str)
+{
+ char *q = mem_data(&(ps->data), ps->offset);
+ if (q == NULL) return False;
+
+ DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, q, str->buffer, str->uni_max_len)
+ ps->offset += str->uni_buf_len;
+
+ return True;
+}
+
+/******************************************************************
+ stream a string, length/buffer specified separately,
+ in uint8 chars.
+ ********************************************************************/
+BOOL prs_string2(BOOL charmode, char *name, prs_struct *ps, int depth, STRING2 *str)
+{
+ char *q = mem_data(&(ps->data), ps->offset);
+ if (q == NULL) return False;
+
+ DBG_RW_PCVAL(charmode, name, depth, ps->offset, ps->io, q, str->buffer, str->str_max_len)
+ ps->offset += str->str_str_len * sizeof(uint8);
+
+ return True;
+}
+
+/******************************************************************
+ stream a unicode string, length/buffer specified separately,
+ in uint16 chars.
+ ********************************************************************/
+BOOL prs_unistr2(BOOL charmode, char *name, prs_struct *ps, int depth, UNISTR2 *str)
+{
+ char *q = mem_data(&(ps->data), ps->offset);
+ if (q == NULL) return False;
+
+ DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, q, str->buffer, str->uni_max_len)
+ ps->offset += str->uni_str_len * sizeof(uint16);
+
+ return True;
+}
+
+/*******************************************************************
+ stream a unicode null-terminated string
+ ********************************************************************/
+BOOL prs_unistr(char *name, prs_struct *ps, int depth, UNISTR *str)
+{
+ char *q = mem_data(&(ps->data), ps->offset);
+ int i = 0;
+ uint8 *start = (uint8*)q;
+
+ if (q == NULL) return False;
+
+ do
+ {
+ RW_SVAL(ps->io, q, str->buffer[i],0);
+ q += 2;
+ i++;
+
+ } while ((i < sizeof(str->buffer) / sizeof(str->buffer[0])) &&
+ (str->buffer[i] != 0));
+
+ ps->offset += i*2;
+
+ dump_data(5+depth, start, ps->offset);
+
+ return True;
+}
+
+/*******************************************************************
+ stream a null-terminated string. len is strlen, and therefore does
+ not include the null-termination character.
+
+ len == 0 indicates variable length string
+ (up to max size of pstring - 1024 chars).
+
+ ********************************************************************/
+BOOL prs_string(char *name, prs_struct *ps, int depth, char *str, uint16 len)
+{
+ char *q = mem_data(&(ps->data), ps->offset);
+ uint8 *start = (uint8*)q;
+ int i = -1; /* start off at zero after 1st i++ */
+
+ if (q == NULL) return False;
+
+ do
+ {
+ i++;
+
+ if (i < len || len == 0)
+ {
+ RW_CVAL(ps->io, q, str[i],0);
+ }
+ else
+ {
+ uint8 dummy = 0;
+ RW_CVAL(ps->io, q, dummy,0);
+ }
+
+ q++;
+
+ } while (i < sizeof(pstring) && (len == 0 ? str[i] != 0 : i < len) );
+
+ ps->offset += i+1;
+
+ dump_data(5+depth, start, ps->offset);
+
+ return True;
+}
+
diff --git a/source3/rpc_parse/parse_reg.c b/source3/rpc_parse/parse_reg.c
new file mode 100644
index 0000000000..d278b75f5d
--- /dev/null
+++ b/source3/rpc_parse/parse_reg.c
@@ -0,0 +1,335 @@
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-1997,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ * Copyright (C) Paul Ashton 1997.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+
+extern int DEBUGLEVEL;
+
+
+/*******************************************************************
+creates a structure.
+********************************************************************/
+void make_reg_q_open_policy(REG_Q_OPEN_POLICY *r_q,
+ uint16 unknown_0, uint32 level, uint16 unknown_1)
+{
+ r_q->ptr = 1;
+ r_q->unknown_0 = unknown_0;
+ r_q->level = level;
+ r_q->unknown_1 = unknown_1;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void reg_io_q_open_policy(char *desc, REG_Q_OPEN_POLICY *r_q, prs_struct *ps, int depth)
+{
+ if (r_q == NULL) return;
+
+ prs_debug(ps, depth, desc, "reg_io_q_open_policy");
+ 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_uint32("level ", ps, depth, &(r_q->level ));
+ prs_uint16("unknown_1", ps, depth, &(r_q->unknown_1));
+ }
+}
+
+
+/*******************************************************************
+creates a structure.
+********************************************************************/
+void make_reg_r_open_policy(REG_R_OPEN_POLICY *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_policy(char *desc, REG_R_OPEN_POLICY *r_r, prs_struct *ps, int depth)
+{
+ if (r_r == NULL) return;
+
+ prs_debug(ps, depth, desc, "reg_io_r_open_policy");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("", &(r_r->pol), ps, depth);
+
+ prs_uint32("status", ps, depth, &(r_r->status));
+}
+
+
+/*******************************************************************
+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));
+}
+/*******************************************************************
+creates a structure.
+********************************************************************/
+void make_reg_q_info(REG_Q_INFO *r_q,
+ POLICY_HND *pol, char *product_type,
+ NTTIME *prod_time, uint8 major_version, uint8 minor_version,
+ uint32 unknown)
+{
+ int type_len = strlen(product_type);
+
+ memcpy(&(r_q->pol), pol, sizeof(r_q->pol));
+ make_uni_hdr(&(r_q->hdr_type), type_len, type_len, 1);
+ make_unistr2(&(r_q->uni_type), product_type, type_len);
+
+ r_q->ptr1 = 1;
+ memcpy(&(r_q->time), prod_time, sizeof(r_q->time));
+ r_q->major_version1 = major_version;
+ r_q->minor_version1 = minor_version;
+ bzero(&(r_q->pad1), sizeof(r_q->pad1));
+
+ r_q->ptr2 = 1;
+ r_q->major_version2 = major_version;
+ r_q->minor_version2 = minor_version;
+ bzero(&(r_q->pad2), sizeof(r_q->pad2));
+
+ r_q->ptr3 = 1;
+ r_q->unknown = unknown;
+}
+
+/*******************************************************************
+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_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)
+{
+ int type_len = strlen(os_type);
+
+ r_r->ptr1 = 1;
+ r_r->level = level;
+
+ r_r->ptr_type = 1;
+ make_uninotstr2(&(r_r->uni_type), os_type, type_len);
+
+ 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_uninotstr2("", &(r_r->uni_type), r_r->ptr_type, ps, depth);
+ prs_align(ps);
+
+ 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));
+}
+
+
+/*******************************************************************
+creates a structure.
+********************************************************************/
+void make_reg_q_open_entry(REG_Q_OPEN_ENTRY *r_q,
+ POLICY_HND *pol, char *name,
+ uint32 unknown_0, uint32 unknown_1, uint16 unknown_2)
+{
+ int len_name = strlen(name);
+
+ 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), name, len_name);
+
+ r_q->unknown_0 = unknown_0;
+ r_q->unknown_1 = unknown_1;
+ r_q->unknown_2 = unknown_2;
+}
+
+/*******************************************************************
+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_uint32("unknown_0", ps, depth, &(r_q->unknown_0));
+ prs_uint16("unknown_1", ps, depth, &(r_q->unknown_1));
+ prs_uint16("unknown_2", ps, depth, &(r_q->unknown_2));
+}
+
+
+/*******************************************************************
+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));
+}
+
diff --git a/source3/rpc_parse/parse_rpc.c b/source3/rpc_parse/parse_rpc.c
new file mode 100644
index 0000000000..b025d3f1c8
--- /dev/null
+++ b/source3/rpc_parse/parse_rpc.c
@@ -0,0 +1,528 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-1997,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ * Copyright (C) Paul Ashton 1997.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+
+extern int DEBUGLEVEL;
+
+
+/*******************************************************************
+interface/version dce/rpc pipe identification
+********************************************************************/
+
+#define TRANS_SYNT_V2 \
+{ \
+ { \
+ 0x04, 0x5d, 0x88, 0x8a, \
+ 0xeb, 0x1c, 0xc9, 0x11, \
+ 0x9f, 0xe8, 0x08, 0x00, \
+ 0x2b, 0x10, 0x48, 0x60 \
+ }, 0x02 \
+} \
+
+#define SYNT_NETLOGON_V2 \
+{ \
+ { \
+ 0x04, 0x5d, 0x88, 0x8a, \
+ 0xeb, 0x1c, 0xc9, 0x11, \
+ 0x9f, 0xe8, 0x08, 0x00, \
+ 0x2b, 0x10, 0x48, 0x60 \
+ }, 0x02 \
+} \
+
+#define SYNT_WKSSVC_V1 \
+{ \
+ { \
+ 0x98, 0xd0, 0xff, 0x6b, \
+ 0x12, 0xa1, 0x10, 0x36, \
+ 0x98, 0x33, 0x46, 0xc3, \
+ 0xf8, 0x7e, 0x34, 0x5a \
+ }, 0x01 \
+} \
+
+#define SYNT_SRVSVC_V3 \
+{ \
+ { \
+ 0xc8, 0x4f, 0x32, 0x4b, \
+ 0x70, 0x16, 0xd3, 0x01, \
+ 0x12, 0x78, 0x5a, 0x47, \
+ 0xbf, 0x6e, 0xe1, 0x88 \
+ }, 0x03 \
+} \
+
+#define SYNT_LSARPC_V0 \
+{ \
+ { \
+ 0x78, 0x57, 0x34, 0x12, \
+ 0x34, 0x12, 0xcd, 0xab, \
+ 0xef, 0x00, 0x01, 0x23, \
+ 0x45, 0x67, 0x89, 0xab \
+ }, 0x00 \
+} \
+
+#define SYNT_SAMR_V1 \
+{ \
+ { \
+ 0x78, 0x57, 0x34, 0x12, \
+ 0x34, 0x12, 0xcd, 0xab, \
+ 0xef, 0x00, 0x01, 0x23, \
+ 0x45, 0x67, 0x89, 0xac \
+ }, 0x01 \
+} \
+
+#define SYNT_NETLOGON_V1 \
+{ \
+ { \
+ 0x78, 0x56, 0x34, 0x12, \
+ 0x34, 0x12, 0xcd, 0xab, \
+ 0xef, 0x00, 0x01, 0x23, \
+ 0x45, 0x67, 0xcf, 0xfb \
+ }, 0x01 \
+} \
+
+#define SYNT_WINREG_V1 \
+{ \
+ { \
+ 0x01, 0xd0, 0x8c, 0x33, \
+ 0x44, 0x22, 0xf1, 0x31, \
+ 0xaa, 0xaa, 0x90, 0x00, \
+ 0x38, 0x00, 0x10, 0x03 \
+ }, 0x01 \
+} \
+
+#define SYNT_NONE_V0 \
+{ \
+ { \
+ 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x00 \
+ }, 0x00 \
+} \
+
+/* pipe string names */
+#define PIPE_SRVSVC "\\PIPE\\srvsvc"
+#define PIPE_SAMR "\\PIPE\\samr"
+#define PIPE_WINREG "\\PIPE\\winreg"
+#define PIPE_WKSSVC "\\PIPE\\wkssvc"
+#define PIPE_NETLOGON "\\PIPE\\NETLOGON"
+#define PIPE_NTLSA "\\PIPE\\ntlsa"
+#define PIPE_NTSVCS "\\PIPE\\ntsvcs"
+#define PIPE_LSASS "\\PIPE\\lsass"
+#define PIPE_LSARPC "\\PIPE\\lsarpc"
+
+struct pipe_id_info pipe_names [] =
+{
+ /* client pipe , abstract syntax , server pipe , transfer syntax */
+ { PIPE_LSARPC , SYNT_LSARPC_V0 , PIPE_LSASS , TRANS_SYNT_V2 },
+ { PIPE_SAMR , SYNT_SAMR_V1 , PIPE_LSASS , TRANS_SYNT_V2 },
+ { PIPE_NETLOGON, SYNT_NETLOGON_V1, PIPE_LSASS , TRANS_SYNT_V2 },
+ { PIPE_SRVSVC , SYNT_SRVSVC_V3 , PIPE_NTSVCS , TRANS_SYNT_V2 },
+ { PIPE_WKSSVC , SYNT_WKSSVC_V1 , PIPE_NTSVCS , TRANS_SYNT_V2 },
+ { PIPE_WINREG , SYNT_WINREG_V1 , PIPE_WINREG , TRANS_SYNT_V2 },
+ { NULL , SYNT_NONE_V0 , NULL , SYNT_NONE_V0 }
+};
+
+/*******************************************************************
+creates an RPC_HDR structure.
+********************************************************************/
+void make_rpc_hdr(RPC_HDR *hdr, enum RPC_PKT_TYPE pkt_type, uint8 flags,
+ uint32 call_id, int data_len, int auth_len)
+{
+ if (hdr == NULL) return;
+
+ hdr->major = 5; /* RPC version 5 */
+ hdr->minor = 0; /* minor version 0 */
+ hdr->pkt_type = pkt_type; /* RPC packet type */
+ hdr->flags = flags; /* dce/rpc flags */
+ hdr->pack_type = 0x10; /* packed data representation */
+ hdr->frag_len = data_len; /* fragment length, fill in later */
+ hdr->auth_len = auth_len; /* authentication length */
+ hdr->call_id = call_id; /* call identifier - match incoming RPC */
+}
+
+/*******************************************************************
+reads or writes an RPC_HDR structure.
+********************************************************************/
+void smb_io_rpc_hdr(char *desc, RPC_HDR *rpc, prs_struct *ps, int depth)
+{
+ if (rpc == NULL) return;
+
+ prs_debug(ps, depth, desc, "smb_io_rpc_hdr");
+ depth++;
+
+ prs_uint8 ("major ", ps, depth, &(rpc->major));
+ prs_uint8 ("minor ", ps, depth, &(rpc->minor));
+ prs_uint8 ("pkt_type ", ps, depth, &(rpc->pkt_type));
+ prs_uint8 ("flags ", ps, depth, &(rpc->flags));
+ prs_uint32("pack_type ", ps, depth, &(rpc->pack_type));
+ prs_uint16("frag_len ", ps, depth, &(rpc->frag_len));
+ prs_uint16("auth_len ", ps, depth, &(rpc->auth_len));
+ prs_uint32("call_id ", ps, depth, &(rpc->call_id));
+}
+
+/*******************************************************************
+creates an RPC_IFACE structure.
+********************************************************************/
+void make_rpc_iface(RPC_IFACE *ifc, char data[16], uint32 version)
+{
+ if (ifc == NULL || data == NULL) return;
+
+ memcpy(ifc->data, data, sizeof(ifc->data)); /* 16 bytes of number */
+ ifc->version = version; /* the interface number */
+}
+
+/*******************************************************************
+reads or writes an RPC_IFACE structure.
+********************************************************************/
+void smb_io_rpc_iface(char *desc, RPC_IFACE *ifc, prs_struct *ps, int depth)
+{
+ if (ifc == NULL) return;
+
+ prs_debug(ps, depth, desc, "smb_io_rpc_iface");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint8s (False, "data ", ps, depth, ifc->data, sizeof(ifc->data));
+ prs_uint32 ( "version", ps, depth, &(ifc->version));
+}
+
+/*******************************************************************
+creates an RPC_ADDR_STR structure.
+********************************************************************/
+void make_rpc_addr_str(RPC_ADDR_STR *str, char *name)
+{
+ if (str == NULL || name == NULL) return;
+
+ str->len = strlen(name) + 1;
+ fstrcpy(str->str, name);
+}
+
+/*******************************************************************
+reads or writes an RPC_ADDR_STR structure.
+********************************************************************/
+void smb_io_rpc_addr_str(char *desc, RPC_ADDR_STR *str, prs_struct *ps, int depth)
+{
+ if (str == NULL) return;
+
+ prs_debug(ps, depth, desc, "smb_io_rpc_addr_str");
+ depth++;
+ prs_align(ps);
+
+ prs_uint16 ( "len", ps, depth, &(str->len));
+ prs_uint8s (True, "str", ps, depth, (uchar*)str->str, str->len);
+}
+
+/*******************************************************************
+creates an RPC_HDR_BBA structure.
+********************************************************************/
+void make_rpc_hdr_bba(RPC_HDR_BBA *bba, uint16 max_tsize, uint16 max_rsize, uint32 assoc_gid)
+{
+ if (bba == NULL) return;
+
+ bba->max_tsize = max_tsize; /* maximum transmission fragment size (0x1630) */
+ bba->max_rsize = max_rsize; /* max receive fragment size (0x1630) */
+ bba->assoc_gid = assoc_gid; /* associated group id (0x0) */
+}
+
+/*******************************************************************
+reads or writes an RPC_HDR_BBA structure.
+********************************************************************/
+void smb_io_rpc_hdr_bba(char *desc, RPC_HDR_BBA *rpc, prs_struct *ps, int depth)
+{
+ if (rpc == NULL) return;
+
+ prs_debug(ps, depth, desc, "smb_io_rpc_hdr_bba");
+ depth++;
+
+ prs_uint16("max_tsize", ps, depth, &(rpc->max_tsize));
+ prs_uint16("max_rsize", ps, depth, &(rpc->max_rsize));
+ prs_uint32("assoc_gid", ps, depth, &(rpc->assoc_gid));
+}
+
+/*******************************************************************
+creates an RPC_HDR_RB structure.
+********************************************************************/
+void make_rpc_hdr_rb(RPC_HDR_RB *rpc,
+ uint16 max_tsize, uint16 max_rsize, uint32 assoc_gid,
+ uint32 num_elements, uint16 context_id, uint8 num_syntaxes,
+ RPC_IFACE *abstract, RPC_IFACE *transfer)
+{
+ if (rpc == NULL) return;
+
+ make_rpc_hdr_bba(&(rpc->bba), max_tsize, max_rsize, assoc_gid);
+
+ rpc->num_elements = num_elements ; /* the number of elements (0x1) */
+ rpc->context_id = context_id ; /* presentation context identifier (0x0) */
+ rpc->num_syntaxes = num_syntaxes ; /* the number of syntaxes (has always been 1?)(0x1) */
+
+ /* num and vers. of interface client is using */
+ memcpy(&(rpc->abstract), abstract, sizeof(rpc->abstract));
+
+ /* num and vers. of interface to use for replies */
+ memcpy(&(rpc->transfer), transfer, sizeof(rpc->transfer));
+}
+
+/*******************************************************************
+reads or writes an RPC_HDR_RB structure.
+********************************************************************/
+void smb_io_rpc_hdr_rb(char *desc, RPC_HDR_RB *rpc, prs_struct *ps, int depth)
+{
+ if (rpc == NULL) return;
+
+ prs_debug(ps, depth, desc, "smb_io_rpc_hdr_rb");
+ depth++;
+
+ smb_io_rpc_hdr_bba("", &(rpc->bba), ps, depth);
+
+ prs_uint32("num_elements", ps, depth, &(rpc->num_elements));
+ prs_uint16("context_id ", ps, depth, &(rpc->context_id ));
+ prs_uint8 ("num_syntaxes", ps, depth, &(rpc->num_syntaxes));
+
+ smb_io_rpc_iface("", &(rpc->abstract), ps, depth);
+ smb_io_rpc_iface("", &(rpc->transfer), ps, depth);
+}
+
+/*******************************************************************
+creates an RPC_RESULTS structure.
+
+lkclXXXX only one reason at the moment!
+
+********************************************************************/
+void make_rpc_results(RPC_RESULTS *res,
+ uint8 num_results, uint16 result, uint16 reason)
+{
+ if (res == NULL) return;
+
+ res->num_results = num_results; /* the number of results (0x01) */
+ res->result = result ; /* result (0x00 = accept) */
+ res->reason = reason ; /* reason (0x00 = no reason specified) */
+}
+
+/*******************************************************************
+reads or writes an RPC_RESULTS structure.
+
+lkclXXXX only one reason at the moment!
+
+********************************************************************/
+void smb_io_rpc_results(char *desc, RPC_RESULTS *res, prs_struct *ps, int depth)
+{
+ if (res == NULL) return;
+
+ prs_debug(ps, depth, desc, "smb_io_rpc_results");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint8 ("num_results", ps, depth, &(res->num_results));
+
+ prs_align(ps);
+
+ prs_uint16("result ", ps, depth, &(res->result ));
+ prs_uint16("reason ", ps, depth, &(res->reason ));
+}
+
+/*******************************************************************
+creates an RPC_HDR_BA structure.
+
+lkclXXXX only one reason at the moment!
+
+********************************************************************/
+void make_rpc_hdr_ba(RPC_HDR_BA *rpc,
+ uint16 max_tsize, uint16 max_rsize, uint32 assoc_gid,
+ char *pipe_addr,
+ uint8 num_results, uint16 result, uint16 reason,
+ RPC_IFACE *transfer)
+{
+ if (rpc == NULL || transfer == NULL || pipe_addr == NULL) return;
+
+ make_rpc_hdr_bba (&(rpc->bba ), max_tsize, max_rsize, assoc_gid);
+ make_rpc_addr_str(&(rpc->addr), pipe_addr);
+ make_rpc_results (&(rpc->res ), num_results, result, reason);
+
+ /* the transfer syntax from the request */
+ memcpy(&(rpc->transfer), transfer, sizeof(rpc->transfer));
+}
+
+/*******************************************************************
+reads or writes an RPC_HDR_BA structure.
+********************************************************************/
+void smb_io_rpc_hdr_ba(char *desc, RPC_HDR_BA *rpc, prs_struct *ps, int depth)
+{
+ if (rpc == NULL) return;
+
+ prs_debug(ps, depth, desc, "smb_io_rpc_hdr_ba");
+ depth++;
+
+ smb_io_rpc_hdr_bba ("", &(rpc->bba) , ps, depth);
+ smb_io_rpc_addr_str("", &(rpc->addr) , ps, depth);
+ smb_io_rpc_results ("", &(rpc->res) , ps, depth);
+ smb_io_rpc_iface ("", &(rpc->transfer), ps, depth);
+}
+
+/*******************************************************************
+creates an RPC_HDR_RR structure.
+********************************************************************/
+void make_rpc_hdr_rr(RPC_HDR_RR *hdr, uint32 data_len, uint8 opnum)
+{
+ if (hdr == NULL) return;
+
+ hdr->alloc_hint = data_len - 0x18; /* allocation hint */
+ hdr->context_id = 0; /* presentation context identifier */
+ hdr->cancel_count = 0; /* cancel count */
+ hdr->opnum = opnum; /* opnum */
+ hdr->reserved = 0; /* 0 - reserved */
+}
+
+/*******************************************************************
+reads or writes an RPC_HDR_RR structure.
+********************************************************************/
+void smb_io_rpc_hdr_rr(char *desc, RPC_HDR_RR *rpc, prs_struct *ps, int depth)
+{
+ if (rpc == NULL) return;
+
+ prs_debug(ps, depth, desc, "smb_io_rpc_hdr_rr");
+ depth++;
+
+ prs_uint32("alloc_hint", ps, depth, &(rpc->alloc_hint));
+ prs_uint8 ("context_id", ps, depth, &(rpc->context_id));
+ prs_uint8 ("cancel_ct ", ps, depth, &(rpc->cancel_count));
+ prs_uint8 ("opnum ", ps, depth, &(rpc->opnum));
+ prs_uint8 ("reserved ", ps, depth, &(rpc->reserved));
+}
+
+/*******************************************************************
+creates an RPC_AUTH_NTLMSSP_REQ structure.
+********************************************************************/
+void make_rpc_auth_ntlmssp_req(RPC_AUTH_NTLMSSP_REQ *req,
+ fstring ntlmssp_str, uint32 ntlmssp_ver,
+ uint32 unknown_0, fstring myname, fstring domain)
+{
+ int len_myname = strlen(myname);
+ int len_domain = strlen(domain);
+
+ if (req == NULL) return;
+
+ fstrcpy(req->ntlmssp_str, ntlmssp_str); /* "NTLMSSP" */
+ req->ntlmssp_ver = ntlmssp_ver; /* 0x0000 0001 */
+
+ req->unknown_0 = unknown_0 ; /* 0x00b2b3 */
+ make_str_hdr(&req->hdr_myname, len_myname, len_myname, 1);
+ make_str_hdr(&req->hdr_domain, len_domain, len_domain, 1);
+
+ fstrcpy(req->myname, myname);
+ fstrcpy(req->domain, domain);
+}
+
+/*******************************************************************
+reads or writes an RPC_AUTH_NTLMSSP_REQ structure.
+********************************************************************/
+void smb_io_rpc_auth_ntlmssp_req(char *desc, RPC_AUTH_NTLMSSP_REQ *req, prs_struct *ps, int depth)
+{
+ if (req == NULL) return;
+
+ prs_debug(ps, depth, desc, "smb_io_rpc_auth_ntlmssp_req");
+ depth++;
+
+ prs_string("ntlmssp_str", ps, depth, req->ntlmssp_str, 0); /* "NTLMSSP" */
+ prs_uint32("ntlmssp_ver", ps, depth, &(req->ntlmssp_ver ));
+
+ prs_uint32("unknown_0 ", ps, depth, &(req->unknown_0 ));
+ smb_io_strhdr("hdr_myname", &(req->hdr_myname), ps, depth);
+ smb_io_strhdr("hdr_domain", &(req->hdr_domain), ps, depth);
+
+ prs_string("myname", ps, depth, req->myname, req->hdr_myname.str_str_len);
+ prs_string("domain", ps, depth, req->domain, req->hdr_domain.str_str_len);
+}
+
+/*******************************************************************
+creates an RPC_AUTH_NTLMSSP_RESP structure.
+********************************************************************/
+void make_rpc_auth_ntlmssp_resp(RPC_AUTH_NTLMSSP_RESP *rsp,
+ uint8 auth_type, uint8 auth_level, uint8 stub_type_len,
+ fstring ntlmssp_str, uint32 ntlmssp_ver,
+ uint32 unknown_1, uint32 unknown_2, uint32 unknown_3,
+ uint8 data[16])
+{
+ if (rsp == NULL) return;
+
+ rsp->auth_type = auth_type; /* nt lm ssp 0x0a */
+ rsp->auth_level = auth_level; /* 0x06 */
+ rsp->stub_type_len = stub_type_len; /* dunno. */
+ rsp->padding = 0; /* padding */
+
+ rsp->ptr_0 = 1; /* non-zero pointer to something */
+
+ fstrcpy(rsp->ntlmssp_str, ntlmssp_str); /* "NTLMSSP" */
+ rsp->ntlmssp_ver = ntlmssp_ver; /* 0x0000 0002 */
+
+ rsp->unknown_1 = unknown_1; /* 0x0000 0000 */
+ rsp->unknown_2 = unknown_2; /* 0x00b2b3 */
+ rsp->unknown_3 = unknown_3; /* 0x0082b1 */
+
+ memcpy(rsp->data, data, sizeof(rsp->data)); /* 0x10 bytes of something, 8 of which are zeros */
+}
+
+/*******************************************************************
+reads or writes an RPC_AUTH_NTLMSSP_RESP structure.
+********************************************************************/
+void smb_io_rpc_auth_ntlmssp_resp(char *desc, RPC_AUTH_NTLMSSP_RESP *rsp, prs_struct *ps, int depth)
+{
+ if (rsp == NULL) return;
+
+ prs_debug(ps, depth, desc, "smb_io_rpc_auth_ntlmssp_resp");
+ depth++;
+
+ prs_uint8("auth_type", ps, depth, &(rsp->auth_type)); /* nt lm ssp 0x0a */
+ prs_uint8("auth_level", ps, depth, &(rsp->auth_level));/* 0x06 */
+ prs_uint8("stub_type_len", ps, depth, &(rsp->stub_type_len));
+ prs_uint8("padding", ps, depth, &(rsp->padding));
+
+ prs_uint32("ptr_0", ps, depth, &(rsp->ptr_0 )); /* non-zero pointer to something */
+
+ prs_string("ntlmssp_str", ps, depth, rsp->ntlmssp_str, 0); /* "NTLMSSP" */
+ prs_uint32("ntlmssp_ver", ps, depth, &(rsp->ntlmssp_ver )); /* 0x0000 0002 */
+
+ prs_uint32("unknown_1", ps, depth, &(rsp->unknown_1)); /* 0x0000 0000 */
+ prs_uint32("unknown_2", ps, depth, &(rsp->unknown_2)); /* 0x00b2b3 */
+ prs_uint32("unknown_3", ps, depth, &(rsp->unknown_3)); /* 0x0082b1 */
+
+ prs_uint8s (False, "data", ps, depth, rsp->data, sizeof(rsp->data));
+}
+
+#if 0
+
+/* attached to the end of encrypted rpc requests and responses */
+/* RPC_AUTH_NTLMSSP_CHK */
+typedef struct rpc_auth_ntlmssp_chk_info
+{
+ uint32 ver; /* 0x1 */
+ uint8 data[12];
+
+} RPC_AUTH_NTLMSSP_CHK;
+
+#endif /* 0 */
+
diff --git a/source3/rpc_parse/parse_samr.c b/source3/rpc_parse/parse_samr.c
new file mode 100644
index 0000000000..a72769d9c0
--- /dev/null
+++ b/source3/rpc_parse/parse_samr.c
@@ -0,0 +1,2796 @@
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-1997,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ * Copyright (C) Paul Ashton 1997.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#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, char *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_8(SAMR_Q_UNKNOWN_8 *q_u,
+ POLICY_HND *domain_pol, uint16 switch_value)
+{
+ if (q_u == NULL) return;
+
+ DEBUG(5,("samr_make_q_unknown_8\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_unknown_8(char *desc, SAMR_Q_UNKNOWN_8 *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_q_unknown_8");
+ 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);
+}
+
+/*******************************************************************
+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);
+}
+
+/*******************************************************************
+ 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, char *sid)
+{
+ if (sid3 == NULL) return;
+
+ make_dom_sid(&(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 :-)
+
+********************************************************************/
+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
+
+********************************************************************/
+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;
+
+ bzero(stf->padding1, 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.
+********************************************************************/
+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 ));
+
+ 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;
+ int ptr_len1;
+ 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));
+}
+
+
+/*******************************************************************
+makes a SAM_STR1 structure.
+********************************************************************/
+void make_sam_str1(SAM_STR1 *sam, char *sam_acct, char *sam_name, char *sam_desc)
+{
+ int len_sam_acct = sam_acct != NULL ? strlen(sam_acct) : 0;
+ int len_sam_name = sam_name != NULL ? strlen(sam_name) : 0;
+ int len_sam_desc = sam_desc != NULL ? strlen(sam_desc) : 0;
+
+ if (sam == NULL) return;
+
+ DEBUG(5,("make_sam_str1: %d\n", __LINE__));
+
+ make_unistr2(&(sam->uni_acct_name), sam_acct, len_sam_acct);
+ make_unistr2(&(sam->uni_full_name), sam_name, len_sam_name);
+ make_unistr2(&(sam->uni_acct_desc), sam_desc, len_sam_desc);
+}
+
+/*******************************************************************
+reads or writes a SAM_STR1 structure.
+********************************************************************/
+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.
+********************************************************************/
+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_entry2: %d\n", __LINE__));
+
+ 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.
+********************************************************************/
+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_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_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 */
+}
+
+/*******************************************************************
+makes a SAM_STR2 structure.
+********************************************************************/
+void make_sam_str2(SAM_STR2 *sam, char *sam_acct, char *sam_desc)
+{
+ int len_sam_acct = sam_acct != NULL ? strlen(sam_acct) : 0;
+ int len_sam_desc = sam_desc != NULL ? strlen(sam_desc) : 0;
+
+ if (sam == NULL) return;
+
+ DEBUG(5,("make_sam_str2: %d\n", __LINE__));
+
+ make_unistr2(&(sam->uni_srv_name), sam_acct, len_sam_acct);
+ make_unistr2(&(sam->uni_srv_desc), sam_desc, len_sam_desc);
+}
+
+/*******************************************************************
+reads or writes a SAM_STR2 structure.
+********************************************************************/
+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.
+********************************************************************/
+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: %d\n", __LINE__));
+
+ 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.
+********************************************************************/
+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 */
+}
+
+/*******************************************************************
+makes a SAM_STR3 structure.
+********************************************************************/
+void make_sam_str3(SAM_STR3 *sam, char *grp_acct, char *grp_desc)
+{
+ int len_grp_acct = strlen(grp_acct);
+ int len_grp_desc = strlen(grp_desc);
+
+ if (sam == NULL) return;
+
+ DEBUG(5,("make_sam_str3: %d\n", __LINE__));
+
+ make_unistr2(&(sam->uni_grp_name), grp_acct, len_grp_acct);
+ make_unistr2(&(sam->uni_grp_desc), grp_desc, len_grp_desc);
+}
+
+/*******************************************************************
+reads or writes a SAM_STR3 structure.
+********************************************************************/
+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.
+********************************************************************/
+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: %d\n", __LINE__));
+
+ 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.
+********************************************************************/
+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.
+********************************************************************/
+void make_sam_entry(SAM_ENTRY *sam, uint32 len_sam_name, uint32 rid)
+{
+ if (sam == NULL) return;
+
+ DEBUG(5,("make_sam_entry: %d\n", __LINE__));
+
+ 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.
+********************************************************************/
+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 %s\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;
+
+ 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));
+
+ for (i = 0; i < r_u->num_entries2; i++)
+ {
+ prs_grow(ps);
+ sam_io_sam_entry("", &(r_u->sam[i]), ps, depth);
+ }
+
+ 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 %s\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;
+
+ 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));
+
+ 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 %s\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.
+********************************************************************/
+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 ));
+
+ for (i = 0; i < sam->num_entries; i++)
+ {
+ sam_io_sam_entry2("", &(sam->sam[i]), ps, depth);
+ }
+
+ for (i = 0; i < sam->num_entries; i++)
+ {
+ 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 %s\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.
+********************************************************************/
+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 ));
+
+ for (i = 0; i < sam->num_entries; i++)
+ {
+ sam_io_sam_entry1("", &(sam->sam[i]), ps, depth);
+ }
+
+ for (i = 0; i < sam->num_entries; i++)
+ {
+ 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 %s\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 ));
+
+ for (i = 0; i < r_u->num_entries; i++)
+ {
+ sam_io_sam_entry3("", &(r_u->sam[i]), ps, depth);
+ }
+
+ for (i = 0; i < r_u->num_entries; i++)
+ {
+ 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));
+
+ for (i = 0; i < q_u->num_sids2; i++)
+ {
+ sprintf(tmp, "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)
+ {
+ sprintf(tmp, "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;
+
+ 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)
+ {
+
+ for (i = 0; i < r_u->num_entries2; i++)
+ {
+ sprintf(tmp, "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));
+
+ for (i = 0; i < q_u->num_rids2; i++)
+ {
+ smb_io_unihdr ("", &(q_u->hdr_user_name[i]), ps, depth);
+ }
+ for (i = 0; i < q_u->num_rids2; i++)
+ {
+ 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;
+
+ for (i = 0; i < num_rids; i++)
+ {
+ make_dom_rid3(&(r_u->dom_rid[i]), rid[i]);
+ }
+
+ 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)
+ {
+ for (i = 0; i < r_u->num_entries2; i++)
+ {
+ 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));
+}
+
+/*******************************************************************
+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];
+ }
+}
+
+/*******************************************************************
+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));
+
+ for (i = 0; i < q_u->num_gids2; i++)
+ {
+ sprintf(tmp, "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;
+
+ 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)
+ {
+ for (i = 0; i < r_u->num_aliases2; i++)
+ {
+ sprintf(tmp, "als_hdr[%02d] ", i);
+ smb_io_unihdr ("", &(r_u->hdr_als_name[i]), ps, depth);
+ }
+ for (i = 0; i < r_u->num_aliases2; i++)
+ {
+ sprintf(tmp, "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)
+ {
+ for (i = 0; i < r_u->num_als_usrs2; i++)
+ {
+ sprintf(tmp, "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;
+
+#if 0
+ int i;
+ for (i = 0; i < num_gids && i < LSA_MAX_GROUPS; i++)
+ {
+ r_u->gid[i].g_rid = gid[i].g_rid;
+ r_u->gid[i].attr = gid[i].attr ;
+ }
+#endif
+
+ }
+ 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++)
+ {
+ 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.
+********************************************************************/
+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_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_samr_r_unknown_24\n"));
+
+ len_mach_acct = strlen(mach_acct);
+
+ memcpy(&(usr->expiry),expiry, sizeof(usr->expiry)); /* expiry time or something? */
+ bzero(usr->padding_1, 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 */
+ bzero(usr->padding_3, 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 */
+ bzero(usr->padding_6, 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 */
+
+ bzero(usr->padding_7, 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 */
+
+ bzero(usr->padding_9, 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 , len_user_name != 0);
+ make_uni_hdr(&(usr->hdr_full_name ), len_full_name , len_full_name , len_full_name != 0);
+ make_uni_hdr(&(usr->hdr_home_dir ), len_home_dir , len_home_dir , len_home_dir != 0);
+ make_uni_hdr(&(usr->hdr_dir_drive ), len_dir_drive , len_dir_drive , len_dir_drive != 0);
+ make_uni_hdr(&(usr->hdr_logon_script), len_logon_script, len_logon_script, len_logon_script != 0);
+ make_uni_hdr(&(usr->hdr_profile_path), len_profile_path, len_profile_path, len_profile_path != 0);
+ make_uni_hdr(&(usr->hdr_acct_desc ), len_description , len_description , len_description != 0);
+ make_uni_hdr(&(usr->hdr_workstations), len_workstations, len_workstations, len_workstations != 0);
+ make_uni_hdr(&(usr->hdr_unknown_str ), len_unknown_str , len_unknown_str , len_workstations != 0);
+ make_uni_hdr(&(usr->hdr_munged_dial ), len_munged_dial , len_munged_dial , len_workstations != 0);
+
+ bzero(usr->nt_pwd, sizeof(usr->nt_pwd));
+ bzero(usr->lm_pwd, 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 */
+
+ bzero(usr->padding1, 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.
+********************************************************************/
+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);
+ }
+}
+
+
+/*******************************************************************
+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 NULL;
+ }
+ 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 NULL;
+ }
+ 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));
+}
+
+
+/*******************************************************************
+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;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_q_unknown_21(char *desc, SAMR_Q_UNKNOWN_21 *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_q_unknown_21");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("group_pol", &(q_u->group_pol), ps, depth);
+ prs_align(ps);
+
+ prs_uint16("unknown_1", ps, depth, &(q_u->unknown_1));
+ prs_uint16("unknown_2", ps, depth, &(q_u->unknown_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;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void samr_io_q_unknown_13(char *desc, SAMR_Q_UNKNOWN_13 *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "samr_io_q_unknown_13");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("alias_pol", &(q_u->alias_pol), ps, depth);
+ prs_align(ps);
+
+ 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_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 */
+ make_unistr2(&(q_u->uni_srv_name), srv_name, len_srv_name);
+
+ /* 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_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_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,
+ uint16 level, uint32 status)
+{
+ if (r_u == NULL) return;
+
+ DEBUG(5,("make_r_unknown_38\n"));
+
+ r_u->level.value = level;
+ r_u->ptr_0 = 0;
+ r_u->status = status;
+}
+
+/*******************************************************************
+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);
+
+ smb_io_lookup_level("level ", &(r_u->level), ps, depth);
+ prs_uint32("ptr_0 ", ps, depth, &(r_u->ptr_0 ));
+ prs_uint32("status", ps, depth, &(r_u->status));
+}
+
+/*******************************************************************
+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));
+}
+
+/*******************************************************************
+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));
+}
+
+#if 0
+/* SAMR_Q_CHGPASSWD_USER */
+typedef struct q_samr_chgpasswd_user_info
+{
+ uint32 ptr_0;
+
+ UNIHDR hdr_server; /* server name unicode header */
+ UNISTR2 uni_server; /* 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_1; /* seems to always contain 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 result; /* 0 == OK, C000006A (NT_STATUS_WRONG_PASSWORD) */
+
+} SAMR_R_CHGPASSWD_USER;
+
+#endif /* 0 */
+
diff --git a/source3/rpc_parse/parse_srv.c b/source3/rpc_parse/parse_srv.c
new file mode 100644
index 0000000000..959a6096aa
--- /dev/null
+++ b/source3/rpc_parse/parse_srv.c
@@ -0,0 +1,1528 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-1997,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ * Copyright (C) Paul Ashton 1997.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+
+extern int DEBUGLEVEL;
+
+
+/*******************************************************************
+ makes a SH_INFO_1_STR structure
+********************************************************************/
+void make_srv_share_info1_str(SH_INFO_1_STR *sh1, char *net_name, char *remark)
+{
+ if (sh1 == NULL) return;
+
+ DEBUG(5,("make_srv_share_info1_str\n"));
+
+ make_unistr2(&(sh1->uni_netname), net_name, strlen(net_name)+1);
+ make_unistr2(&(sh1->uni_remark ), remark , strlen(remark )+1);
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void srv_io_share_info1_str(char *desc, SH_INFO_1_STR *sh1, prs_struct *ps, int depth)
+{
+ if (sh1 == NULL) return;
+
+ prs_debug(ps, depth, desc, "srv_io_share_info1_str");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_unistr2("", &(sh1->uni_netname), True, ps, depth);
+ smb_io_unistr2("", &(sh1->uni_remark ), True, ps, depth);
+}
+
+/*******************************************************************
+ makes a SH_INFO_1 structure
+********************************************************************/
+void make_srv_share_info1(SH_INFO_1 *sh1, char *net_name, uint32 type, char *remark)
+{
+ if (sh1 == NULL) return;
+
+ DEBUG(5,("make_srv_share_info1: %s %8x %s\n", net_name, type, remark));
+
+ sh1->ptr_netname = net_name != NULL ? 1 : 0;
+ sh1->type = type;
+ sh1->ptr_remark = remark != NULL ? 1 : 0;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void srv_io_share_info1(char *desc, SH_INFO_1 *sh1, prs_struct *ps, int depth)
+{
+ if (sh1 == NULL) return;
+
+ prs_debug(ps, depth, desc, "srv_io_share_info1");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("ptr_netname", ps, depth, &(sh1->ptr_netname));
+ prs_uint32("type ", ps, depth, &(sh1->type ));
+ prs_uint32("ptr_remark ", ps, depth, &(sh1->ptr_remark));
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void srv_io_srv_share_info_1(char *desc, SRV_SHARE_INFO_1 *ctr, prs_struct *ps, int depth)
+{
+ if (ctr == NULL) return;
+
+ prs_debug(ps, depth, desc, "srv_io_share_1_ctr");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("num_entries_read", ps, depth, &(ctr->num_entries_read));
+ prs_uint32("ptr_share_info", ps, depth, &(ctr->ptr_share_info));
+
+ if (ctr->ptr_share_info != 0)
+ {
+ int i;
+ int num_entries = ctr->num_entries_read;
+ if (num_entries > MAX_SHARE_ENTRIES)
+ {
+ num_entries = MAX_SHARE_ENTRIES; /* report this! */
+ }
+
+ prs_uint32("num_entries_read2", ps, depth, &(ctr->num_entries_read2));
+
+ for (i = 0; i < num_entries; i++)
+ {
+ prs_grow(ps);
+ srv_io_share_info1("", &(ctr->info_1[i]), ps, depth);
+ }
+
+ for (i = 0; i < num_entries; i++)
+ {
+ prs_grow(ps);
+ srv_io_share_info1_str("", &(ctr->info_1_str[i]), ps, depth);
+ }
+
+ prs_align(ps);
+ }
+}
+
+/*******************************************************************
+ makes a SH_INFO_2_STR structure
+********************************************************************/
+void make_srv_share_info2_str(SH_INFO_2_STR *sh2,
+ char *net_name, char *remark,
+ char *path, char *passwd)
+{
+ if (sh2 == NULL) return;
+
+ DEBUG(5,("make_srv_share_info2_str\n"));
+
+ make_unistr2(&(sh2->uni_netname), net_name, strlen(net_name)+1);
+ make_unistr2(&(sh2->uni_remark ), remark , strlen(remark )+1);
+ make_unistr2(&(sh2->uni_path ), path , strlen(path )+1);
+ make_unistr2(&(sh2->uni_passwd ), passwd , strlen(passwd )+1);
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void srv_io_share_info2_str(char *desc, SH_INFO_2_STR *sh2, prs_struct *ps, int depth)
+{
+ if (sh2 == NULL) return;
+
+ prs_debug(ps, depth, desc, "srv_io_share_info2_str");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_unistr2("", &(sh2->uni_netname), True, ps, depth);
+ smb_io_unistr2("", &(sh2->uni_remark ), True, ps, depth);
+ smb_io_unistr2("", &(sh2->uni_path ), True, ps, depth);
+ smb_io_unistr2("", &(sh2->uni_passwd ), True, ps, depth);
+}
+
+/*******************************************************************
+ makes a SH_INFO_2 structure
+********************************************************************/
+void make_srv_share_info2(SH_INFO_2 *sh2,
+ char *net_name, uint32 type, char *remark,
+ uint32 perms, uint32 max_uses, uint32 num_uses,
+ char *path, char *passwd)
+{
+ if (sh2 == NULL) return;
+
+ DEBUG(5,("make_srv_share_info2: %s %8x %s\n", net_name, type, remark));
+
+ sh2->ptr_netname = net_name != NULL ? 1 : 0;
+ sh2->type = type;
+ sh2->ptr_remark = remark != NULL ? 1 : 0;
+ sh2->perms = perms;
+ sh2->max_uses = max_uses;
+ sh2->num_uses = num_uses;
+ sh2->type = type;
+ sh2->ptr_path = path != NULL ? 1 : 0;
+ sh2->ptr_passwd = passwd != NULL ? 1 : 0;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void srv_io_share_info2(char *desc, SH_INFO_2 *sh2, prs_struct *ps, int depth)
+{
+ if (sh2 == NULL) return;
+
+ prs_debug(ps, depth, desc, "srv_io_share_info2");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("ptr_netname", ps, depth, &(sh2->ptr_netname));
+ prs_uint32("type ", ps, depth, &(sh2->type ));
+ prs_uint32("ptr_remark ", ps, depth, &(sh2->ptr_remark ));
+ prs_uint32("perms ", ps, depth, &(sh2->perms ));
+ prs_uint32("max_uses ", ps, depth, &(sh2->max_uses ));
+ prs_uint32("num_uses ", ps, depth, &(sh2->num_uses ));
+ prs_uint32("ptr_path ", ps, depth, &(sh2->ptr_path ));
+ prs_uint32("ptr_passwd ", ps, depth, &(sh2->ptr_passwd ));
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void srv_io_srv_share_info_2(char *desc, SRV_SHARE_INFO_2 *ctr, prs_struct *ps, int depth)
+{
+ if (ctr == NULL) return;
+
+ prs_debug(ps, depth, desc, "srv_io_share_2_ctr");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("num_entries_read", ps, depth, &(ctr->num_entries_read));
+ prs_uint32("ptr_share_info", ps, depth, &(ctr->ptr_share_info));
+
+ if (ctr->ptr_share_info != 0)
+ {
+ int i;
+ int num_entries = ctr->num_entries_read;
+ if (num_entries > MAX_SHARE_ENTRIES)
+ {
+ num_entries = MAX_SHARE_ENTRIES; /* report this! */
+ }
+
+ prs_uint32("num_entries_read2", ps, depth, &(ctr->num_entries_read2));
+
+ for (i = 0; i < num_entries; i++)
+ {
+ prs_grow(ps);
+ srv_io_share_info2("", &(ctr->info_2[i]), ps, depth);
+ }
+
+ for (i = 0; i < num_entries; i++)
+ {
+ prs_grow(ps);
+ srv_io_share_info2_str("", &(ctr->info_2_str[i]), ps, depth);
+ }
+
+ prs_align(ps);
+ }
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void srv_io_srv_share_ctr(char *desc, SRV_SHARE_INFO_CTR *ctr, prs_struct *ps, int depth)
+{
+ if (ctr == NULL) return;
+
+ prs_debug(ps, depth, desc, "srv_io_srv_share_ctr");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("switch_value", ps, depth, &(ctr->switch_value));
+ prs_uint32("ptr_share_ctr", ps, depth, &(ctr->ptr_share_ctr));
+
+ if (ctr->ptr_share_ctr != 0)
+ {
+ switch (ctr->switch_value)
+ {
+ case 2:
+ {
+ srv_io_srv_share_info_2("", &(ctr->share.info2), ps, depth);
+ break;
+ }
+ case 1:
+ {
+ srv_io_srv_share_info_1("", &(ctr->share.info1), ps, depth);
+ break;
+ }
+ default:
+ {
+ DEBUG(5,("%s no share info at switch_value %d\n",
+ tab_depth(depth), ctr->switch_value));
+ break;
+ }
+ }
+ }
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void make_srv_q_net_share_enum(SRV_Q_NET_SHARE_ENUM *q_n,
+ char *srv_name,
+ uint32 share_level, SRV_SHARE_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_share_enum\n"));
+
+ make_buf_unistr2(&(q_n->uni_srv_name), &(q_n->ptr_srv_name), srv_name);
+
+ q_n->share_level = share_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_share_enum(char *desc, SRV_Q_NET_SHARE_ENUM *q_n, prs_struct *ps, int depth)
+{
+ if (q_n == NULL) return;
+
+ prs_debug(ps, depth, desc, "srv_io_q_net_share_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("share_level", ps, depth, &(q_n->share_level ));
+
+ if (q_n->share_level != -1)
+ {
+ srv_io_srv_share_ctr("share_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_share_enum(char *desc, SRV_R_NET_SHARE_ENUM *r_n, prs_struct *ps, int depth)
+{
+ if (r_n == NULL) return;
+
+ prs_debug(ps, depth, desc, "srv_io_r_net_share_enum");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("share_level", ps, depth, &(r_n->share_level));
+
+ if (r_n->share_level != 0)
+ {
+ srv_io_srv_share_ctr("share_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 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));
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+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.
+********************************************************************/
+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.
+********************************************************************/
+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));
+
+ 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));
+ make_unistr2(&(ss1->uni_user), name, strlen(user));
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+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.
+********************************************************************/
+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.
+********************************************************************/
+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));
+
+ 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.
+********************************************************************/
+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), True, 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.
+********************************************************************/
+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.
+********************************************************************/
+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));
+ make_unistr2(&(ss1->uni_net_name), net_name, strlen(net_name));
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+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.
+********************************************************************/
+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.
+********************************************************************/
+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.
+********************************************************************/
+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.
+********************************************************************/
+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.
+********************************************************************/
+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.
+********************************************************************/
+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.
+********************************************************************/
+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), True, 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.
+ ********************************************************************/
+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)
+{
+ if (sv101 == NULL) return;
+
+ DEBUG(5,("make_srv_info_101\n"));
+
+ sv101->platform_id = platform_id;
+ make_buf_unistr2(&(sv101->uni_name ), &(sv101->ptr_name ) , name );
+ sv101->ver_major = ver_major;
+ sv101->ver_minor = ver_minor;
+ sv101->srv_type = srv_type;
+ make_buf_unistr2(&(sv101->uni_comment ), &(sv101->ptr_comment) , comment );
+}
+
+
+/*******************************************************************
+ reads or writes a SRV_INFO_101 structure.
+ ********************************************************************/
+void srv_io_info_101(char *desc, SRV_INFO_101 *sv101, prs_struct *ps, int depth)
+{
+ if (sv101 == NULL) return;
+
+ prs_debug(ps, depth, desc, "srv_io_info_101");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("platform_id ", ps, depth, &(sv101->platform_id ));
+ prs_uint32("ptr_name ", ps, depth, &(sv101->ptr_name ));
+ prs_uint32("ver_major ", ps, depth, &(sv101->ver_major ));
+ prs_uint32("ver_minor ", ps, depth, &(sv101->ver_minor ));
+ prs_uint32("srv_type ", ps, depth, &(sv101->srv_type ));
+ prs_uint32("ptr_comment ", ps, depth, &(sv101->ptr_comment ));
+
+ prs_align(ps);
+
+ smb_io_unistr2("uni_name ", &(sv101->uni_name ), True, ps, depth);
+ smb_io_unistr2("uni_comment ", &(sv101->uni_comment ), True, ps, depth);
+}
+
+/*******************************************************************
+ makes a SRV_INFO_102 structure.
+ ********************************************************************/
+void make_srv_info_102(SRV_INFO_102 *sv102, uint32 platform_id, char *name,
+ char *comment, uint32 ver_major, uint32 ver_minor,
+ uint32 srv_type, uint32 users, uint32 disc, uint32 hidden,
+ uint32 announce, uint32 ann_delta, uint32 licenses,
+ char *usr_path)
+{
+ if (sv102 == NULL) return;
+
+ DEBUG(5,("make_srv_info_102\n"));
+
+ sv102->platform_id = platform_id;
+ make_buf_unistr2(&(sv102->uni_name ), &(sv102->ptr_name ), name );
+ sv102->ver_major = ver_major;
+ sv102->ver_minor = ver_minor;
+ sv102->srv_type = srv_type;
+ make_buf_unistr2(&(sv102->uni_comment ), &(sv102->ptr_comment ), comment );
+
+ /* same as 101 up to here */
+
+ sv102->users = users;
+ sv102->disc = disc;
+ sv102->hidden = hidden;
+ sv102->announce = announce;
+ sv102->ann_delta =ann_delta;
+ sv102->licenses = licenses;
+ make_buf_unistr2(&(sv102->uni_usr_path), &(sv102->ptr_usr_path), usr_path);
+}
+
+
+/*******************************************************************
+ reads or writes a SRV_INFO_102 structure.
+ ********************************************************************/
+void srv_io_info_102(char *desc, SRV_INFO_102 *sv102, prs_struct *ps, int depth)
+{
+ if (sv102 == NULL) return;
+
+ prs_debug(ps, depth, desc, "srv_io_info102");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("platform_id ", ps, depth, &(sv102->platform_id ));
+ prs_uint32("ptr_name ", ps, depth, &(sv102->ptr_name ));
+ prs_uint32("ver_major ", ps, depth, &(sv102->ver_major ));
+ prs_uint32("ver_minor ", ps, depth, &(sv102->ver_minor ));
+ prs_uint32("srv_type ", ps, depth, &(sv102->srv_type ));
+ prs_uint32("ptr_comment ", ps, depth, &(sv102->ptr_comment ));
+
+ /* same as 101 up to here */
+
+ prs_uint32("users ", ps, depth, &(sv102->users ));
+ prs_uint32("disc ", ps, depth, &(sv102->disc ));
+ prs_uint32("hidden ", ps, depth, &(sv102->hidden ));
+ prs_uint32("announce ", ps, depth, &(sv102->announce ));
+ prs_uint32("ann_delta ", ps, depth, &(sv102->ann_delta ));
+ prs_uint32("licenses ", ps, depth, &(sv102->licenses ));
+ prs_uint32("ptr_usr_path", ps, depth, &(sv102->ptr_usr_path));
+
+ smb_io_unistr2("uni_name ", &(sv102->uni_name ), True, ps, depth);
+ prs_align(ps);
+ smb_io_unistr2("uni_comment ", &(sv102->uni_comment ), True, ps, depth);
+ prs_align(ps);
+ smb_io_unistr2("uni_usr_path", &(sv102->uni_usr_path), True, ps, depth);
+}
+
+/*******************************************************************
+ reads or writes a SRV_INFO_102 structure.
+ ********************************************************************/
+void srv_io_info_ctr(char *desc, SRV_INFO_CTR *ctr, prs_struct *ps, int depth)
+{
+ if (ctr == NULL) return;
+
+ prs_debug(ps, depth, desc, "srv_io_info_ctr");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("switch_value", ps, depth, &(ctr->switch_value));
+ prs_uint32("ptr_srv_ctr ", ps, depth, &(ctr->ptr_srv_ctr ));
+
+ if (ctr->ptr_srv_ctr != 0 && ctr->switch_value != 0 && ctr != NULL)
+ {
+ switch (ctr->switch_value)
+ {
+ case 101:
+ {
+ srv_io_info_101("sv101", &(ctr->srv.sv101), ps, depth);
+ break;
+ }
+ case 102:
+ {
+ srv_io_info_102("sv102", &(ctr->srv.sv102), ps, depth);
+ break;
+ }
+ default:
+ {
+ DEBUG(5,("%s% no server info at switch_value %d\n",
+ tab_depth(depth), ctr->switch_value));
+ break;
+ }
+ }
+ }
+}
+
+/*******************************************************************
+ makes a SRV_Q_NET_SRV_GET_INFO structure.
+ ********************************************************************/
+void make_srv_q_net_srv_get_info(SRV_Q_NET_SRV_GET_INFO *srv,
+ char *server_name, uint32 switch_value)
+{
+ if (srv == NULL) return;
+
+ DEBUG(5,("make_srv_q_net_srv_get_info\n"));
+
+ make_buf_unistr2(&(srv->uni_srv_name), &(srv->ptr_srv_name), server_name);
+
+ srv->switch_value = switch_value;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void srv_io_q_net_srv_get_info(char *desc, SRV_Q_NET_SRV_GET_INFO *q_n, prs_struct *ps, int depth)
+{
+ if (q_n == NULL) return;
+
+ prs_debug(ps, depth, desc, "srv_io_q_net_srv_get_info");
+ 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("switch_value ", ps, depth, &(q_n->switch_value));
+}
+
+/*******************************************************************
+ makes a SRV_R_NET_SRV_GET_INFO structure.
+ ********************************************************************/
+void make_srv_r_net_srv_get_info(SRV_R_NET_SRV_GET_INFO *srv,
+ uint32 switch_value, SRV_INFO_CTR *ctr, uint32 status)
+{
+ if (srv == NULL) return;
+
+ DEBUG(5,("make_srv_r_net_srv_get_info\n"));
+
+ srv->ctr = ctr;
+
+ if (status == 0x0)
+ {
+ srv->ctr->switch_value = switch_value;
+ srv->ctr->ptr_srv_ctr = 1;
+ }
+ else
+ {
+ srv->ctr->switch_value = 0;
+ srv->ctr->ptr_srv_ctr = 0;
+ }
+
+ srv->status = status;
+}
+
+/*******************************************************************
+ reads or writes a structure.
+ ********************************************************************/
+void srv_io_r_net_srv_get_info(char *desc, SRV_R_NET_SRV_GET_INFO *r_n, prs_struct *ps, int depth)
+{
+ if (r_n == NULL) return;
+
+ prs_debug(ps, depth, desc, "srv_io_r_net_srv_get_info");
+ depth++;
+
+ prs_align(ps);
+
+ srv_io_info_ctr("ctr", r_n->ctr, ps, depth);
+
+ prs_uint32("status ", ps, depth, &(r_n->status ));
+}
+
+
+/*******************************************************************
+ makes a SRV_Q_NET_SRV_SET_INFO structure.
+ ********************************************************************/
+void make_srv_q_net_srv_set_info(SRV_Q_NET_SRV_SET_INFO *srv,
+ uint32 switch_value, SRV_INFO_CTR *ctr)
+{
+ if (srv == NULL) return;
+
+ DEBUG(5,("make_srv_r_net_srv_set_info\n"));
+
+ srv->ctr = ctr;
+
+ srv->ctr->switch_value = switch_value;
+ srv->ctr->ptr_srv_ctr = 1;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void srv_io_q_net_srv_set_info(char *desc, SRV_Q_NET_SRV_SET_INFO *q_n, prs_struct *ps, int depth)
+{
+ if (q_n == NULL) return;
+
+ prs_debug(ps, depth, desc, "srv_io_q_net_srv_set_info");
+ 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);
+
+ srv_io_info_ctr("ctr", q_n->ctr, ps, depth);
+}
+
+/*******************************************************************
+ makes a SRV_R_NET_SRV_SET_INFO structure.
+ ********************************************************************/
+void make_srv_r_net_srv_set_info(SRV_R_NET_SRV_SET_INFO *srv,
+ uint32 switch_value, SRV_INFO_CTR *ctr, uint32 status)
+{
+ if (srv == NULL) return;
+
+ DEBUG(5,("make_srv_r_net_srv_set_info\n"));
+
+ if (status == 0x0)
+ {
+ srv->switch_value = switch_value;
+ }
+ else
+ {
+ srv->switch_value = 0;
+ }
+
+ srv->status = status;
+}
+
+/*******************************************************************
+ reads or writes a structure.
+ ********************************************************************/
+void srv_io_r_net_srv_set_info(char *desc, SRV_R_NET_SRV_SET_INFO *r_n, prs_struct *ps, int depth)
+{
+ if (r_n == NULL) return;
+
+ prs_debug(ps, depth, desc, "srv_io_q_net_srv_set_info");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("switch_value", ps, depth, &(r_n->switch_value));
+ prs_uint32("status ", ps, depth, &(r_n->status ));
+}
+
+
diff --git a/source3/rpc_parse/parse_wks.c b/source3/rpc_parse/parse_wks.c
new file mode 100644
index 0000000000..694acb5eec
--- /dev/null
+++ b/source3/rpc_parse/parse_wks.c
@@ -0,0 +1,146 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-1997,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ * Copyright (C) Paul Ashton 1997.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+
+extern int DEBUGLEVEL;
+
+
+/*******************************************************************
+ make_wks_q_query_info
+ ********************************************************************/
+void make_wks_q_query_info(WKS_Q_QUERY_INFO *q_u,
+ char *server, uint16 switch_value)
+{
+ DEBUG(5,("make_wks_q_query_info: %d\n", __LINE__));
+
+ make_buf_unistr2(&(q_u->uni_srv_name), &(q_u->ptr_srv_name), server);
+ q_u->switch_value = switch_value;
+
+}
+
+/*******************************************************************
+reads or writes a WKS_Q_QUERY_INFO structure.
+********************************************************************/
+void wks_io_q_query_info(char *desc, WKS_Q_QUERY_INFO *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "wks_io_q_query_info");
+ 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_uint16("switch_value", ps, depth, &(q_u->switch_value));
+ prs_align(ps);
+}
+
+/*******************************************************************
+ wks_info_100
+ ********************************************************************/
+void make_wks_info_100(WKS_INFO_100 *inf,
+ uint32 platform_id, uint32 ver_major, uint32 ver_minor,
+ char *my_name, char *domain_name)
+{
+ DEBUG(5,("WKS_INFO_100: %d\n", __LINE__));
+
+ inf->platform_id = platform_id; /* 0x0000 01f4 - unknown */
+ inf->ver_major = ver_major; /* os major version */
+ inf->ver_minor = ver_minor; /* os minor version */
+
+ make_buf_unistr2(&(inf->uni_compname), &(inf->ptr_compname), my_name );
+ make_buf_unistr2(&(inf->uni_lan_grp ), &(inf->ptr_lan_grp ), domain_name);
+}
+
+/*******************************************************************
+reads or writes a WKS_INFO_100 structure.
+********************************************************************/
+void wks_io_wks_info_100(char *desc, WKS_INFO_100 *inf, prs_struct *ps, int depth)
+{
+ if (inf == NULL) return;
+
+ prs_debug(ps, depth, desc, "wks_io_wks_info_100");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("platform_id ", ps, depth, &(inf->platform_id )); /* 0x0000 01f4 - unknown */
+ prs_uint32("ptr_compname", ps, depth, &(inf->ptr_compname)); /* pointer to computer name */
+ prs_uint32("ptr_lan_grp ", ps, depth, &(inf->ptr_lan_grp )); /* pointer to LAN group name */
+ prs_uint32("ver_major ", ps, depth, &(inf->ver_major )); /* 4 - major os version */
+ prs_uint32("ver_minor ", ps, depth, &(inf->ver_minor )); /* 0 - minor os version */
+
+ smb_io_unistr2("", &(inf->uni_compname), inf->ptr_compname, ps, depth);
+ prs_align(ps);
+
+ smb_io_unistr2("", &(inf->uni_lan_grp ), inf->ptr_lan_grp , ps, depth);
+ prs_align(ps);
+}
+
+/*******************************************************************
+ make_wks_r_query_info
+
+ only supports info level 100 at the moment.
+
+ ********************************************************************/
+void make_wks_r_query_info(WKS_R_QUERY_INFO *r_u,
+ uint32 switch_value, WKS_INFO_100 *wks100,
+ int status)
+{
+ DEBUG(5,("make_wks_r_unknown_0: %d\n", __LINE__));
+
+ r_u->switch_value = switch_value; /* same as in request */
+
+ r_u->ptr_1 = 1; /* pointer 1 */
+ r_u->wks100 = wks100;
+
+ r_u->status = status;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+void wks_io_r_query_info(char *desc, WKS_R_QUERY_INFO *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return;
+
+ prs_debug(ps, depth, desc, "wks_io_r_query_info");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint16("switch_value", ps, depth, &(r_u->switch_value)); /* level 100 (0x64) */
+ prs_align(ps);
+
+ prs_uint32("ptr_1 ", ps, depth, &(r_u->ptr_1 )); /* pointer 1 */
+ wks_io_wks_info_100("inf", r_u->wks100, ps, depth);
+
+ prs_uint32("status ", ps, depth, &(r_u->status));
+}
+
diff --git a/source3/rpc_server/srv_lsa.c b/source3/rpc_server/srv_lsa.c
new file mode 100644
index 0000000000..60b74cf599
--- /dev/null
+++ b/source3/rpc_server/srv_lsa.c
@@ -0,0 +1,444 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-1997,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ * Copyright (C) Paul Ashton 1997.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+
+
+/***************************************************************************
+lsa_reply_open_policy
+ ***************************************************************************/
+static void lsa_reply_open_policy(prs_struct *rdata)
+{
+ int i;
+ LSA_R_OPEN_POL r_o;
+
+ /* set up the LSA QUERY INFO response */
+ bzero(&(r_o.pol.data), POL_HND_SIZE);
+ for (i = 4; i < POL_HND_SIZE; i++)
+ {
+ r_o.pol.data[i] = i;
+ }
+ r_o.status = 0x0;
+
+ /* store the response in the SMB stream */
+ lsa_io_r_open_pol("", &r_o, rdata, 0);
+}
+
+/***************************************************************************
+make_dom_query
+ ***************************************************************************/
+static void make_dom_query(DOM_QUERY *d_q, char *dom_name, char *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
+ ***************************************************************************/
+static void lsa_reply_enum_trust_dom(LSA_Q_ENUM_TRUST_DOM *q_e,
+ prs_struct *rdata,
+ uint32 enum_context, char *dom_name, char *dom_sid)
+{
+ LSA_R_ENUM_TRUST_DOM r_e;
+
+ /* set up the LSA QUERY INFO response */
+ make_r_enum_trust_dom(&r_e, enum_context, dom_name, dom_sid,
+ dom_name != NULL ? 0x0 : 0x80000000 | NT_STATUS_UNABLE_TO_FREE_VM);
+
+ /* store the response in the SMB stream */
+ lsa_io_r_enum_trust_dom("", &r_e, rdata, 0);
+}
+
+/***************************************************************************
+lsa_reply_query_info
+ ***************************************************************************/
+static void lsa_reply_query_info(LSA_Q_QUERY_INFO *q_q, prs_struct *rdata,
+ char *dom_name, char *dom_sid)
+{
+ LSA_R_QUERY_INFO r_q;
+
+ /* set up the LSA QUERY INFO response */
+
+ r_q.undoc_buffer = 0x22000000; /* bizarre */
+ r_q.info_class = q_q->info_class;
+
+ make_dom_query(&r_q.dom.id5, dom_name, dom_sid);
+
+ r_q.status = 0x0;
+
+ /* store the response in the SMB stream */
+ lsa_io_r_query("", &r_q, rdata, 0);
+}
+
+/***************************************************************************
+make_dom_ref
+
+ pretty much hard-coded choice of "other" sids, unfortunately...
+
+ ***************************************************************************/
+static void make_dom_ref(DOM_R_REF *ref,
+ char *dom_name, char *dom_sid,
+ char *other_sid1, char *other_sid2, char *other_sid3)
+{
+ int len_dom_name = strlen(dom_name);
+ int len_other_sid1 = strlen(other_sid1);
+ int len_other_sid2 = strlen(other_sid2);
+ int len_other_sid3 = strlen(other_sid3);
+
+ ref->undoc_buffer = 1;
+ ref->num_ref_doms_1 = 4;
+ ref->buffer_dom_name = 1;
+ ref->max_entries = 32;
+ ref->num_ref_doms_2 = 4;
+
+ make_uni_hdr2(&(ref->hdr_dom_name ), len_dom_name , len_dom_name , 0);
+ make_uni_hdr2(&(ref->hdr_ref_dom[0]), len_other_sid1, len_other_sid1, 0);
+ make_uni_hdr2(&(ref->hdr_ref_dom[1]), len_other_sid2, len_other_sid2, 0);
+ make_uni_hdr2(&(ref->hdr_ref_dom[2]), len_other_sid3, len_other_sid3, 0);
+
+ if (dom_name != NULL)
+ {
+ make_unistr(&(ref->uni_dom_name), dom_name);
+ }
+
+ make_dom_sid2(&(ref->ref_dom[0]), dom_sid );
+ make_dom_sid2(&(ref->ref_dom[1]), other_sid1);
+ make_dom_sid2(&(ref->ref_dom[2]), other_sid2);
+ make_dom_sid2(&(ref->ref_dom[3]), other_sid3);
+}
+
+/***************************************************************************
+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],
+ char *dom_name, char *dom_sid,
+ char *other_sid1, char *other_sid2, char *other_sid3)
+{
+ int i;
+
+ make_dom_ref(&(r_l->dom_ref), dom_name, dom_sid,
+ other_sid1, other_sid2, other_sid3);
+
+ r_l->num_entries = num_entries;
+ r_l->undoc_buffer = 1;
+ r_l->num_entries2 = num_entries;
+
+ for (i = 0; i < num_entries; i++)
+ {
+ make_dom_rid2(&(r_l->dom_rid[i]), dom_rids[i]);
+ }
+
+ 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;
+
+ for (i = 0; i < num_entries; i++)
+ {
+ uint32 rid = 0xffffffff;
+ uint8 num_auths = sid[i].sid.num_auths;
+ fstring name;
+ uint32 type;
+
+ trn->ptr_name[i] = 0;
+ trn->ptr_name[(*total)] = 0;
+
+ /* 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)
+ {
+ trn->ptr_name[i] = 1;
+ make_lsa_trans_name(&(trn->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],
+ char *dom_name, char *dom_sid,
+ char *other_sid1, char *other_sid2, char *other_sid3)
+{
+ LSA_R_LOOKUP_SIDS r_l;
+ DOM_R_REF ref;
+ LSA_TRANS_NAME_ENUM names;
+ uint32 mapped_count = 0;
+
+ /* set up the LSA Lookup SIDs response */
+ make_dom_ref(&ref, dom_name, dom_sid, other_sid1, other_sid2, other_sid3);
+ 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],
+ char *dom_name, char *dom_sid,
+ char *other_sid1, char *other_sid2, char *other_sid3)
+{
+ LSA_R_LOOKUP_RIDS r_l;
+
+ /* set up the LSA Lookup RIDs response */
+ make_reply_lookup_rids(&r_l, num_entries, dom_rids,
+ dom_name, dom_sid, other_sid1, other_sid2, other_sid3);
+ r_l.status = 0x0;
+
+ /* store the response in the SMB stream */
+ lsa_io_r_lookup_rids("", &r_l, rdata, 0);
+}
+
+/***************************************************************************
+api_lsa_open_policy
+ ***************************************************************************/
+static void api_lsa_open_policy( int uid, prs_struct *data,
+ prs_struct *rdata )
+{
+ LSA_Q_OPEN_POL q_o;
+
+ /* grab the server, object attributes and desired access flag...*/
+ lsa_io_q_open_pol("", &q_o, data, 0);
+
+ /* lkclXXXX having decoded it, ignore all fields in the open policy! */
+
+ /* return a 20 byte policy handle */
+ lsa_reply_open_policy(rdata);
+}
+
+/***************************************************************************
+api_lsa_enum_trust_dom
+ ***************************************************************************/
+static void api_lsa_enum_trust_dom( int uid, prs_struct *data,
+ prs_struct *rdata )
+{
+ LSA_Q_ENUM_TRUST_DOM q_e;
+
+ /* grab the enum trust domain context etc. */
+ lsa_io_q_enum_trust_dom("", &q_e, data, 0);
+
+ /* construct reply. return status is always 0x0 */
+ lsa_reply_enum_trust_dom(&q_e, rdata,
+ 0, NULL, NULL);
+}
+
+/***************************************************************************
+api_lsa_query_info
+ ***************************************************************************/
+static void api_lsa_query_info( int uid, prs_struct *data,
+ prs_struct *rdata )
+{
+ LSA_Q_QUERY_INFO q_i;
+ pstring dom_name;
+ pstring dom_sid;
+
+ /* grab the info class and policy handle */
+ lsa_io_q_query("", &q_i, data, 0);
+
+ pstrcpy(dom_name, lp_workgroup());
+ pstrcpy(dom_sid , lp_domain_sid());
+
+ /* construct reply. return status is always 0x0 */
+ lsa_reply_query_info(&q_i, rdata, dom_name, dom_sid);
+}
+
+/***************************************************************************
+api_lsa_lookup_sids
+ ***************************************************************************/
+static void api_lsa_lookup_sids( int uid, prs_struct *data,
+ prs_struct *rdata )
+{
+ LSA_Q_LOOKUP_SIDS q_l;
+ pstring dom_name;
+ pstring dom_sid;
+
+ /* grab the info class and policy handle */
+ lsa_io_q_lookup_sids("", &q_l, data, 0);
+
+ pstrcpy(dom_name, lp_workgroup());
+ pstrcpy(dom_sid , lp_domain_sid());
+
+ /* construct reply. return status is always 0x0 */
+ lsa_reply_lookup_sids(rdata,
+ q_l.sids.num_entries, q_l.sids.sid, /* SIDs */
+ dom_name, dom_sid, /* domain name, domain SID */
+ "S-1-1", "S-1-3", "S-1-5"); /* the three other SIDs */
+}
+
+/***************************************************************************
+api_lsa_lookup_names
+ ***************************************************************************/
+static void api_lsa_lookup_names( int uid, prs_struct *data,
+ prs_struct *rdata )
+{
+ int i;
+ LSA_Q_LOOKUP_RIDS q_l;
+ pstring dom_name;
+ pstring dom_sid;
+ uint32 dom_rids[MAX_LOOKUP_SIDS];
+ uint32 dummy_g_rid;
+
+ /* grab the info class and policy handle */
+ lsa_io_q_lookup_rids("", &q_l, data, 0);
+
+ pstrcpy(dom_name, lp_workgroup());
+ pstrcpy(dom_sid , lp_domain_sid());
+
+ /* convert received RIDs to strings, so we can do them. */
+ for (i = 0; i < q_l.num_entries; i++)
+ {
+ char *user_name = unistr2(q_l.lookup_name[i].str.buffer);
+ if (!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 */
+ dom_name, dom_sid, /* domain name, domain SID */
+ "S-1-1", "S-1-3", "S-1-5"); /* the three other SIDs */
+}
+
+/***************************************************************************
+ api_lsa_close
+ ***************************************************************************/
+static void api_lsa_close( int uid, prs_struct *data,
+ prs_struct *rdata)
+{
+ /* XXXX this is NOT good */
+ char *q = mem_data(&(rdata->data), rdata->offset);
+
+ SIVAL(q, 0, 0); q += 4;
+ SIVAL(q, 0, 0); q += 4;
+ SIVAL(q, 0, 0); q += 4;
+ SIVAL(q, 0, 0); q += 4;
+ SIVAL(q, 0, 0); q += 4;
+ SIVAL(q, 0, 0); q += 4;
+
+ rdata->offset += 24;
+}
+
+/***************************************************************************
+ api_lsa_open_secret
+ ***************************************************************************/
+static void api_lsa_open_secret( int uid, prs_struct *data,
+ prs_struct *rdata)
+{
+ /* XXXX this is NOT good */
+ char *q = mem_data(&(rdata->data), rdata->offset);
+
+ SIVAL(q, 0, 0); q += 4;
+ SIVAL(q, 0, 0); q += 4;
+ SIVAL(q, 0, 0); q += 4;
+ SIVAL(q, 0, 0); q += 4;
+ SIVAL(q, 0, 0); q += 4;
+ SIVAL(q, 0, 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND); q += 4;
+
+ rdata->offset += 24;
+}
+
+/***************************************************************************
+ \PIPE\ntlsa commands
+ ***************************************************************************/
+static struct api_struct api_lsa_cmds[] =
+{
+ { "LSA_OPENPOLICY" , LSA_OPENPOLICY , api_lsa_open_policy },
+ { "LSA_QUERYINFOPOLICY" , LSA_QUERYINFOPOLICY , api_lsa_query_info },
+ { "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 }
+};
+
+/***************************************************************************
+ api_ntLsarpcTNP
+ ***************************************************************************/
+BOOL api_ntlsa_rpc(pipes_struct *p, prs_struct *data)
+{
+ return api_rpcTNP(p, "api_ntlsa_rpc", api_lsa_cmds, data);
+}
+
diff --git a/source3/rpc_server/srv_lsa_hnd.c b/source3/rpc_server/srv_lsa_hnd.c
new file mode 100644
index 0000000000..c8eabf35b4
--- /dev/null
+++ b/source3/rpc_server/srv_lsa_hnd.c
@@ -0,0 +1,316 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-1997,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+
+
+extern int DEBUGLEVEL;
+
+#ifndef MAX_OPEN_POLS
+#define MAX_OPEN_POLS 50
+#endif
+
+struct reg_info
+{
+ /* for use by \PIPE\winreg */
+ fstring name; /* name of registry key */
+};
+
+struct samr_info
+{
+ /* for use by the \PIPE\samr policy */
+ DOM_SID sid;
+ uint32 rid; /* relative id associated with the pol_hnd */
+ uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
+};
+
+static struct
+{
+ BOOL open;
+ POLICY_HND pol_hnd;
+
+ union
+ {
+ struct samr_info samr;
+ struct reg_info reg;
+
+ } dev;
+
+} Policy[MAX_OPEN_POLS];
+
+
+#define VALID_POL(pnum) (((pnum) >= 0) && ((pnum) < MAX_OPEN_POLS))
+#define OPEN_POL(pnum) (VALID_POL(pnum) && Policy[pnum].open)
+
+/****************************************************************************
+ create a unique policy handle
+****************************************************************************/
+void create_pol_hnd(POLICY_HND *hnd)
+{
+ static uint32 pol_hnd_low = 0;
+ static uint32 pol_hnd_high = 0;
+
+ if (hnd == NULL) return;
+
+ /* i severely doubt that pol_hnd_high will ever be non-zero... */
+ pol_hnd_low++;
+ if (pol_hnd_low == 0) pol_hnd_high++;
+
+ SIVAL(hnd->data, 0 , 0x0); /* first bit must be null */
+ SIVAL(hnd->data, 4 , pol_hnd_low ); /* second bit is incrementing */
+ SIVAL(hnd->data, 8 , pol_hnd_high); /* second bit is incrementing */
+ SIVAL(hnd->data, 12, time(NULL)); /* something random */
+ SIVAL(hnd->data, 16, getpid()); /* something more random */
+}
+
+/****************************************************************************
+ initialise policy handle states...
+****************************************************************************/
+void init_lsa_policy_hnd(void)
+{
+ int i;
+ for (i = 0; i < MAX_OPEN_POLS; i++)
+ {
+ Policy[i].open = False;
+ }
+
+ return;
+}
+
+/****************************************************************************
+ find first available policy slot. creates a policy handle for you.
+****************************************************************************/
+BOOL open_lsa_policy_hnd(POLICY_HND *hnd)
+{
+ int i;
+
+ for (i = 0; i < MAX_OPEN_POLS; i++)
+ {
+ if (!Policy[i].open)
+ {
+ Policy[i].open = True;
+
+ create_pol_hnd(hnd);
+ memcpy(&(Policy[i].pol_hnd), hnd, sizeof(*hnd));
+
+ DEBUG(4,("Opened policy hnd[%x] ", i));
+ dump_data(4, hnd->data, sizeof(hnd->data));
+
+ return True;
+ }
+ }
+
+ /* i love obscure error messages. */
+#if TERRY_PRATCHET_INTERESTING_TIMES
+ DEBUG(1,("+++ OUT OF CHEESE ERROR +++ REDO FROM START ... @?!*@@\n"));
+#else
+ DEBUG(1,("ERROR - open_lsa_policy_hnd: out of Policy Handles!\n"));
+#endif
+
+ return False;
+}
+
+/****************************************************************************
+ find policy index by handle
+****************************************************************************/
+int find_lsa_policy_by_hnd(POLICY_HND *hnd)
+{
+ int i;
+
+ for (i = 0; i < MAX_OPEN_POLS; i++)
+ {
+ if (memcmp(&(Policy[i].pol_hnd), hnd, sizeof(*hnd)) == 0)
+ {
+ DEBUG(4,("Found policy hnd[%x] ", i));
+ dump_data(4, hnd->data, sizeof(hnd->data));
+
+ return i;
+ }
+ }
+
+ DEBUG(4,("Policy not found: "));
+ dump_data(4, hnd->data, sizeof(hnd->data));
+
+ return -1;
+}
+
+/****************************************************************************
+ set samr rid
+****************************************************************************/
+BOOL set_lsa_policy_samr_rid(POLICY_HND *hnd, uint32 rid)
+{
+ int pnum = find_lsa_policy_by_hnd(hnd);
+
+ if (OPEN_POL(pnum))
+ {
+ DEBUG(3,("%s Setting policy device rid=%x pnum=%x\n",
+ timestring(), rid, pnum));
+
+ Policy[pnum].dev.samr.rid = rid;
+ return True;
+ }
+ else
+ {
+ DEBUG(3,("%s Error setting policy rid=%x (pnum=%x)\n",
+ timestring(), rid, pnum));
+ return False;
+ }
+}
+
+/****************************************************************************
+ set samr pol status. absolutely no idea what this is.
+****************************************************************************/
+BOOL set_lsa_policy_samr_pol_status(POLICY_HND *hnd, uint32 pol_status)
+{
+ int pnum = find_lsa_policy_by_hnd(hnd);
+
+ if (OPEN_POL(pnum))
+ {
+ DEBUG(3,("%s Setting policy status=%x pnum=%x\n",
+ timestring(), pol_status, pnum));
+
+ Policy[pnum].dev.samr.status = pol_status;
+ return True;
+ }
+ else
+ {
+ DEBUG(3,("%s Error setting policy status=%x (pnum=%x)\n",
+ timestring(), pol_status, pnum));
+ return False;
+ }
+}
+
+/****************************************************************************
+ set samr sid
+****************************************************************************/
+BOOL set_lsa_policy_samr_sid(POLICY_HND *hnd, DOM_SID *sid)
+{
+ int pnum = find_lsa_policy_by_hnd(hnd);
+
+ if (OPEN_POL(pnum))
+ {
+ DEBUG(3,("%s Setting policy sid=%s pnum=%x\n",
+ timestring(), dom_sid_to_string(sid), pnum));
+
+ memcpy(&(Policy[pnum].dev.samr.sid), sid, sizeof(*sid));
+ return True;
+ }
+ else
+ {
+ DEBUG(3,("%s Error setting policy sid=%s (pnum=%x)\n",
+ timestring(), dom_sid_to_string(sid), pnum));
+ return False;
+ }
+}
+
+/****************************************************************************
+ set samr rid
+****************************************************************************/
+uint32 get_lsa_policy_samr_rid(POLICY_HND *hnd)
+{
+ int pnum = find_lsa_policy_by_hnd(hnd);
+
+ if (OPEN_POL(pnum))
+ {
+ uint32 rid = Policy[pnum].dev.samr.rid;
+ DEBUG(3,("%s Getting policy device rid=%x pnum=%x\n",
+ timestring(), rid, pnum));
+
+ return rid;
+ }
+ else
+ {
+ DEBUG(3,("%s Error getting policy (pnum=%x)\n",
+ timestring(), pnum));
+ return 0xffffffff;
+ }
+}
+
+/****************************************************************************
+ set reg name
+****************************************************************************/
+BOOL set_lsa_policy_reg_name(POLICY_HND *hnd, fstring name)
+{
+ int pnum = find_lsa_policy_by_hnd(hnd);
+
+ if (OPEN_POL(pnum))
+ {
+ DEBUG(3,("%s Setting policy pnum=%x name=%s\n",
+ timestring(), pnum, name));
+
+ fstrcpy(Policy[pnum].dev.reg.name, name);
+ return True;
+ }
+ else
+ {
+ DEBUG(3,("%s Error setting policy (pnum=%x) name=%s\n",
+ timestring(), pnum, name));
+ return False;
+ }
+}
+
+/****************************************************************************
+ get reg name
+****************************************************************************/
+BOOL get_lsa_policy_reg_name(POLICY_HND *hnd, fstring name)
+{
+ int pnum = find_lsa_policy_by_hnd(hnd);
+
+ if (OPEN_POL(pnum))
+ {
+ fstrcpy(name, Policy[pnum].dev.reg.name);
+
+ DEBUG(3,("%s Getting policy pnum=%x name=%s\n",
+ timestring(), pnum, name));
+
+ return True;
+ }
+ else
+ {
+ DEBUG(3,("%s Error getting policy (pnum=%x)\n",
+ timestring(), pnum));
+ return False;
+ }
+}
+
+/****************************************************************************
+ close an lsa policy
+****************************************************************************/
+BOOL close_lsa_policy_hnd(POLICY_HND *hnd)
+{
+ int pnum = find_lsa_policy_by_hnd(hnd);
+
+ if (OPEN_POL(pnum))
+ {
+ DEBUG(3,("%s Closed policy name pnum=%x\n", timestring(), pnum));
+ Policy[pnum].open = False;
+ return True;
+ }
+ else
+ {
+ DEBUG(3,("%s Error closing policy pnum=%x\n", timestring(), pnum));
+ return False;
+ }
+}
+
diff --git a/source3/rpc_server/srv_netlog.c b/source3/rpc_server/srv_netlog.c
new file mode 100644
index 0000000000..94d6faa992
--- /dev/null
+++ b/source3/rpc_server/srv_netlog.c
@@ -0,0 +1,832 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-1997,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ * Copyright (C) Paul Ashton 1997.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+
+extern BOOL sam_logon_in_ssb;
+extern pstring samlogon_user;
+
+
+
+/*************************************************************************
+ make_net_r_req_chal:
+ *************************************************************************/
+static void make_net_r_req_chal(NET_R_REQ_CHAL *r_c,
+ DOM_CHAL *srv_chal, int status)
+{
+ DEBUG(6,("make_net_r_req_chal: %d\n", __LINE__));
+ memcpy(r_c->srv_chal.data, srv_chal->data, sizeof(srv_chal->data));
+ r_c->status = status;
+}
+
+/*************************************************************************
+ net_reply_req_chal:
+ *************************************************************************/
+static void net_reply_req_chal(NET_Q_REQ_CHAL *q_c, prs_struct *rdata,
+ DOM_CHAL *srv_chal, uint32 srv_time)
+{
+ NET_R_REQ_CHAL r_c;
+
+ DEBUG(6,("net_reply_req_chal: %d\n", __LINE__));
+
+ /* set up the LSA REQUEST CHALLENGE response */
+ make_net_r_req_chal(&r_c, srv_chal, srv_time);
+
+ /* store the response in the SMB stream */
+ net_io_r_req_chal("", &r_c, rdata, 0);
+
+ DEBUG(6,("net_reply_req_chal: %d\n", __LINE__));
+
+}
+
+/*************************************************************************
+ net_reply_logon_ctrl2:
+ *************************************************************************/
+static void net_reply_logon_ctrl2(NET_Q_LOGON_CTRL2 *q_l, prs_struct *rdata,
+ uint32 flags, uint32 pdc_status, uint32 logon_attempts,
+ uint32 tc_status, char *trust_domain_name)
+{
+ NET_R_LOGON_CTRL2 r_l;
+
+ DEBUG(6,("net_reply_logon_ctrl2: %d\n", __LINE__));
+
+ /* set up the Logon Control2 response */
+ make_r_logon_ctrl2(&r_l, q_l->query_level,
+ flags, pdc_status, logon_attempts,
+ tc_status, trust_domain_name);
+
+ /* store the response in the SMB stream */
+ net_io_r_logon_ctrl2("", &r_l, rdata, 0);
+
+ DEBUG(6,("net_reply_logon_ctrl2: %d\n", __LINE__));
+
+}
+
+/*************************************************************************
+ net_reply_trust_dom_list:
+ *************************************************************************/
+static void net_reply_trust_dom_list(NET_Q_TRUST_DOM_LIST *q_t, prs_struct *rdata,
+ uint32 num_trust_domains, char *trust_domain_name)
+{
+ NET_R_TRUST_DOM_LIST r_t;
+
+ DEBUG(6,("net_reply_trust_dom_list: %d\n", __LINE__));
+
+ /* set up the Trusted Domain List response */
+ make_r_trust_dom(&r_t, num_trust_domains, trust_domain_name);
+
+ /* store the response in the SMB stream */
+ net_io_r_trust_dom("", &r_t, rdata, 0);
+
+ DEBUG(6,("net_reply_trust_dom_listlogon_ctrl2: %d\n", __LINE__));
+
+}
+
+/*************************************************************************
+ make_net_r_auth_2:
+ *************************************************************************/
+static void make_net_r_auth_2(NET_R_AUTH_2 *r_a,
+ DOM_CHAL *resp_cred, NEG_FLAGS *flgs, int status)
+{
+ memcpy( r_a->srv_chal.data, resp_cred->data, sizeof(resp_cred->data));
+ memcpy(&(r_a->srv_flgs) , flgs , sizeof(r_a->srv_flgs));
+ r_a->status = status;
+}
+
+/*************************************************************************
+ net_reply_auth_2:
+ *************************************************************************/
+static void net_reply_auth_2(NET_Q_AUTH_2 *q_a, prs_struct *rdata,
+ DOM_CHAL *resp_cred, int status)
+{
+ NET_R_AUTH_2 r_a;
+
+ /* set up the LSA AUTH 2 response */
+
+ make_net_r_auth_2(&r_a, resp_cred, &(q_a->clnt_flgs), status);
+
+ /* store the response in the SMB stream */
+ net_io_r_auth_2("", &r_a, rdata, 0);
+
+}
+
+/***********************************************************************************
+ make_net_r_srv_pwset:
+ ***********************************************************************************/
+static void make_net_r_srv_pwset(NET_R_SRV_PWSET *r_s,
+ DOM_CRED *srv_cred, int status)
+{
+ DEBUG(5,("make_net_r_srv_pwset: %d\n", __LINE__));
+
+ memcpy(&(r_s->srv_cred), srv_cred, sizeof(r_s->srv_cred));
+ r_s->status = status;
+
+ DEBUG(5,("make_net_r_srv_pwset: %d\n", __LINE__));
+}
+
+/*************************************************************************
+ net_reply_srv_pwset:
+ *************************************************************************/
+static void net_reply_srv_pwset(NET_Q_SRV_PWSET *q_s, prs_struct *rdata,
+ DOM_CRED *srv_cred, int status)
+{
+ NET_R_SRV_PWSET r_s;
+
+ DEBUG(5,("net_srv_pwset: %d\n", __LINE__));
+
+ /* set up the LSA Server Password Set response */
+ make_net_r_srv_pwset(&r_s, srv_cred, status);
+
+ /* store the response in the SMB stream */
+ net_io_r_srv_pwset("", &r_s, rdata, 0);
+
+ DEBUG(5,("net_srv_pwset: %d\n", __LINE__));
+
+}
+
+/*************************************************************************
+ net_reply_sam_logon:
+ *************************************************************************/
+static void net_reply_sam_logon(NET_Q_SAM_LOGON *q_s, prs_struct *rdata,
+ DOM_CRED *srv_cred, NET_USER_INFO_3 *user_info,
+ uint32 status)
+{
+ NET_R_SAM_LOGON r_s;
+
+ /* XXXX maybe we want to say 'no', reject the client's credentials */
+ r_s.buffer_creds = 1; /* yes, we have valid server credentials */
+ memcpy(&(r_s.srv_creds), srv_cred, sizeof(r_s.srv_creds));
+
+ /* store the user information, if there is any. */
+ r_s.user = user_info;
+ if (status == 0x0 && user_info != NULL && user_info->ptr_user_info != 0)
+ {
+ r_s.switch_value = 3; /* indicates type of validation user info */
+ }
+ else
+ {
+ r_s.switch_value = 0; /* indicates no info */
+ }
+
+ r_s.status = status;
+ r_s.auth_resp = 1; /* authoritative response */
+
+ /* store the response in the SMB stream */
+ net_io_r_sam_logon("", &r_s, rdata, 0);
+
+}
+
+
+/*************************************************************************
+ net_reply_sam_logoff:
+ *************************************************************************/
+static void net_reply_sam_logoff(NET_Q_SAM_LOGOFF *q_s, prs_struct *rdata,
+ DOM_CRED *srv_cred,
+ uint32 status)
+{
+ NET_R_SAM_LOGOFF r_s;
+
+ /* XXXX maybe we want to say 'no', reject the client's credentials */
+ r_s.buffer_creds = 1; /* yes, we have valid server credentials */
+ memcpy(&(r_s.srv_creds), srv_cred, sizeof(r_s.srv_creds));
+
+ r_s.status = status;
+
+ /* store the response in the SMB stream */
+ net_io_r_sam_logoff("", &r_s, rdata, 0);
+
+}
+
+/******************************************************************
+ gets a machine password entry. checks access rights of the host.
+ ******************************************************************/
+static BOOL get_md4pw(char *md4pw, char *mach_name, char *mach_acct)
+{
+ struct smb_passwd *smb_pass;
+
+ if (!allow_access(lp_domain_hostsdeny(), lp_domain_hostsallow(),
+ client_name(), client_addr()))
+ {
+ DEBUG(0,("get_md4pw: Workstation %s denied access to domain\n", mach_acct));
+ return False;
+ }
+
+ become_root(True);
+ smb_pass = get_smbpwd_entry(mach_acct, 0);
+ unbecome_root(True);
+
+ if (smb_pass != NULL)
+ {
+ memcpy(md4pw, smb_pass->smb_nt_passwd, 16);
+ dump_data(5, md4pw, 16);
+
+ return True;
+ }
+ DEBUG(0,("get_md4pw: Workstation %s: no account in domain\n", mach_acct));
+ return False;
+}
+
+/*************************************************************************
+ api_net_req_chal:
+ *************************************************************************/
+static void api_net_req_chal( int uid,
+ prs_struct *data,
+ prs_struct *rdata)
+{
+ NET_Q_REQ_CHAL q_r;
+ uint32 status = 0x0;
+
+ fstring mach_acct;
+ fstring mach_name;
+
+ user_struct *vuser;
+
+ DEBUG(5,("api_net_req_chal(%d): vuid %d\n", __LINE__, uid));
+
+ if ((vuser = get_valid_user_struct(uid)) == NULL) return;
+
+ /* grab the challenge... */
+ net_io_q_req_chal("", &q_r, data, 0);
+
+ fstrcpy(mach_acct, unistrn2(q_r.uni_logon_clnt.buffer,
+ q_r.uni_logon_clnt.uni_str_len));
+
+ fstrcpy(mach_name, mach_acct);
+ strlower(mach_name);
+
+ strcat(mach_acct, "$");
+
+ if (get_md4pw(vuser->dc.md4pw, mach_name, mach_acct))
+ {
+ /* copy the client credentials */
+ memcpy(vuser->dc.clnt_chal.data , q_r.clnt_chal.data, sizeof(q_r.clnt_chal.data));
+ memcpy(vuser->dc.clnt_cred.challenge.data, q_r.clnt_chal.data, sizeof(q_r.clnt_chal.data));
+
+ /* create a server challenge for the client */
+ /* PAXX: set these to random values. */
+ /* lkcl: paul, you mentioned that it doesn't really matter much */
+ SIVAL(vuser->dc.srv_chal.data, 0, 0x11111111);
+ SIVAL(vuser->dc.srv_chal.data, 4, 0x11111111);
+ memcpy(vuser->dc.srv_cred.challenge.data, vuser->dc.srv_chal.data, 8);
+
+ bzero(vuser->dc.sess_key, sizeof(vuser->dc.sess_key));
+
+ /* from client / server challenges and md4 password, generate sess key */
+ cred_session_key(&(vuser->dc.clnt_chal), &(vuser->dc.srv_chal),
+ vuser->dc.md4pw, vuser->dc.sess_key);
+ }
+ else
+ {
+ /* lkclXXXX take a guess at a good error message to return :-) */
+ status = 0xC0000000 | NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT;
+ }
+
+ /* construct reply. */
+ net_reply_req_chal(&q_r, rdata,
+ &(vuser->dc.srv_chal), status);
+
+}
+
+/*************************************************************************
+ api_net_auth_2:
+ *************************************************************************/
+static void api_net_auth_2( int uid,
+ prs_struct *data,
+ prs_struct *rdata)
+{
+ NET_Q_AUTH_2 q_a;
+ uint32 status = 0x0;
+
+ DOM_CHAL srv_cred;
+ UTIME srv_time;
+
+ user_struct *vuser;
+
+ if ((vuser = get_valid_user_struct(uid)) == NULL) return;
+
+ srv_time.time = 0;
+
+ /* grab the challenge... */
+ net_io_q_auth_2("", &q_a, data, 0);
+
+ /* check that the client credentials are valid */
+ if (cred_assert(&(q_a.clnt_chal), vuser->dc.sess_key,
+ &(vuser->dc.clnt_cred.challenge), srv_time))
+ {
+
+ /* create server challenge for inclusion in the reply */
+ cred_create(vuser->dc.sess_key, &(vuser->dc.srv_cred.challenge), srv_time, &srv_cred);
+
+ /* copy the received client credentials for use next time */
+ memcpy(vuser->dc.clnt_cred.challenge.data, &(q_a.clnt_chal.data), sizeof(q_a.clnt_chal.data));
+ memcpy(vuser->dc.srv_cred.challenge.data, &(q_a.clnt_chal.data), sizeof(q_a.clnt_chal.data));
+ }
+ else
+ {
+ status = NT_STATUS_ACCESS_DENIED | 0xC0000000;
+ }
+
+ /* construct reply. */
+ net_reply_auth_2(&q_a, rdata, &srv_cred, status);
+}
+
+
+/*************************************************************************
+ api_net_srv_pwset:
+ *************************************************************************/
+static void api_net_srv_pwset( int uid,
+ prs_struct *data,
+ prs_struct *rdata)
+{
+ NET_Q_SRV_PWSET q_a;
+ uint32 status = NT_STATUS_WRONG_PASSWORD|0xC0000000;
+ DOM_CRED srv_cred;
+#ifdef ALLOW_SRV_PWSET
+ pstring mach_acct;
+ struct smb_passwd *smb_pass;
+ BOOL ret;
+#endif
+ user_struct *vuser;
+
+ if ((vuser = get_valid_user_struct(uid)) == NULL) return;
+
+ /* grab the challenge and encrypted password ... */
+ net_io_q_srv_pwset("", &q_a, data, 0);
+
+ /* checks and updates credentials. creates reply credentials */
+ if (deal_with_creds(vuser->dc.sess_key, &(vuser->dc.clnt_cred),
+ &(q_a.clnt_id.cred), &srv_cred))
+ {
+ memcpy(&(vuser->dc.srv_cred), &(vuser->dc.clnt_cred), sizeof(vuser->dc.clnt_cred));
+
+ DEBUG(5,("api_net_srv_pwset: %d\n", __LINE__));
+
+#ifdef ALLOW_SRV_PWSET
+
+ pstrcpy(mach_acct, unistrn2(q_a.clnt_id.login.uni_acct_name.buffer,
+ q_a.clnt_id.login.uni_acct_name.uni_str_len));
+
+ DEBUG(3,("Server Password Set Wksta:[%s]\n", mach_acct));
+
+ become_root(True);
+ smb_pass = get_smbpwd_entry(mach_acct, 0);
+ unbecome_root(True);
+
+ if (smb_pass != NULL)
+ {
+ unsigned char pwd[16];
+ uint8 mode = 2;
+
+ memcpy(pwd, q_a.pwd, 16);
+
+ if (obfuscate_pwd(pwd, vuser->dc.sess_key, mode))
+ {
+ /* lies! nt and lm passwords are _not_ the same: don't care */
+ smb_pass->smb_passwd = pwd;
+ smb_pass->smb_nt_passwd = pwd;
+ smb_pass->acct_ctrl = ACB_WSTRUST;
+
+ become_root(True);
+ ret = mod_smbpwd_entry(smb_pass);
+ unbecome_root(True);
+
+ if (ret)
+ {
+ /* hooray! */
+ status = 0x0;
+ }
+ }
+ }
+
+ DEBUG(5,("api_net_srv_pwset: %d\n", __LINE__));
+#else
+ DEBUG(5,("api_net_srv_pwset: server password set being denied\n"));
+#endif
+
+ }
+ else
+ {
+ /* lkclXXXX take a guess at a sensible error code to return... */
+ status = 0xC0000000 | NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
+ }
+
+ /* construct reply. always indicate failure. nt keeps going... */
+ net_reply_srv_pwset(&q_a, rdata,
+ &srv_cred, status);
+}
+
+
+/*************************************************************************
+ api_net_sam_logoff:
+ *************************************************************************/
+static void api_net_sam_logoff( int uid,
+ prs_struct *data,
+ prs_struct *rdata)
+{
+ NET_Q_SAM_LOGOFF q_l;
+ NET_ID_INFO_CTR ctr;
+
+ DOM_CRED srv_cred;
+
+ user_struct *vuser;
+
+ if ((vuser = get_valid_user_struct(uid)) == NULL) return;
+
+ /* the DOM_ID_INFO_1 structure is a bit big. plus we might want to
+ dynamically allocate it inside net_io_q_sam_logon, at some point */
+ q_l.sam_id.ctr = &ctr;
+
+ /* grab the challenge... */
+ net_io_q_sam_logoff("", &q_l, data, 0);
+
+ /* checks and updates credentials. creates reply credentials */
+ deal_with_creds(vuser->dc.sess_key, &(vuser->dc.clnt_cred),
+ &(q_l.sam_id.client.cred), &srv_cred);
+ memcpy(&(vuser->dc.srv_cred), &(vuser->dc.clnt_cred), sizeof(vuser->dc.clnt_cred));
+
+ /* construct reply. always indicate success */
+ net_reply_sam_logoff(&q_l, rdata,
+ &srv_cred,
+ 0x0);
+}
+
+/*************************************************************************
+ net_login_interactive:
+ *************************************************************************/
+static uint32 net_login_interactive(NET_ID_INFO_1 *id1,
+ struct smb_passwd *smb_pass,
+ user_struct *vuser)
+{
+ uint32 status = 0x0;
+
+#ifdef USE_ARCFOUR
+ extern void arcfour(uint8 key[16], uint8 out[16], uint8 in[16]);
+ char nt_pwd[16];
+ char lm_pwd[16];
+ unsigned char arc4_key[16];
+ memset(arc4_key, 0, 16);
+ memcpy(arc4_key, vuser->dc.sess_key, 8);
+
+ arcfour(arc4_key, lm_pwd, id1->arc4_lm_owf.data);
+ arcfour(arc4_key, nt_pwd, id1->arc4_nt_owf.data);
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("arcfour decrypt of lm owf password:"));
+ dump_data(100, lm_pwd, 16);
+
+ DEBUG(100,("arcfour decrypt of nt owf password:"));
+ dump_data(100, nt_pwd, 16);
+#endif
+
+ if (memcmp(smb_pass->smb_passwd , lm_pwd, 16) != 0 &&
+ memcmp(smb_pass->smb_nt_passwd, nt_pwd, 16) != 0)
+ {
+ status = 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
+ }
+#else
+/* sorry. have to assume that the password is always ok.
+ this _is_ ok, because the LSA SAM Logon is nothing to do
+ with SMB connections to shares.
+ */
+DEBUG(3,("SAM Logon. Password not being checked\n"));
+#endif
+
+ return status;
+}
+
+/*************************************************************************
+ net_login_network:
+ *************************************************************************/
+static uint32 net_login_network(NET_ID_INFO_2 *id2,
+ struct smb_passwd *smb_pass,
+ user_struct *vuser)
+{
+ if ((id2->lm_chal_resp.str_str_len == 24 ||
+ id2->lm_chal_resp.str_str_len == 0) &&
+ id2->nt_chal_resp.str_str_len == 24 &&
+ (((smb_pass->smb_nt_passwd != NULL) &&
+ smb_password_check(id2->nt_chal_resp.buffer, smb_pass->smb_nt_passwd,
+ id2->lm_chal)) ||
+ smb_password_check(id2->lm_chal_resp.buffer, smb_pass->smb_passwd,
+ id2->lm_chal)))
+ {
+ return 0x0;
+ }
+ return 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
+}
+
+/*************************************************************************
+ api_net_sam_logon:
+ *************************************************************************/
+static void api_net_sam_logon( int uid,
+ prs_struct *data,
+ prs_struct *rdata)
+{
+ NET_Q_SAM_LOGON q_l;
+ NET_ID_INFO_CTR ctr;
+ NET_USER_INFO_3 usr_info;
+ uint32 status = 0x0;
+ DOM_CRED srv_cred;
+ struct smb_passwd *smb_pass = NULL;
+ UNISTR2 *uni_samlogon_user = NULL;
+
+ user_struct *vuser = NULL;
+
+ if ((vuser = get_valid_user_struct(uid)) == NULL) return;
+
+ q_l.sam_id.ctr = &ctr;
+
+ net_io_q_sam_logon("", &q_l, data, 0);
+
+ /* checks and updates credentials. creates reply credentials */
+ if (!deal_with_creds(vuser->dc.sess_key, &(vuser->dc.clnt_cred),
+ &(q_l.sam_id.client.cred), &srv_cred))
+ {
+ status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+ }
+ else
+ {
+ memcpy(&(vuser->dc.srv_cred), &(vuser->dc.clnt_cred), sizeof(vuser->dc.clnt_cred));
+ }
+
+ /* find the username */
+
+ if (status == 0x0)
+ {
+ switch (q_l.sam_id.logon_level)
+ {
+ case 1:
+ {
+ uni_samlogon_user = &(q_l.sam_id.ctr->auth.id1.uni_user_name);
+ pstrcpy(samlogon_user, unistrn2(uni_samlogon_user->buffer,
+ uni_samlogon_user->uni_str_len));
+
+ DEBUG(3,("SAM Logon (Interactive). Domain:[%s]. User:[%s]\n",
+ lp_workgroup(), samlogon_user));
+ break;
+ }
+ case 2:
+ {
+ uni_samlogon_user = &(q_l.sam_id.ctr->auth.id2.uni_user_name);
+ pstrcpy(samlogon_user, unistrn2(uni_samlogon_user->buffer,
+ uni_samlogon_user->uni_str_len));
+
+ DEBUG(3,("SAM Logon (Network). Domain:[%s]. User:[%s]\n",
+ lp_workgroup(), samlogon_user));
+ break;
+ }
+ default:
+ {
+ DEBUG(2,("SAM Logon: unsupported switch value\n"));
+ status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
+ break;
+ }
+ }
+ }
+
+ /* check username exists */
+
+ if (status == 0x0)
+ {
+ pstrcpy(samlogon_user, unistrn2(uni_samlogon_user->buffer,
+ uni_samlogon_user->uni_str_len));
+
+ become_root(True);
+ smb_pass = get_smbpwd_entry(samlogon_user, 0);
+ unbecome_root(True);
+
+ if (smb_pass == NULL)
+ {
+ status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
+ }
+ }
+
+ /* validate password. */
+
+ if (status == 0x0)
+ {
+ switch (q_l.sam_id.logon_level)
+ {
+ case 1:
+ {
+ /* interactive login. passwords arcfour'd with session key */
+ status = net_login_interactive(&q_l.sam_id.ctr->auth.id1,
+ smb_pass, vuser);
+ break;
+ }
+ case 2:
+ {
+ /* network login. lm challenge and 24 byte responses */
+ status = net_login_network(&q_l.sam_id.ctr->auth.id2,
+ smb_pass, vuser);
+ break;
+ }
+ }
+ }
+
+ /* lkclXXXX this is the point at which, if the login was
+ successful, that the SAM Local Security Authority should
+ record that the user is logged in to the domain.
+ */
+
+ /* return the profile plus other bits :-) */
+
+ if (status == 0x0)
+ {
+ DOM_GID gids[LSA_MAX_GROUPS];
+ int num_gids = 0;
+ NTTIME dummy_time;
+ pstring logon_script;
+ pstring profile_path;
+ pstring home_dir;
+ pstring home_drive;
+ pstring my_name;
+ pstring my_workgroup;
+ pstring domain_groups;
+ pstring dom_sid;
+ pstring other_sids;
+ extern pstring myname;
+ uint32 r_uid;
+ uint32 r_gid;
+
+ /* set up pointer indicating user/password failed to be found */
+ usr_info.ptr_user_info = 0;
+
+ dummy_time.low = 0xffffffff;
+ dummy_time.high = 0x7fffffff;
+
+ get_myname(myname, NULL);
+
+ /* XXXX hack to get standard_sub_basic() to use sam logon username */
+ /* possibly a better way would be to do a become_user() call */
+ sam_logon_in_ssb = True;
+
+ pstrcpy(logon_script, lp_logon_script ());
+ pstrcpy(profile_path, lp_logon_path ());
+ pstrcpy(dom_sid , lp_domain_sid ());
+ pstrcpy(other_sids , lp_domain_other_sids());
+ pstrcpy(my_workgroup, lp_workgroup ());
+
+ pstrcpy(home_drive , lp_logon_drive ());
+ pstrcpy(home_dir , lp_logon_home ());
+
+ pstrcpy(my_name , myname );
+ strupper(my_name);
+
+ get_domain_user_groups(domain_groups, samlogon_user);
+
+ num_gids = make_dom_gids(domain_groups, gids);
+
+ sam_logon_in_ssb = False;
+
+ if (name_to_rid(samlogon_user, &r_uid, &r_gid))
+ {
+ make_net_user_info3(&usr_info,
+
+ &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 */
+
+ samlogon_user , /* user_name */
+ vuser->real_name, /* full_name */
+ logon_script , /* logon_script */
+ profile_path , /* profile_path */
+ home_dir , /* home_dir */
+ home_drive , /* dir_drive */
+
+ 0, /* logon_count */
+ 0, /* bad_pw_count */
+
+ r_uid , /* RID user_id */
+ r_gid , /* RID group_id */
+ num_gids, /* uint32 num_groups */
+ gids , /* DOM_GID *gids */
+ 0x20 , /* uint32 user_flgs (?) */
+
+ NULL, /* char sess_key[16] */
+
+ my_name , /* char *logon_srv */
+ my_workgroup, /* char *logon_dom */
+
+ dom_sid, /* char *dom_sid */
+ other_sids); /* char *other_sids */
+ }
+ else
+ {
+ status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
+ }
+ }
+
+ net_reply_sam_logon(&q_l, rdata, &srv_cred, &usr_info, status);
+}
+
+
+/*************************************************************************
+ api_net_trust_dom_list:
+ *************************************************************************/
+static void api_net_trust_dom_list( int uid,
+ prs_struct *data,
+ prs_struct *rdata)
+{
+ NET_Q_TRUST_DOM_LIST q_t;
+
+ char *trusted_domain = "test_domain";
+
+ DEBUG(6,("api_net_trust_dom_list: %d\n", __LINE__));
+
+ /* grab the lsa trusted domain list query... */
+ net_io_q_trust_dom("", &q_t, data, 0);
+
+ /* construct reply. */
+ net_reply_trust_dom_list(&q_t, rdata,
+ 1, trusted_domain);
+
+ DEBUG(6,("api_net_trust_dom_list: %d\n", __LINE__));
+}
+
+
+/*************************************************************************
+ error messages cropping up when using nltest.exe...
+ *************************************************************************/
+#define ERROR_NO_SUCH_DOMAIN 0x54b
+#define ERROR_NO_LOGON_SERVERS 0x51f
+
+/*************************************************************************
+ api_net_logon_ctrl2:
+ *************************************************************************/
+static void api_net_logon_ctrl2( int uid,
+ prs_struct *data,
+ prs_struct *rdata)
+{
+ NET_Q_LOGON_CTRL2 q_l;
+
+ /* lkclXXXX - guess what - absolutely no idea what these are! */
+ uint32 flags = 0x0;
+ uint32 pdc_connection_status = 0x0;
+ uint32 logon_attempts = 0x0;
+ uint32 tc_status = ERROR_NO_LOGON_SERVERS;
+ char *trusted_domain = "test_domain";
+
+ DEBUG(6,("api_net_logon_ctrl2: %d\n", __LINE__));
+
+ /* grab the lsa netlogon ctrl2 query... */
+ net_io_q_logon_ctrl2("", &q_l, data, 0);
+
+ /* construct reply. */
+ net_reply_logon_ctrl2(&q_l, rdata,
+ flags, pdc_connection_status, logon_attempts,
+ tc_status, trusted_domain);
+
+ DEBUG(6,("api_net_logon_ctrl2: %d\n", __LINE__));
+}
+
+/*******************************************************************
+ array of \PIPE\NETLOGON operations
+ ********************************************************************/
+static struct api_struct api_net_cmds [] =
+{
+ { "NET_REQCHAL" , NET_REQCHAL , api_net_req_chal },
+ { "NET_AUTH2" , NET_AUTH2 , api_net_auth_2 },
+ { "NET_SRVPWSET" , NET_SRVPWSET , api_net_srv_pwset },
+ { "NET_SAMLOGON" , NET_SAMLOGON , api_net_sam_logon },
+ { "NET_SAMLOGOFF" , NET_SAMLOGOFF , api_net_sam_logoff },
+ { "NET_LOGON_CTRL2" , NET_LOGON_CTRL2 , api_net_logon_ctrl2 },
+ { "NET_TRUST_DOM_LIST", NET_TRUST_DOM_LIST, api_net_trust_dom_list },
+ { NULL , 0 , NULL }
+};
+
+/*******************************************************************
+ receives a netlogon pipe and responds.
+ ********************************************************************/
+BOOL api_netlog_rpc(pipes_struct *p, prs_struct *data)
+{
+ return api_rpcTNP(p, "api_netlog_rpc", api_net_cmds, data);
+}
diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c
new file mode 100644
index 0000000000..e4893fee89
--- /dev/null
+++ b/source3/rpc_server/srv_pipe_hnd.c
@@ -0,0 +1,315 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-1997,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+
+
+#define PIPE "\\PIPE\\"
+#define PIPELEN strlen(PIPE)
+
+extern int DEBUGLEVEL;
+static int chain_pnum = -1;
+
+#ifndef MAX_OPEN_PIPES
+#define MAX_OPEN_PIPES 50
+#endif
+
+#define PIPE_HANDLE_OFFSET 0x800
+
+pipes_struct Pipes[MAX_OPEN_PIPES];
+
+#define P_OPEN(p) ((p)->open)
+#define P_OK(p,c) (P_OPEN(p) && (c)==((p)->cnum))
+#define VALID_PNUM(pnum) (((pnum) >= 0) && ((pnum) < MAX_OPEN_PIPES))
+#define OPEN_PNUM(pnum) (VALID_PNUM(pnum) && P_OPEN(&(Pipes[pnum])))
+#define PNUM_OK(pnum,c) (OPEN_PNUM(pnum) && (c)==Pipes[pnum].cnum)
+
+
+/****************************************************************************
+ reset pipe chain handle number
+****************************************************************************/
+void reset_chain_pnum(void)
+{
+ chain_pnum = -1;
+}
+
+/****************************************************************************
+ sets chain pipe-file handle
+****************************************************************************/
+void set_chain_pnum(int new_pnum)
+{
+ chain_pnum = new_pnum;
+}
+
+/****************************************************************************
+ initialise pipe handle states...
+****************************************************************************/
+void init_rpc_pipe_hnd(void)
+{
+ int i;
+ /* we start at 1 here for an obscure reason I can't now remember,
+ but I think is important :-) */
+ for (i = 1; i < MAX_OPEN_PIPES; i++)
+ {
+ Pipes[i].open = False;
+ Pipes[i].name[0] = 0;
+ Pipes[i].pipe_srv_name[0] = 0;
+
+ Pipes[i].rhdr.data = NULL;
+ Pipes[i].rdata.data = NULL;
+ Pipes[i].rhdr.offset = 0;
+ Pipes[i].rdata.offset = 0;
+
+ Pipes[i].max_rdata_len = 0;
+ Pipes[i].hdr_offsets = 0;
+ }
+
+ return;
+}
+
+/****************************************************************************
+ find first available file slot
+****************************************************************************/
+int open_rpc_pipe_hnd(char *pipe_name, int cnum, uint16 vuid)
+{
+ int i;
+ /* we start at 1 here for an obscure reason I can't now remember,
+ but I think is important :-) */
+ for (i = 1; i < MAX_OPEN_PIPES; i++)
+ {
+ if (!Pipes[i].open)
+ {
+ Pipes[i].open = True;
+ Pipes[i].device_state = 0;
+ Pipes[i].cnum = cnum;
+ Pipes[i].uid = vuid;
+
+ Pipes[i].rhdr.data = NULL;
+ Pipes[i].rdata.data = NULL;
+ Pipes[i].rhdr.offset = 0;
+ Pipes[i].rdata.offset = 0;
+
+ Pipes[i].max_rdata_len = 0;
+ Pipes[i].hdr_offsets = 0;
+
+ fstrcpy(Pipes[i].name, pipe_name);
+
+ DEBUG(4,("Opened pipe %s with handle %x\n",
+ pipe_name, i + PIPE_HANDLE_OFFSET));
+
+ set_chain_pnum(i);
+
+ return(i);
+ }
+ }
+
+ DEBUG(1,("ERROR! Out of pipe structures - perhaps increase MAX_OPEN_PIPES?\n"));
+
+ return(-1);
+}
+
+/****************************************************************************
+ reads data from a pipe.
+
+ headers are interspersed with the data at regular intervals. by the time
+ this function is called, the start of the data could possibly have been
+ read by an SMBtrans (max_rdata_len != 0).
+
+ calling create_rpc_request() here is a fudge. the data should already
+ have been prepared into arrays of headers + data stream sections.
+
+ ****************************************************************************/
+int read_pipe(uint16 pnum, char *data, uint32 pos, int n)
+{
+ int data_pos = pos;
+ pipes_struct *p = &Pipes[pnum - PIPE_HANDLE_OFFSET];
+ DEBUG(6,("read_pipe: %x", pnum));
+
+ if (VALID_PNUM(pnum - PIPE_HANDLE_OFFSET))
+ {
+ DEBUG(6,("name: %s cnum: %d open: %s data_pos: %lx len: %lx",
+ p->name,
+ p->cnum,
+ BOOLSTR(p->open),
+ data_pos, n));
+ }
+
+ if (OPEN_PNUM(pnum - PIPE_HANDLE_OFFSET))
+ {
+ int num;
+ int len;
+ uint32 rpc_frag_pos;
+
+ DEBUG(6,("OK\n"));
+
+ if (p->rhdr.data == NULL || p->rhdr.data->data == NULL ||
+ p->rhdr.data->data_used == 0)
+ {
+ return 0;
+ }
+
+ /* the read request starts from where the SMBtrans2 left off. */
+ data_pos += p->max_rdata_len;
+
+ /* headers accumulate an offset */
+ data_pos -= p->hdr_offsets;
+
+ len = mem_buf_len(p->rhdr.data);
+ num = len - (int)data_pos;
+
+ if (num > n) num = n;
+
+ if (!IS_BITS_SET_ALL(p->hdr.flags, RPC_FLG_LAST))
+ {
+ rpc_frag_pos = data_pos % p->hdr.frag_len;
+
+ if (rpc_frag_pos == 0)
+ {
+ /* create and copy in a new header. */
+ create_rpc_reply(p, data_pos, p->rdata.offset);
+ mem_buf_copy(data, p->rhdr.data, 0, 0x18);
+
+ /* make room in data stream for header */
+ p->hdr_offsets += 0x18;
+ }
+ }
+
+ if (num > 0)
+ {
+ mem_buf_copy(data, p->rhdr.data, data_pos, num);
+ return num;
+ }
+
+ return 0;
+
+ }
+ else
+ {
+ DEBUG(6,("NOT\n"));
+ return -1;
+ }
+}
+
+/****************************************************************************
+ gets the name of a pipe
+****************************************************************************/
+BOOL get_rpc_pipe(int pnum, pipes_struct **p)
+{
+ DEBUG(6,("get_rpc_pipe: "));
+
+ /* mapping is PIPE_HANDLE_OFFSET up... */
+
+ if (VALID_PNUM(pnum - PIPE_HANDLE_OFFSET))
+ {
+ DEBUG(6,("name: %s cnum: %d open: %s ",
+ Pipes[pnum - PIPE_HANDLE_OFFSET].name,
+ Pipes[pnum - PIPE_HANDLE_OFFSET].cnum,
+ BOOLSTR(Pipes[pnum - PIPE_HANDLE_OFFSET].open)));
+ }
+ if (OPEN_PNUM(pnum - PIPE_HANDLE_OFFSET))
+ {
+ DEBUG(6,("OK\n"));
+ (*p) = &(Pipes[pnum - PIPE_HANDLE_OFFSET]);
+ return True;
+ }
+ else
+ {
+ DEBUG(6,("NOT\n"));
+ return False;
+ }
+}
+
+/****************************************************************************
+ gets the name of a pipe
+****************************************************************************/
+char *get_rpc_pipe_hnd_name(int pnum)
+{
+ pipes_struct *p = NULL;
+ get_rpc_pipe(pnum, &p);
+ return p != NULL ? p->name : NULL;
+}
+
+/****************************************************************************
+ set device state on a pipe. exactly what this is for is unknown...
+****************************************************************************/
+BOOL set_rpc_pipe_hnd_state(pipes_struct *p, uint16 device_state)
+{
+ if (p == NULL) return False;
+
+ if (P_OPEN(p))
+ {
+ DEBUG(3,("%s Setting pipe device state=%x on pipe (name=%s cnum=%d)\n",
+ timestring(), device_state, p->name, p->cnum));
+
+ p->device_state = device_state;
+
+ return True;
+ }
+ else
+ {
+ DEBUG(3,("%s Error setting pipe device state=%x (name=%s cnum=%d)\n",
+ timestring(), device_state, p->name, p->cnum));
+ return False;
+ }
+}
+
+/****************************************************************************
+ close an rpc pipe
+****************************************************************************/
+BOOL close_rpc_pipe_hnd(int pnum, int cnum)
+{
+ pipes_struct *p = NULL;
+ get_rpc_pipe(pnum, &p);
+ /* mapping is PIPE_HANDLE_OFFSET up... */
+
+ if (p != NULL && P_OK(p, cnum))
+ {
+ DEBUG(3,("%s Closed pipe name %s pnum=%x cnum=%d\n",
+ timestring(),Pipes[pnum-PIPE_HANDLE_OFFSET].name, pnum,cnum));
+
+ p->open = False;
+
+ p->rdata.offset = 0;
+ p->rhdr.offset = 0;
+ mem_buf_free(&(p->rdata.data));
+ mem_buf_free(&(p->rhdr .data));
+
+ return True;
+ }
+ else
+ {
+ DEBUG(3,("%s Error closing pipe pnum=%x cnum=%d\n",
+ timestring(),pnum, cnum));
+ return False;
+ }
+}
+
+/****************************************************************************
+ close an rpc pipe
+****************************************************************************/
+int get_rpc_pipe_num(char *buf, int where)
+{
+ return (chain_pnum != -1 ? chain_pnum : SVAL(buf,where));
+}
+
diff --git a/source3/rpc_server/srv_reg.c b/source3/rpc_server/srv_reg.c
new file mode 100644
index 0000000000..fa856f6983
--- /dev/null
+++ b/source3/rpc_server/srv_reg.c
@@ -0,0 +1,240 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-1997,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ * Copyright (C) Paul Ashton 1997.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#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 */
+ bzero(&(r_u.pol.data), 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( int uid, 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_POLICY *q_r,
+ prs_struct *rdata)
+{
+ REG_R_OPEN_POLICY 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_policy("", &r_u, rdata, 0);
+
+ DEBUG(5,("reg_open: %d\n", __LINE__));
+}
+
+/*******************************************************************
+ api_reg_open
+ ********************************************************************/
+static void api_reg_open( int uid, prs_struct *data,
+ prs_struct *rdata )
+{
+ REG_Q_OPEN_POLICY q_u;
+
+ /* grab the reg open */
+ reg_io_q_open_policy("", &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( int uid, 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( int uid, 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_POLICY , 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);
+}
+
diff --git a/source3/rpc_server/srv_samr.c b/source3/rpc_server/srv_samr.c
new file mode 100644
index 0000000000..02c8cb0ffe
--- /dev/null
+++ b/source3/rpc_server/srv_samr.c
@@ -0,0 +1,1352 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-1997,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ * Copyright (C) Paul Ashton 1997.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+
+extern BOOL sam_logon_in_ssb;
+extern pstring samlogon_user;
+extern rid_name domain_group_rids[];
+extern rid_name domain_alias_rids[];
+
+/*******************************************************************
+ This next function should be replaced with something that
+ dynamically returns the correct user info..... JRA.
+ ********************************************************************/
+
+static BOOL get_smbpwd_entries(SAM_USER_INFO_21 *pw_buf,
+ int *total_entries, int *num_entries,
+ int max_num_entries,
+ uint16 acb_mask)
+{
+ FILE *fp = NULL;
+ struct smb_passwd *pwd = NULL;
+
+ (*num_entries) = 0;
+ (*total_entries) = 0;
+
+ if (pw_buf == NULL) return False;
+
+ fp = startsmbpwent(False);
+ if (!fp)
+ {
+ DEBUG(0, ("get_smbpwd_entries: Unable to open SMB password file.\n"));
+ return False;
+ }
+
+ while (((pwd = getsmbpwent(fp)) != NULL) && (*num_entries) < max_num_entries)
+ {
+ int 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->smb_userid;
+ bzero( pw_buf[(*num_entries)].nt_pwd , 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, ("get_smbpwd_entries: idx: %d user %s, uid %d, acb %x",
+ (*num_entries), pwd->smb_name, pwd->smb_userid, 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(fp);
+
+ 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 */
+ bzero(&(r_u.pol.data), 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( int uid, 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;
+ int pol_idx;
+
+ r_u.status = 0x0;
+
+ /* find the connection policy handle. */
+ if (r_u.status == 0x0 && ((pol_idx = 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( int uid, 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_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];
+ fstring user_sid;
+ fstring user_rid;
+ int pol_idx;
+ uint32 rid;
+ uint32 status;
+
+ status = 0x0;
+
+ /* find the policy handle. open a policy on it. */
+ if (status == 0x0 && ((pol_idx = 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)
+ {
+ strcpy(user_sid, lp_domain_sid());
+ sprintf(user_rid, "-%x", rid);
+ strcat(user_sid, user_rid);
+
+ /* maybe need another 1 or 2 (S-1-5-20-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, "S-1-1");
+ 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( int uid, 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;
+ int pol_idx;
+ BOOL got_pwds;
+
+ r_e.status = 0x0;
+ r_e.total_num_entries = 0;
+
+ /* find the policy handle. open a policy on it. */
+ if (r_e.status == 0x0 && ((pol_idx = 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);
+ got_pwds = get_smbpwd_entries(pass, &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( int uid, 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;
+ int pol_idx;
+ 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 && ((pol_idx = 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( int uid, 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;
+ int pol_idx;
+ BOOL got_aliases;
+ char *dummy_alias = "admins";
+
+ r_e.status = 0x0;
+ r_e.num_entries = 0;
+
+ /* find the policy handle. open a policy on it. */
+ if (r_e.status == 0x0 && ((pol_idx = find_lsa_policy_by_hnd(&(q_u->pol))) == -1))
+ {
+ r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+ }
+
+ DEBUG(5,("samr_reply_enum_dom_aliases: %d\n", __LINE__));
+
+ got_aliases = True;
+ num_entries = 1;
+ make_unistr2(&(pass[0].uni_user_name), dummy_alias, strlen(dummy_alias));
+ pass[0].user_rid = DOMAIN_ALIAS_RID_ADMINS;
+
+ if (r_e.status == 0 && got_aliases)
+ {
+ 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( int uid, 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;
+ int total_entries;
+ int pol_idx;
+ BOOL got_pwds;
+ uint16 switch_level = 0x0;
+
+ r_e.status = 0x0;
+
+ /* find the policy handle. open a policy on it. */
+ if (r_e.status == 0x0 && ((pol_idx = find_lsa_policy_by_hnd(&(q_u->pol))) == -1))
+ {
+ r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+ }
+
+ DEBUG(5,("samr_reply_query_dispinfo: %d\n", __LINE__));
+
+ become_root(True);
+
+ got_pwds = get_smbpwd_entries(pass, &total_entries, &num_entries, MAX_SAM_ENTRIES, 0);
+
+ unbecome_root(True);
+
+ switch (q_u->switch_level)
+ {
+ case 0x1:
+ {
+ /* query disp info is for users */
+ make_sam_info_1(&info1, ACB_NORMAL,
+ q_u->start_idx, num_entries, pass);
+
+ ctr.sam.info1 = &info1;
+ switch_level = 0x1;
+
+ break;
+ }
+ case 0x2:
+ {
+ /* query disp info is for servers */
+ make_sam_info_2(&info2, ACB_WSTRUST,
+ q_u->start_idx, num_entries, pass);
+
+ ctr.sam.info2 = &info2;
+ switch_level = 0x2;
+
+ 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( int uid, 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;
+ int pol_idx;
+ BOOL got_alias;
+
+ r_e.status = 0x0;
+ r_e.ptr = 0;
+
+ /* find the policy handle. open a policy on it. */
+ if (r_e.status == 0x0 && ((pol_idx = 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;
+ }
+ }
+
+ if (r_e.status == 0x0)
+ {
+ got_alias = True;
+ }
+
+ 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( int uid, 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;
+ for (i = 0; i < num_rids && status == 0; i++)
+ {
+ struct smb_passwd *smb_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);
+ smb_pass = get_smbpwd_entry(user_name, 0);
+ unbecome_root(True);
+
+ if (smb_pass == NULL)
+ {
+ status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
+ rid[i] = 0;
+ }
+ else
+ {
+ /* lkclXXXX SHOULD use name_to_rid() here! */
+ rid[i] = smb_pass->smb_userid;
+ }
+ }
+#endif
+
+ num_rids = 1;
+ rid[0] = DOMAIN_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( int uid, 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));
+ }
+
+ 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( int uid, 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_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;
+ uint32 pol_idx;
+
+ 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 && ((pol_idx = 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( int uid, 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 smb_passwd *smb_pass;
+ int pol_idx;
+ BOOL pol_open = False;
+
+ /* set up the SAMR open_user response */
+ bzero(&(r_u.user_pol.data), POL_HND_SIZE);
+
+ r_u.status = 0x0;
+
+ /* find the policy handle. open a policy on it. */
+ if (r_u.status == 0x0 && ((pol_idx = 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);
+ smb_pass = get_smbpwd_entry(NULL, q_u->user_rid);
+ unbecome_root(True);
+
+ /* check that the RID exists in our domain. */
+ if (r_u.status == 0x0 && smb_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( int uid, 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_21
+ *************************************************************************/
+static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 rid)
+{
+ NTTIME dummy_time;
+
+ pstring logon_script;
+ pstring profile_path;
+ pstring home_drive;
+ pstring home_dir;
+ pstring description;
+ pstring workstations;
+ pstring full_name;
+ pstring munged_dialin;
+ pstring unknown_str;
+
+ uint32 r_uid;
+ uint32 r_gid;
+
+ LOGON_HRS hrs;
+ int i;
+
+ struct smb_passwd *smb_pass;
+
+ become_root(True);
+ smb_pass = get_smbpwd_entry(NULL, rid);
+ unbecome_root(True);
+
+ if (smb_pass == NULL)
+ {
+ return False;
+ }
+
+ DEBUG(3,("User:[%s]\n", smb_pass->smb_name));
+
+ dummy_time.low = 0xffffffff;
+ dummy_time.high = 0x7fffffff;
+
+ pstrcpy(samlogon_user, smb_pass->smb_name);
+
+ if (samlogon_user[strlen(samlogon_user)-1] != '$')
+ {
+ if (!name_to_rid(samlogon_user, &r_uid, &r_gid))
+ {
+ return False;
+ }
+
+ /* XXXX hack to get standard_sub_basic() to use sam logon username */
+ /* possibly a better way would be to do a become_user() call */
+ sam_logon_in_ssb = True;
+
+ pstrcpy(full_name , "<Full Name>");
+ pstrcpy(logon_script , lp_logon_script ());
+ pstrcpy(profile_path , lp_logon_path ());
+ pstrcpy(home_drive , lp_logon_drive ());
+ pstrcpy(home_dir , lp_logon_home ());
+ pstrcpy(description , "<Description>");
+ pstrcpy(workstations , "");
+ pstrcpy(unknown_str , "");
+ pstrcpy(munged_dialin, "");
+
+ sam_logon_in_ssb = False;
+ }
+ else
+ {
+ r_uid = smb_pass->smb_userid;
+ r_gid = DOMAIN_GROUP_RID_USERS;
+
+ pstrcpy(samlogon_user, smb_pass->smb_name);
+
+ pstrcpy(full_name , "");
+ pstrcpy(logon_script , "");
+ pstrcpy(profile_path , "");
+ pstrcpy(home_drive , "");
+ pstrcpy(home_dir , "");
+ pstrcpy(description , "");
+ pstrcpy(workstations , "");
+ pstrcpy(unknown_str , "");
+ pstrcpy(munged_dialin, "");
+ }
+
+ hrs.len = 21;
+ for (i = 0; i < hrs.len; i++)
+ {
+ hrs.hours[i] = 0xff;
+ }
+ 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 */
+
+ samlogon_user, /* user_name */
+ full_name, /* full_name */
+ home_dir, /* home_dir */
+ home_drive, /* dir_drive */
+ logon_script, /* logon_script */
+ profile_path, /* profile_path */
+ description, /* description */
+ workstations, /* workstations user can log in from */
+ unknown_str, /* don't know, yet */
+ munged_dialin, /* dialin info. contains dialin path and tel no */
+
+ r_uid, /* RID user_id */
+ r_gid, /* RID group_id */
+ smb_pass->acct_ctrl,
+
+ 0x00ffffff, /* unknown_3 */
+ 168, /* divisions per week */
+ &hrs, /* logon hours */
+ 0x00020000,
+ 0x000004ec);
+
+ 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_21 id21;
+ void *info = NULL;
+
+ uint32 status = 0x0;
+ uint32 rid;
+ int obj_idx;
+
+ DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
+
+ /* search for the handle */
+ if (status == 0x0 && (obj_idx = 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;
+ }
+
+ /* ok! user info levels (there are lots: see MSDEV help), off we go... */
+ if (status == 0x0)
+ {
+ switch (q_u->switch_value)
+ {
+#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( int uid, 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 smb_passwd *smb_pass;
+ DOM_GID gids[LSA_MAX_GROUPS];
+ int num_groups = 0;
+ int pol_idx;
+ uint32 rid;
+
+ DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
+
+ /* find the policy handle. open a policy on it. */
+ if (status == 0x0 && ((pol_idx = 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);
+ smb_pass = get_smbpwd_entry(NULL, rid);
+ unbecome_root(True);
+
+ if (smb_pass == NULL)
+ {
+ status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
+ }
+ }
+
+ if (status == 0x0)
+ {
+ pstring groups;
+ get_domain_user_groups(groups, smb_pass->smb_name);
+ 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);
+
+ DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
+
+}
+
+/*******************************************************************
+ api_samr_query_usergroups
+ ********************************************************************/
+static void api_samr_query_usergroups( int uid, 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_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 */
+ bzero(&(r_u.pol.data), 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( int uid, prs_struct *data, prs_struct *rdata)
+{
+ uint32 status = 0;
+ struct smb_passwd *smb_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);
+ smb_pass = get_smbpwd_entry(mach_acct, 0);
+ unbecome_root(True);
+
+ if (smb_pass != NULL)
+ {
+ /* machine account exists: say so */
+ status = 0xC0000000 | NT_STATUS_USER_EXISTS;
+ }
+ else
+ {
+ /* this could cause trouble... */
+ status = 0;
+ }
+
+ /* construct reply. */
+ samr_reply_unknown_32(&q_u, rdata, status);
+}
+
+
+/*******************************************************************
+ 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( int uid, 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( int uid, 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_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_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_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 },
+ { 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);
+}
+
diff --git a/source3/rpc_server/srv_srvsvc.c b/source3/rpc_server/srv_srvsvc.c
new file mode 100644
index 0000000000..285ea89657
--- /dev/null
+++ b/source3/rpc_server/srv_srvsvc.c
@@ -0,0 +1,1015 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-1997,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ * Copyright (C) Paul Ashton 1997.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+
+
+/*******************************************************************
+ fill in a share 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.
+
+ see ipc.c:fill_share_info()
+
+ ********************************************************************/
+static void make_srv_share_1_info(SH_INFO_1 *sh1,
+ SH_INFO_1_STR *str1, int snum)
+{
+ int len_net_name;
+ pstring net_name;
+ pstring remark;
+ uint32 type;
+
+ pstrcpy(net_name, lp_servicename(snum));
+ strupper(net_name);
+ pstrcpy(remark , lp_comment (snum));
+ len_net_name = strlen(net_name);
+
+ /* work out the share type */
+ type = STYPE_DISKTREE;
+
+ if (lp_print_ok(snum)) type = STYPE_PRINTQ;
+ if (strequal("IPC$", net_name)) type = STYPE_IPC;
+ if (net_name[len_net_name] == '$') type |= STYPE_HIDDEN;
+
+ make_srv_share_info1 (sh1 , net_name, type, remark);
+ make_srv_share_info1_str(str1, net_name, remark);
+}
+
+/*******************************************************************
+ fill in a share 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_share_info_1(SRV_SHARE_INFO_1 *sh1, uint32 *snum, uint32 *svcs)
+{
+ uint32 num_entries = 0;
+ (*svcs) = lp_numservices();
+
+ if (sh1 == NULL)
+ {
+ (*snum) = 0;
+ return;
+ }
+
+ DEBUG(5,("make_srv_share_1_sh1\n"));
+
+ for (; (*snum) < (*svcs) && num_entries < MAX_SHARE_ENTRIES; (*snum)++)
+ {
+ if (lp_browseable((*snum)) && lp_snum_ok((*snum)))
+ {
+ make_srv_share_1_info(&(sh1->info_1 [num_entries]),
+ &(sh1->info_1_str[num_entries]), (*snum));
+
+ /* move on to creating next share */
+ num_entries++;
+ }
+ }
+
+ sh1->num_entries_read = num_entries;
+ sh1->ptr_share_info = num_entries > 0 ? 1 : 0;
+ sh1->num_entries_read2 = num_entries;
+
+ if ((*snum) >= (*svcs))
+ {
+ (*snum) = 0;
+ }
+}
+
+/*******************************************************************
+ fill in a share info level 2 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.
+
+ see ipc.c:fill_share_info()
+
+ ********************************************************************/
+static void make_srv_share_2_info(SH_INFO_2 *sh2,
+ SH_INFO_2_STR *str2, int snum)
+{
+ int len_net_name;
+ pstring net_name;
+ pstring remark;
+ pstring path;
+ pstring passwd;
+ uint32 type;
+
+ pstrcpy(net_name, lp_servicename(snum));
+ pstrcpy(remark , lp_comment (snum));
+ pstrcpy(path , lp_pathname (snum));
+ pstrcpy(passwd , "");
+ len_net_name = strlen(net_name);
+
+ /* work out the share type */
+ type = STYPE_DISKTREE;
+
+ if (lp_print_ok(snum)) type = STYPE_PRINTQ;
+ if (strequal("IPC$", net_name)) type = STYPE_IPC;
+ if (net_name[len_net_name] == '$') type |= STYPE_HIDDEN;
+
+ make_srv_share_info2 (sh2 , net_name, type, remark, 0, 0xffffffff, 1, path, passwd);
+ make_srv_share_info2_str(str2, net_name, remark, path, passwd);
+}
+
+/*******************************************************************
+ fill in a share info level 2 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_share_info_2(SRV_SHARE_INFO_2 *sh2, uint32 *snum, uint32 *svcs)
+{
+ uint32 num_entries = 0;
+ (*svcs) = lp_numservices();
+
+ if (sh2 == NULL)
+ {
+ (*snum) = 0;
+ return;
+ }
+
+ DEBUG(5,("make_srv_share_2_sh1\n"));
+
+ for (; (*snum) < (*svcs) && num_entries < MAX_SHARE_ENTRIES; (*snum)++)
+ {
+ if (lp_browseable((*snum)) && lp_snum_ok((*snum)))
+ {
+ make_srv_share_2_info(&(sh2->info_2 [num_entries]),
+ &(sh2->info_2_str[num_entries]), (*snum));
+
+ /* move on to creating next share */
+ num_entries++;
+ }
+ }
+
+ sh2->num_entries_read = num_entries;
+ sh2->ptr_share_info = num_entries > 0 ? 1 : 0;
+ sh2->num_entries_read2 = num_entries;
+
+ if ((*snum) >= (*svcs))
+ {
+ (*snum) = 0;
+ }
+}
+
+/*******************************************************************
+ makes a SRV_R_NET_SHARE_ENUM structure.
+********************************************************************/
+static uint32 make_srv_share_info_ctr(SRV_SHARE_INFO_CTR *ctr,
+ int switch_value, uint32 *resume_hnd, uint32 *total_entries)
+{
+ uint32 status = 0x0;
+ DEBUG(5,("make_srv_share_info_ctr: %d\n", __LINE__));
+
+ ctr->switch_value = switch_value;
+
+ switch (switch_value)
+ {
+ case 1:
+ {
+ make_srv_share_info_1(&(ctr->share.info1), resume_hnd, total_entries);
+ ctr->ptr_share_ctr = 1;
+ break;
+ }
+ case 2:
+ {
+ make_srv_share_info_2(&(ctr->share.info2), resume_hnd, total_entries);
+ ctr->ptr_share_ctr = 2;
+ break;
+ }
+ default:
+ {
+ DEBUG(5,("make_srv_share_info_ctr: unsupported switch value %d\n",
+ switch_value));
+ (*resume_hnd = 0);
+ (*total_entries) = 0;
+ ctr->ptr_share_ctr = 0;
+ status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
+ break;
+ }
+ }
+
+ return status;
+}
+
+/*******************************************************************
+ makes a SRV_R_NET_SHARE_ENUM structure.
+********************************************************************/
+static void make_srv_r_net_share_enum(SRV_R_NET_SHARE_ENUM *r_n,
+ uint32 resume_hnd, int share_level, int switch_value)
+{
+ DEBUG(5,("make_srv_r_net_share_enum: %d\n", __LINE__));
+
+ r_n->share_level = share_level;
+ if (share_level == 0)
+ {
+ r_n->status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
+ }
+ else
+ {
+ r_n->status = make_srv_share_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 share enum
+********************************************************************/
+static void srv_reply_net_share_enum(SRV_Q_NET_SHARE_ENUM *q_n,
+ prs_struct *rdata)
+{
+ SRV_R_NET_SHARE_ENUM r_n;
+ SRV_SHARE_INFO_CTR ctr;
+
+ r_n.ctr = &ctr;
+
+ DEBUG(5,("srv_net_share_enum: %d\n", __LINE__));
+
+ /* set up the */
+ make_srv_r_net_share_enum(&r_n,
+ get_enum_hnd(&q_n->enum_hnd),
+ q_n->share_level,
+ q_n->ctr->switch_value);
+
+ /* store the response in the SMB stream */
+ srv_io_r_net_share_enum("", &r_n, rdata, 0);
+
+ 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 srv_reply_net_srv_get_info(SRV_Q_NET_SRV_GET_INFO *q_n,
+ prs_struct *rdata)
+{
+ SRV_R_NET_SRV_GET_INFO r_n;
+ uint32 status = 0x0;
+ SRV_INFO_CTR ctr;
+
+ extern pstring myname;
+ get_myname(myname,NULL);
+
+ DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
+
+ switch (q_n->switch_value)
+ {
+ case 102:
+ {
+ make_srv_info_102(&ctr.srv.sv102,
+ 500, myname, lp_serverstring(),
+ 5, 4, /* major/minor version - NT 5.4 :-) */
+ 0x4100b, /* browsing stuff SV_TYPE_XXXX */
+ 0xffffffff, /* users */
+ 0xf, /* disc */
+ 0, /* hidden */
+ 240, /* announce */
+ 3000, /* announce delta */
+ 100000, /* licenses */
+ "c:\\"); /* user path */
+ break;
+ }
+ case 101:
+ {
+ make_srv_info_101(&ctr.srv.sv101,
+ 500, myname,
+ 5, 4, /* major/minor version - NT 5.4 :-) */
+ 0x4100b, /* browsing stuff SV_TYPE_XXXX */
+ lp_serverstring());
+ break;
+ }
+ default:
+ {
+ status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
+ break;
+ }
+ }
+
+ /* set up the net server get info structure */
+ make_srv_r_net_srv_get_info(&r_n, q_n->switch_value, &ctr, status);
+
+ /* store the response in the SMB stream */
+ srv_io_r_net_srv_get_info("", &r_n, rdata, 0);
+
+ DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
+}
+
+/*******************************************************************
+********************************************************************/
+static void api_srv_net_srv_get_info( int uid, prs_struct *data,
+ prs_struct *rdata )
+{
+ SRV_Q_NET_SRV_GET_INFO q_n;
+
+ /* grab the net server get info */
+ srv_io_q_net_srv_get_info("", &q_n, data, 0);
+
+ /* construct reply. always indicate success */
+ srv_reply_net_srv_get_info(&q_n, rdata);
+}
+
+
+/*******************************************************************
+********************************************************************/
+static void api_srv_net_file_enum( int uid, 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( int uid, 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( int uid, 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);
+}
+
+
+/*******************************************************************
+********************************************************************/
+static void api_srv_net_share_enum( int uid, prs_struct *data,
+ prs_struct *rdata )
+{
+ SRV_Q_NET_SHARE_ENUM q_n;
+ SRV_SHARE_INFO_CTR ctr;
+
+ q_n.ctr = &ctr;
+
+ /* grab the net server get enum */
+ srv_io_q_net_share_enum("", &q_n, data, 0);
+
+ /* construct reply. always indicate success */
+ srv_reply_net_share_enum(&q_n, rdata);
+}
+
+
+/*******************************************************************
+\PIPE\srvsvc commands
+********************************************************************/
+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 },
+ { NULL , 0 , NULL }
+};
+
+/*******************************************************************
+receives a srvsvc pipe and responds.
+********************************************************************/
+BOOL api_srvsvc_rpc(pipes_struct *p, prs_struct *data)
+{
+ return api_rpcTNP(p, "api_srvsvc_rpc", api_srv_cmds, data);
+}
+
diff --git a/source3/rpc_server/srv_util.c b/source3/rpc_server/srv_util.c
new file mode 100644
index 0000000000..7be259029a
--- /dev/null
+++ b/source3/rpc_server/srv_util.c
@@ -0,0 +1,477 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-1998
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
+ * Copyright (C) Paul Ashton 1997-1998.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* this module apparently provides an implementation of DCE/RPC over a
+ * named pipe (IPC$ connection using SMBtrans). details of DCE/RPC
+ * documentation are available (in on-line form) from the X-Open group.
+ *
+ * this module should provide a level of abstraction between SMB
+ * and DCE/RPC, while minimising the amount of mallocs, unnecessary
+ * data copies, and network traffic.
+ *
+ * in this version, which takes a "let's learn what's going on and
+ * get something running" approach, there is additional network
+ * traffic generated, but the code should be easier to understand...
+ *
+ * ... if you read the docs. or stare at packets for weeks on end.
+ *
+ */
+
+#include "includes.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+
+/* array lookup of well-known RID aliases. the purpose of these escapes me.. */
+/* XXXX this structure should not have the well-known RID groups added to it,
+ i.e the DOMAIN_GROUP_RID_ADMIN/USER/GUEST. */
+rid_name domain_alias_rids[] =
+{
+ { DOMAIN_ALIAS_RID_ADMINS , "admins" },
+ { DOMAIN_ALIAS_RID_USERS , "users" },
+ { DOMAIN_ALIAS_RID_GUESTS , "guests" },
+ { DOMAIN_ALIAS_RID_POWER_USERS , "power_users" },
+
+ { DOMAIN_ALIAS_RID_ACCOUNT_OPS , "account_ops" },
+ { DOMAIN_ALIAS_RID_SYSTEM_OPS , "system_ops" },
+ { DOMAIN_ALIAS_RID_PRINT_OPS , "print_ops" },
+ { DOMAIN_ALIAS_RID_BACKUP_OPS , "backup_ops" },
+ { DOMAIN_ALIAS_RID_REPLICATOR , "replicator" },
+ { 0 , NULL }
+};
+
+/* array lookup of well-known Domain RID groups. */
+rid_name domain_group_rids[] =
+{
+ { DOMAIN_GROUP_RID_ADMINS , "domain admins" },
+ { DOMAIN_GROUP_RID_USERS , "domain users" },
+ { DOMAIN_GROUP_RID_GUESTS , "domain guests" },
+ { 0 , NULL }
+};
+
+
+
+int make_dom_gids(char *gids_str, DOM_GID *gids)
+{
+ char *ptr;
+ pstring s2;
+ int count;
+
+ DEBUG(4,("make_dom_gids: %s\n", gids_str));
+
+ if (gids_str == NULL || *gids_str == 0) return 0;
+
+ for (count = 0, ptr = gids_str; next_token(&ptr, s2, NULL) && count < LSA_MAX_GROUPS; count++)
+ {
+ /* the entries are of the form GID/ATTR, ATTR being optional.*/
+ char *attr;
+ uint32 rid = 0;
+ int i;
+
+ attr = strchr(s2,'/');
+ if (attr) *attr++ = 0;
+ if (!attr || !*attr) attr = "7"; /* default value for attribute is 7 */
+
+ /* look up the RID string and see if we can turn it into a rid number */
+ for (i = 0; domain_alias_rids[i].name != NULL; i++)
+ {
+ if (strequal(domain_alias_rids[i].name, s2))
+ {
+ rid = domain_alias_rids[i].rid;
+ break;
+ }
+ }
+
+ if (rid == 0) rid = atoi(s2);
+
+ if (rid == 0)
+ {
+ DEBUG(1,("make_dom_gids: unknown well-known alias RID %s/%s\n",
+ s2, attr));
+ count--;
+ }
+ else
+ {
+ gids[count].g_rid = rid;
+ gids[count].attr = atoi(attr);
+
+ DEBUG(5,("group id: %d attr: %d\n",
+ gids[count].g_rid,
+ gids[count].attr));
+ }
+ }
+
+ return count;
+}
+
+/*******************************************************************
+ gets a domain user's groups
+ ********************************************************************/
+void get_domain_user_groups(char *domain_groups, char *user)
+{
+ pstring tmp;
+
+ if (domain_groups == NULL || user == NULL) return;
+
+ /* any additional groups this user is in. e.g power users */
+ pstrcpy(domain_groups, lp_domain_groups());
+
+ /* can only be a user or a guest. cannot be guest _and_ admin */
+ if (user_in_list(user, lp_domain_guest_users()))
+ {
+ sprintf(tmp, " %ld/7 ", DOMAIN_GROUP_RID_GUESTS);
+ strcat(domain_groups, tmp);
+
+ DEBUG(3,("domain guest access %s granted\n", tmp));
+ }
+ else
+ {
+ sprintf(tmp, " %ld/7 ", DOMAIN_GROUP_RID_USERS);
+ strcat(domain_groups, tmp);
+
+ DEBUG(3,("domain user access %s granted\n", tmp));
+
+ if (user_in_list(user, lp_domain_admin_users()))
+ {
+ sprintf(tmp, " %ld/7 ", DOMAIN_GROUP_RID_ADMINS);
+ strcat(domain_groups, tmp);
+
+ DEBUG(3,("domain admin access %s granted\n", tmp));
+ }
+ }
+}
+
+
+/*******************************************************************
+ turns a DCE/RPC request into a DCE/RPC reply
+
+ this is where the data really should be split up into an array of
+ headers and data sections.
+
+ ********************************************************************/
+BOOL create_rpc_reply(pipes_struct *p,
+ uint32 data_start, uint32 data_end)
+{
+ mem_buf_init(&(p->rhdr.data), 0);
+ mem_alloc_data(p->rhdr.data, 0x18);
+
+ p->rhdr.align = 4;
+ p->rhdr.io = False;
+
+ p->hdr_rr.alloc_hint = data_end - data_start; /* calculate remaining data to be sent */
+ p->hdr.pkt_type = RPC_RESPONSE; /* mark header as an rpc response */
+
+ /* set up rpc header (fragmentation issues) */
+ if (data_start == 0)
+ {
+ p->hdr.flags = RPC_FLG_FIRST;
+ }
+ else
+ {
+ p->hdr.flags = 0;
+ }
+
+ if (p->hdr_rr.alloc_hint + 0x18 <= p->hdr_ba.bba.max_tsize)
+ {
+ p->hdr.flags |= RPC_FLG_LAST;
+ p->hdr.frag_len = p->hdr_rr.alloc_hint + 0x18;
+ }
+ else
+ {
+ p->hdr.frag_len = p->hdr_ba.bba.max_tsize;
+ }
+
+ p->rhdr.data->offset.start = 0;
+ p->rhdr.data->offset.end = 0x18;
+
+ /* store the header in the data stream */
+ p->rhdr.offset = 0;
+ smb_io_rpc_hdr ("hdr", &(p->hdr ), &(p->rhdr), 0);
+ smb_io_rpc_hdr_rr("rr" , &(p->hdr_rr), &(p->rhdr), 0);
+
+ return p->rhdr.data != NULL && p->rhdr.offset == 0x18;
+}
+
+
+/*******************************************************************
+ receives a netlogon pipe and responds.
+ ********************************************************************/
+static BOOL api_rpc_command(pipes_struct *p,
+ char *rpc_name, struct api_struct *api_rpc_cmds,
+ prs_struct *data)
+{
+ int fn_num;
+ DEBUG(4,("api_rpc_command: %s op 0x%x - ", rpc_name, p->hdr_rr.opnum));
+
+ for (fn_num = 0; api_rpc_cmds[fn_num].name; fn_num++)
+ {
+ if (api_rpc_cmds[fn_num].opnum == p->hdr_rr.opnum && api_rpc_cmds[fn_num].fn != NULL)
+ {
+ DEBUG(3,("api_rpc_command: %s\n", api_rpc_cmds[fn_num].name));
+ break;
+ }
+ }
+
+ if (api_rpc_cmds[fn_num].name == NULL)
+ {
+ DEBUG(4, ("unknown\n"));
+ return False;
+ }
+
+ /* start off with 1024 bytes, and a large safety margin too */
+ mem_buf_init(&(p->rdata.data), SAFETY_MARGIN);
+ mem_alloc_data(p->rdata.data, 1024);
+
+ p->rdata.io = False;
+ p->rdata.align = 4;
+
+ p->rdata.data->offset.start = 0;
+ p->rdata.data->offset.end = 0xffffffff;
+
+ /* do the actual command */
+ p->rdata.offset = 0;
+ api_rpc_cmds[fn_num].fn(p->uid, data, &(p->rdata));
+
+ if (p->rdata.data == NULL || p->rdata.offset == 0)
+ {
+ mem_free_data(p->rdata.data);
+ return False;
+ }
+
+ mem_realloc_data(p->rdata.data, p->rdata.offset);
+
+ DEBUG(10,("called %s\n", rpc_name));
+
+ return True;
+}
+
+
+/*******************************************************************
+ receives a netlogon pipe and responds.
+ ********************************************************************/
+BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, struct api_struct *api_rpc_cmds,
+ prs_struct *data)
+{
+ if (data == NULL || data->data == NULL)
+ {
+ DEBUG(2,("%s: NULL data received\n", rpc_name));
+ return False;
+ }
+
+ /* read the rpc header */
+ smb_io_rpc_hdr_rr("", &(p->hdr_rr), data, 0);
+
+ /* interpret the command */
+ if (!api_rpc_command(p, rpc_name, api_rpc_cmds, data))
+ {
+ return False;
+ }
+
+ /* create the rpc header */
+ if (!create_rpc_reply(p, 0, p->rdata.offset))
+ {
+ return False;
+ }
+
+ /* set up the data chain */
+ p->rhdr.data->offset.start = 0;
+ p->rhdr.data->offset.end = p->rhdr.offset;
+ p->rhdr.data->next = p->rdata.data;
+
+ p->rdata.data->offset.start = p->rhdr.data->offset.end;
+ p->rdata.data->offset.end = p->rhdr.data->offset.end + p->rdata.offset;
+ p->rdata.data->next = NULL;
+
+ return True;
+}
+
+extern rid_name domain_group_rids[];
+
+/*******************************************************************
+ lookup_group_name
+ ********************************************************************/
+uint32 lookup_group_name(uint32 rid, char *group_name, uint32 *type)
+{
+ int i = 0;
+ (*type) = SID_NAME_DOM_GRP;
+
+ while (domain_group_rids[i].rid != rid && domain_group_rids[i].rid != 0)
+ {
+ i++;
+ }
+
+ if (domain_group_rids[i].rid != 0)
+ {
+ fstrcpy(group_name, domain_group_rids[i].name);
+ return 0x0;
+ }
+
+ return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+}
+
+extern rid_name domain_alias_rids[];
+
+/*******************************************************************
+ lookup_alias_name
+ ********************************************************************/
+uint32 lookup_alias_name(uint32 rid, char *alias_name, uint32 *type)
+{
+ int i = 0;
+ (*type) = SID_NAME_WKN_GRP;
+
+ while (domain_alias_rids[i].rid != rid && domain_alias_rids[i].rid != 0)
+ {
+ i++;
+ }
+
+ if (domain_alias_rids[i].rid != 0)
+ {
+ fstrcpy(alias_name, domain_alias_rids[i].name);
+ return 0x0;
+ }
+
+ return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+}
+
+/*******************************************************************
+ lookup_user_name
+ ********************************************************************/
+uint32 lookup_user_name(uint32 rid, char *user_name, uint32 *type)
+{
+ struct smb_passwd *smb_pass;
+ (*type) = SID_NAME_USER;
+
+ /* find the user account */
+ become_root(True);
+ smb_pass = get_smbpwd_entry(NULL, rid); /* lkclXXXX SHOULD use rid mapping here! */
+ unbecome_root(True);
+
+ if (smb_pass != NULL)
+ {
+ fstrcpy(user_name, smb_pass->smb_name);
+ return 0x0;
+ }
+
+ return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+}
+
+/*******************************************************************
+ lookup_group_rid
+ ********************************************************************/
+uint32 lookup_group_rid(char *group_name, uint32 *rid)
+{
+ char *grp_name;
+ int i = -1; /* start do loop at -1 */
+
+ do /* find, if it exists, a group rid for the group name*/
+ {
+ i++;
+ (*rid) = domain_group_rids[i].rid;
+ grp_name = domain_group_rids[i].name;
+
+ } while (grp_name != NULL && !strequal(grp_name, group_name));
+
+ return (grp_name != NULL) ? 0 : 0xC0000000 | NT_STATUS_NONE_MAPPED;
+}
+
+/*******************************************************************
+ lookup_alias_rid
+ ********************************************************************/
+uint32 lookup_alias_rid(char *alias_name, uint32 *rid)
+{
+ char *als_name;
+ int i = -1; /* start do loop at -1 */
+
+ do /* find, if it exists, a alias rid for the alias name*/
+ {
+ i++;
+ (*rid) = domain_alias_rids[i].rid;
+ als_name = domain_alias_rids[i].name;
+
+ } while (als_name != NULL && !strequal(als_name, alias_name));
+
+ return (als_name != NULL) ? 0 : 0xC0000000 | NT_STATUS_NONE_MAPPED;
+}
+
+/*******************************************************************
+ lookup_user_rid
+ ********************************************************************/
+uint32 lookup_user_rid(char *user_name, uint32 *rid)
+{
+ struct smb_passwd *smb_pass;
+ (*rid) = 0;
+
+ /* find the user account */
+ become_root(True);
+ smb_pass = get_smbpwd_entry(user_name, 0);
+ unbecome_root(True);
+
+ if (smb_pass != NULL)
+ {
+ /* lkclXXXX SHOULD use name_to_rid() here! */
+ (*rid) = smb_pass->smb_userid;
+ return 0x0;
+ }
+
+ return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+}
+
+/*******************************************************************
+ Group and User RID username mapping function
+ ********************************************************************/
+BOOL name_to_rid(char *user_name, uint32 *u_rid, uint32 *g_rid)
+{
+ struct passwd *pw = Get_Pwnam(user_name, False);
+
+ if (u_rid == NULL || g_rid == NULL || user_name == NULL)
+ {
+ return False;
+ }
+
+ if (!pw)
+ {
+ DEBUG(1,("Username %s is invalid on this system\n", user_name));
+ return False;
+ }
+
+ if (user_in_list(user_name, lp_domain_guest_users()))
+ {
+ *u_rid = DOMAIN_USER_RID_GUEST;
+ }
+ else if (user_in_list(user_name, lp_domain_admin_users()))
+ {
+ *u_rid = DOMAIN_USER_RID_ADMIN;
+ }
+ else
+ {
+ /* turn the unix UID into a Domain RID. this is what the posix
+ sub-system does (adds 1000 to the uid) */
+ *u_rid = (uint32)(pw->pw_uid + 1000);
+ }
+
+ /* absolutely no idea what to do about the unix GID to Domain RID mapping */
+ *g_rid = (uint32)(pw->pw_gid + 1000);
+
+ return True;
+}
diff --git a/source3/rpc_server/srv_wkssvc.c b/source3/rpc_server/srv_wkssvc.c
new file mode 100644
index 0000000000..3dd273f784
--- /dev/null
+++ b/source3/rpc_server/srv_wkssvc.c
@@ -0,0 +1,113 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-1997,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ * Copyright (C) Paul Ashton 1997.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+
+
+/*******************************************************************
+ create_wks_info_100
+ ********************************************************************/
+static void create_wks_info_100(WKS_INFO_100 *inf)
+{
+ extern pstring myname;
+ pstring my_name;
+ pstring domain;
+
+ DEBUG(5,("create_wks_info_100: %d\n", __LINE__));
+
+ get_myname(myname, NULL);
+ pstrcpy (my_name, myname);
+ strupper(my_name);
+
+ pstrcpy (domain , lp_workgroup());
+ strupper(domain);
+
+ make_wks_info_100(inf,
+ 0x000001f4, /* platform id info */
+ lp_major_announce_version(),
+ lp_minor_announce_version(),
+ my_name, domain);
+}
+
+/*******************************************************************
+ wks_reply_query_info
+
+ only supports info level 100 at the moment.
+
+ ********************************************************************/
+static void wks_reply_query_info(WKS_Q_QUERY_INFO *q_u,
+ prs_struct *rdata,
+ int status)
+{
+ WKS_R_QUERY_INFO r_u;
+ WKS_INFO_100 wks100;
+
+ DEBUG(5,("wks_query_info: %d\n", __LINE__));
+
+ create_wks_info_100(&wks100);
+ make_wks_r_query_info(&r_u, q_u->switch_value, &wks100, status);
+
+ /* store the response in the SMB stream */
+ wks_io_r_query_info("", &r_u, rdata, 0);
+
+ DEBUG(5,("wks_query_info: %d\n", __LINE__));
+}
+
+/*******************************************************************
+ api_wks_query_info
+ ********************************************************************/
+static void api_wks_query_info( int uid, prs_struct *data,
+ prs_struct *rdata )
+{
+ WKS_Q_QUERY_INFO q_u;
+
+ /* grab the net share enum */
+ wks_io_q_query_info("", &q_u, data, 0);
+
+ /* construct reply. always indicate success */
+ wks_reply_query_info(&q_u, rdata, 0x0);
+}
+
+
+/*******************************************************************
+ \PIPE\wkssvc commands
+ ********************************************************************/
+struct api_struct api_wks_cmds[] =
+{
+ { "WKS_Q_QUERY_INFO", WKS_QUERY_INFO, api_wks_query_info },
+ { NULL , 0 , NULL }
+};
+
+/*******************************************************************
+ receives a wkssvc pipe and responds.
+ ********************************************************************/
+BOOL api_wkssvc_rpc(pipes_struct *p, prs_struct *data)
+{
+ return api_rpcTNP(p, "api_wkssvc_rpc", api_wks_cmds, data);
+}
+
diff --git a/source3/script/mkproto.awk b/source3/script/mkproto.awk
index 1ccf2fb2b0..bbbbc9029e 100644
--- a/source3/script/mkproto.awk
+++ b/source3/script/mkproto.awk
@@ -64,7 +64,7 @@ BEGIN {
next;
}
-!/^unsigned|^mode_t|^DIR|^user|^int|^char|^uint|^struct|^BOOL|^void|^time|^smb_shm_offset_t|^shm_offset_t|^enum remote_arch_types|arc4_key/ {
+!/^unsigned|^mode_t|^DIR|^user|^int|^char|^uint|^struct|^BOOL|^void|^time|^smb_shm_offset_t|^shm_offset_t|^enum remote_arch_types|^arc4_key|^FILE/ {
next;
}
diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c
index fb795e973e..c83ff1911c 100644
--- a/source3/smbd/chgpasswd.c
+++ b/source3/smbd/chgpasswd.c
@@ -422,6 +422,12 @@ BOOL check_lanman_password(char *user, unsigned char *pass1,
return False;
}
+ if(smbpw->acct_ctrl & ACB_DISABLED)
+ {
+ DEBUG(0,("check_lanman_password: account %s disabled.\n", user));
+ return False;
+ }
+
if(smbpw->smb_passwd == NULL)
{
DEBUG(0,("check_lanman_password: no lanman password !\n"));
@@ -462,6 +468,12 @@ BOOL change_lanman_password(struct smb_passwd *smbpw, unsigned char *pass1, unsi
return False;
}
+ if(smbpw->acct_ctrl & ACB_DISABLED)
+ {
+ DEBUG(0,("change_lanman_password: account %s disabled.\n", smbpw->smb_name));
+ return False;
+ }
+
if(smbpw->smb_passwd == NULL)
{
DEBUG(0,("change_lanman_password: no lanman password !\n"));
diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c
index 048dab8b3e..bbeeb21e96 100644
--- a/source3/smbd/ipc.c
+++ b/source3/smbd/ipc.c
@@ -27,6 +27,7 @@
*/
#include "includes.h"
+#include "nterr.h"
#ifdef CHECK_TYPES
#undef CHECK_TYPES
@@ -131,79 +132,128 @@ static BOOL prefix_ok(char *str,char *prefix)
return(strncmp(str,prefix,strlen(prefix)) == 0);
}
+/*******************************************************************
+ copies parameters and data, as needed, into the smb buffer
+
+ *both* the data and params sections should be aligned. this
+ is fudged in the rpc pipes by
+ at present, only the data section is. this may be a possible
+ cause of some of the ipc problems being experienced. lkcl26dec97
+
+ ******************************************************************/
+static void copy_trans_params_and_data(char *outbuf, int align,
+ struct mem_buf *rparam, struct mem_buf *rdata,
+ int param_offset, int data_offset,
+ int param_len, int data_len)
+{
+ char *copy_into = smb_buf(outbuf);
+
+ DEBUG(5,("copy_trans_params_and_data: params[%d..%d] data[%d..%d]\n",
+ param_offset, param_offset + param_len,
+ data_offset , data_offset + data_len));
+
+ if (param_len) mem_buf_copy(copy_into, rparam, param_offset, param_len);
+ copy_into += param_len + align;
+ if (data_len ) mem_buf_copy(copy_into, rdata , data_offset , data_len);
+}
/****************************************************************************
send a trans reply
****************************************************************************/
-static void send_trans_reply(char *outbuf,char *data,char *param,uint16 *setup,
- int ldata,int lparam,int lsetup)
+static void send_trans_reply(char *outbuf,
+ struct mem_buf *rdata,
+ struct mem_buf *rparam,
+ uint16 *setup, int lsetup, int max_data_ret)
{
- int i;
- int this_ldata,this_lparam;
- int tot_data=0,tot_param=0;
- int align;
+ int i;
+ int this_ldata,this_lparam;
+ int tot_data=0,tot_param=0;
+ int align;
+
+ int ldata = rdata ? mem_buf_len(rdata ) : 0;
+ int lparam = rparam ? mem_buf_len(rparam) : 0;
- this_lparam = MIN(lparam,max_send - (500+lsetup*SIZEOFWORD)); /* hack */
- this_ldata = MIN(ldata,max_send - (500+lsetup*SIZEOFWORD+this_lparam));
+ BOOL buffer_too_large = max_data_ret ? ldata > max_data_ret : False;
+
+ if (buffer_too_large)
+ {
+ DEBUG(5,("send_trans_reply: buffer %d too large %d\n", ldata, max_data_ret));
+ ldata = max_data_ret;
+ }
+
+ this_lparam = MIN(lparam,max_send - (500+lsetup*SIZEOFWORD)); /* hack */
+ this_ldata = MIN(ldata,max_send - (500+lsetup*SIZEOFWORD+this_lparam));
#ifdef CONFUSE_NETMONITOR_MSRPC_DECODING
- /* if you don't want Net Monitor to decode your packets, do this!!! */
- align = ((this_lparam+1)%4);
+ /* if you don't want Net Monitor to decode your packets, do this!!! */
+ align = ((this_lparam+1)%4);
#else
- align = (this_lparam%4);
+ align = (this_lparam%4);
#endif
- set_message(outbuf,10+lsetup,align+this_ldata+this_lparam,True);
- if (this_lparam)
- memcpy(smb_buf(outbuf),param,this_lparam);
- if (this_ldata)
- memcpy(smb_buf(outbuf)+this_lparam+align,data,this_ldata);
-
- SSVAL(outbuf,smb_vwv0,lparam);
- SSVAL(outbuf,smb_vwv1,ldata);
- SSVAL(outbuf,smb_vwv3,this_lparam);
- SSVAL(outbuf,smb_vwv4,smb_offset(smb_buf(outbuf),outbuf));
- SSVAL(outbuf,smb_vwv5,0);
- SSVAL(outbuf,smb_vwv6,this_ldata);
- SSVAL(outbuf,smb_vwv7,smb_offset(smb_buf(outbuf)+this_lparam+align,outbuf));
- SSVAL(outbuf,smb_vwv8,0);
- SSVAL(outbuf,smb_vwv9,lsetup);
- for (i=0;i<lsetup;i++)
- SSVAL(outbuf,smb_vwv10+i*SIZEOFWORD,setup[i]);
-
- show_msg(outbuf);
- send_smb(Client,outbuf);
-
- tot_data = this_ldata;
- tot_param = this_lparam;
-
- while (tot_data < ldata || tot_param < lparam)
- {
- this_lparam = MIN(lparam-tot_param,max_send - 500); /* hack */
- this_ldata = MIN(ldata-tot_data,max_send - (500+this_lparam));
+ set_message(outbuf,10+lsetup,align+this_ldata+this_lparam,True);
- align = (this_lparam%4);
+ if (buffer_too_large)
+ {
+ /* issue a buffer size warning. on a DCE/RPC pipe, expect an SMBreadX... */
+ SIVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ SIVAL(outbuf, smb_rcls, 0x80000000 | NT_STATUS_ACCESS_VIOLATION);
+ }
- set_message(outbuf,10,this_ldata+this_lparam+align,False);
- if (this_lparam)
- memcpy(smb_buf(outbuf),param+tot_param,this_lparam);
- if (this_ldata)
- memcpy(smb_buf(outbuf)+this_lparam+align,data+tot_data,this_ldata);
+ copy_trans_params_and_data(outbuf, align,
+ rparam , rdata,
+ tot_param , tot_data,
+ this_lparam, this_ldata);
+
+ SSVAL(outbuf,smb_vwv0,lparam);
+ SSVAL(outbuf,smb_vwv1,ldata);
+ SSVAL(outbuf,smb_vwv3,this_lparam);
+ SSVAL(outbuf,smb_vwv4,smb_offset(smb_buf(outbuf),outbuf));
+ SSVAL(outbuf,smb_vwv5,0);
+ SSVAL(outbuf,smb_vwv6,this_ldata);
+ SSVAL(outbuf,smb_vwv7,smb_offset(smb_buf(outbuf)+this_lparam+align,outbuf));
+ SSVAL(outbuf,smb_vwv8,0);
+ SSVAL(outbuf,smb_vwv9,lsetup);
+
+ for (i=0;i<lsetup;i++)
+ {
+ SSVAL(outbuf,smb_vwv10+i*SIZEOFWORD,setup[i]);
+ }
- SSVAL(outbuf,smb_vwv3,this_lparam);
- SSVAL(outbuf,smb_vwv4,smb_offset(smb_buf(outbuf),outbuf));
- SSVAL(outbuf,smb_vwv5,tot_param);
- SSVAL(outbuf,smb_vwv6,this_ldata);
- SSVAL(outbuf,smb_vwv7,smb_offset(smb_buf(outbuf)+this_lparam+align,outbuf));
- SSVAL(outbuf,smb_vwv8,tot_data);
- SSVAL(outbuf,smb_vwv9,0);
+ show_msg(outbuf);
+ send_smb(Client,outbuf);
- show_msg(outbuf);
- send_smb(Client,outbuf);
+ tot_data = this_ldata;
+ tot_param = this_lparam;
- tot_data += this_ldata;
- tot_param += this_lparam;
- }
+ while (tot_data < ldata || tot_param < lparam)
+ {
+ this_lparam = MIN(lparam-tot_param, max_send - 500); /* hack */
+ this_ldata = MIN(ldata -tot_data , max_send - (500+this_lparam));
+
+ align = (this_lparam%4);
+
+ set_message(outbuf,10,this_ldata+this_lparam+align,False);
+
+ copy_trans_params_and_data(outbuf, align,
+ rparam , rdata,
+ tot_param , tot_data,
+ this_lparam, this_ldata);
+
+ SSVAL(outbuf,smb_vwv3,this_lparam);
+ SSVAL(outbuf,smb_vwv4,smb_offset(smb_buf(outbuf),outbuf));
+ SSVAL(outbuf,smb_vwv5,tot_param);
+ SSVAL(outbuf,smb_vwv6,this_ldata);
+ SSVAL(outbuf,smb_vwv7,smb_offset(smb_buf(outbuf)+this_lparam+align,outbuf));
+ SSVAL(outbuf,smb_vwv8,tot_data);
+ SSVAL(outbuf,smb_vwv9,0);
+
+ show_msg(outbuf);
+ send_smb(Client,outbuf);
+
+ tot_data += this_ldata;
+ tot_param += this_lparam;
+ }
}
struct pack_desc {
@@ -1252,6 +1302,39 @@ static BOOL api_RNetServerEnum(int cnum, uint16 vuid, char *param, char *data,
return(True);
}
+/****************************************************************************
+ command 0x34 - suspected of being a "Lookup Names" stub api
+ ****************************************************************************/
+static BOOL api_RNetGroupGetUsers(int cnum, uint16 vuid, char *param, char *data,
+ int mdrcnt, int mprcnt, char **rdata,
+ char **rparam, int *rdata_len, int *rparam_len)
+{
+ char *str1 = param+2;
+ char *str2 = skip_string(str1,1);
+ char *p = skip_string(str2,1);
+ int uLevel = SVAL(p,0);
+ int buf_len = SVAL(p,2);
+ int counted=0;
+ int missed=0;
+
+ DEBUG(5,("RNetGroupGetUsers: %s %s %s %d %d\n",
+ str1, str2, p, uLevel, buf_len));
+
+ if (!prefix_ok(str1,"zWrLeh")) return False;
+
+ *rdata_len = 0;
+ *rdata = NULL;
+
+ *rparam_len = 8;
+ *rparam = REALLOC(*rparam,*rparam_len);
+
+ SSVAL(*rparam,0,0x08AC); /* informational warning message */
+ SSVAL(*rparam,2,0);
+ SSVAL(*rparam,4,counted);
+ SSVAL(*rparam,6,counted+missed);
+
+ return(True);
+}
/****************************************************************************
get info about a share
@@ -2185,8 +2268,11 @@ static BOOL api_RNetUserGetInfo(int cnum,uint16 vuid, char *param,char *data,
char *p2;
/* get NIS home of a previously validated user - simeon */
+ /* With share level security vuid will always be zero.
+ Don't depend on vuser being non-null !!. JRA */
user_struct *vuser = get_valid_user_struct(vuid);
- DEBUG(3,(" Username of UID %d is %s\n", vuser->uid, vuser->name));
+ if(vuser != NULL)
+ DEBUG(3,(" Username of UID %d is %s\n", vuser->uid, vuser->name));
*rparam_len = 6;
*rparam = REALLOC(*rparam,*rparam_len);
@@ -2236,7 +2322,7 @@ static BOOL api_RNetUserGetInfo(int cnum,uint16 vuid, char *param,char *data,
/* EEK! the cifsrap.txt doesn't have this in!!!! */
SIVAL(p,usri11_full_name,PTR_DIFF(p2,p)); /* full name */
- strcpy(p2,vuser->real_name); /* simeon */
+ strcpy(p2,((vuser != NULL) ? vuser->real_name : UserName));
p2 = skip_string(p2,1);
}
@@ -2292,7 +2378,7 @@ static BOOL api_RNetUserGetInfo(int cnum,uint16 vuid, char *param,char *data,
{
SIVAL(p,60,0); /* auth_flags */
SIVAL(p,64,PTR_DIFF(p2,*rdata)); /* full_name */
- strcpy(p2,vuser->real_name); /* simeon */
+ strcpy(p2,((vuser != NULL) ? vuser->real_name : UserName));
p2 = skip_string(p2,1);
SIVAL(p,68,0); /* urs_comment */
SIVAL(p,72,PTR_DIFF(p2,*rdata)); /* parms */
@@ -2920,175 +3006,331 @@ static BOOL api_WPrintPortEnum(int cnum,uint16 vuid, char *param,char *data,
return(True);
}
-
-struct
+struct api_cmd
{
- char * name;
char * pipe_clnt_name;
-#ifdef NTDOMAIN
char * pipe_srv_name;
-#endif
- int subcommand;
- BOOL (*fn) ();
-} api_fd_commands [] =
- {
-#ifdef NTDOMAIN
- { "TransactNmPipe", "lsarpc", "lsass", 0x26, api_ntLsarpcTNP },
- { "TransactNmPipe", "samr", "lsass", 0x26, api_samrTNP },
- { "TransactNmPipe", "srvsvc", "lsass", 0x26, api_srvsvcTNP },
- { "TransactNmPipe", "wkssvc", "ntsvcs", 0x26, api_wkssvcTNP },
- { "TransactNmPipe", "NETLOGON", "NETLOGON", 0x26, api_netlogrpcTNP },
- { NULL, NULL, NULL, -1, (BOOL (*)())api_Unsupported }
-#else
- { "TransactNmPipe" , "lsarpc", 0x26, api_LsarpcTNP },
- { NULL, NULL, -1, (BOOL (*)())api_Unsupported }
-#endif
- };
+ BOOL (*fn) (pipes_struct *, prs_struct *);
+};
-/****************************************************************************
- handle remote api calls delivered to a named pipe already opened.
- ****************************************************************************/
-static int api_fd_reply(int cnum,uint16 vuid,char *outbuf,
- uint16 *setup,char *data,char *params,
- int suwcnt,int tdscnt,int tpscnt,int mdrcnt,int mprcnt)
+static struct api_cmd api_fd_commands[] =
{
- char *rdata = NULL;
- char *rparam = NULL;
- int rdata_len = 0;
- int rparam_len = 0;
+ { "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 }
+};
- BOOL reply = False;
- BOOL bind_req = False;
- BOOL set_nphs = False;
+static BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *pd)
+{
+ BOOL ntlmssp_auth = False;
+ fstring ack_pipe_name;
+ int i = 0;
- int i;
- int fd;
- int subcommand;
- char *pipe_name;
-
- DEBUG(5,("api_fd_reply\n"));
- /* First find out the name of this file. */
- if (suwcnt != 2)
- {
- DEBUG(0,("Unexpected named pipe transaction.\n"));
- return(-1);
- }
-
- /* Get the file handle and hence the file name. */
- fd = setup[1];
- subcommand = setup[0];
- pipe_name = get_rpc_pipe_hnd_name(fd);
+ DEBUG(5,("api_pipe_bind_req: decode request. %d\n", __LINE__));
- if (pipe_name == NULL)
- {
- DEBUG(1,("api_fd_reply: INVALID PIPE HANDLE: %x\n", fd));
- }
+ for (i = 0; api_fd_commands[i].pipe_clnt_name; i++)
+ {
+ if (strequal(api_fd_commands[i].pipe_clnt_name, p->name) &&
+ api_fd_commands[i].fn != NULL)
+ {
+ DEBUG(3,("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
+ api_fd_commands[i].pipe_clnt_name,
+ api_fd_commands[i].pipe_srv_name));
+ fstrcpy(p->pipe_srv_name, api_fd_commands[i].pipe_srv_name);
+ break;
+ }
+ }
- DEBUG(3,("Got API command %d on pipe %s (fd %x)",
- subcommand, pipe_name, fd));
- DEBUG(3,("(tdscnt=%d,tpscnt=%d,mdrcnt=%d,mprcnt=%d,cnum=%d,vuid=%d)\n",
- tdscnt,tpscnt,mdrcnt,mprcnt,cnum,vuid));
-
- for (i = 0; api_fd_commands[i].name; i++)
- {
- if (strequal(api_fd_commands[i].pipe_clnt_name, pipe_name) &&
- api_fd_commands[i].subcommand == subcommand &&
- api_fd_commands[i].fn)
- {
- DEBUG(3,("Doing %s\n", api_fd_commands[i].name));
- break;
- }
- }
-
- rdata = (char *)malloc(1024); if (rdata ) bzero(rdata ,1024);
- rparam = (char *)malloc(1024); if (rparam) bzero(rparam,1024);
-
-#ifdef NTDOMAIN
- /* RPC Pipe command 0x26. */
- if (data != NULL && api_fd_commands[i].subcommand == 0x26)
- {
- RPC_HDR hdr;
+ if (api_fd_commands[i].fn == NULL) return False;
- /* process the rpc header */
- char *q = smb_io_rpc_hdr(True, &hdr, data, data, 4, 0);
-
- /* bind request received */
- if ((bind_req = ((q != NULL) && (hdr.pkt_type == RPC_BIND))))
- {
- RPC_HDR_RB hdr_rb;
+ /* decode the bind request */
+ smb_io_rpc_hdr_rb("", &p->hdr_rb, pd, 0);
- /* decode the bind request */
- char *p = smb_io_rpc_hdr_rb(True, &hdr_rb, q, data, 4, 0);
+ if (pd->offset == 0) return False;
- if ((bind_req = (p != NULL)))
- {
- RPC_HDR_BA hdr_ba;
- fstring ack_pipe_name;
+ if (p->hdr.auth_len != 0)
+ {
+ /* decode the authentication verifier */
+ smb_io_rpc_auth_ntlmssp_req("", &p->ntlmssp_req, pd, 0);
- /* name has to be \PIPE\xxxxx */
- strcpy(ack_pipe_name, "\\PIPE\\");
- strcat(ack_pipe_name, api_fd_commands[i].pipe_srv_name);
+ if (pd->offset == 0) return False;
- /* make a bind acknowledgement */
- make_rpc_hdr_ba(&hdr_ba,
- hdr_rb.bba.max_tsize, hdr_rb.bba.max_rsize, hdr_rb.bba.assoc_gid,
- ack_pipe_name,
- 0x1, 0x0, 0x0,
- &(hdr_rb.transfer));
+ /* ignore the version number for now */
+ ntlmssp_auth = strequal(p->ntlmssp_req.ntlmssp_str, "NTLMSSP");
+ }
- p = smb_io_rpc_hdr_ba(False, &hdr_ba, rdata + 0x10, rdata, 4, 0);
+ /* name has to be \PIPE\xxxxx */
+ strcpy(ack_pipe_name, "\\PIPE\\");
+ strcat(ack_pipe_name, p->pipe_srv_name);
- rdata_len = PTR_DIFF(p, rdata);
+ DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
- make_rpc_hdr(&hdr, RPC_BINDACK, 0x0, hdr.call_id, rdata_len);
+ prs_init(&(p->rdata), 1024, 4, 0, False);
+ prs_init(&(p->rhdr ), 0x10, 4, 0, False);
+ prs_init(&(p->rauth), 1024, 4, 0, False);
- p = smb_io_rpc_hdr(False, &hdr, rdata, rdata, 4, 0);
-
- reply = (p != NULL);
- }
- }
- }
-#endif
+ /***/
+ /*** do the bind ack first ***/
+ /***/
- /* Set Named Pipe Handle state */
- if (subcommand == 0x1)
- {
- set_nphs = True;
- reply = api_LsarpcSNPHS(fd, cnum, params);
- }
+ make_rpc_hdr_ba(&p->hdr_ba,
+ p->hdr_rb.bba.max_tsize,
+ p->hdr_rb.bba.max_rsize,
+ p->hdr_rb.bba.assoc_gid,
+ ack_pipe_name,
+ 0x1, 0x0, 0x0,
+ &(p->hdr_rb.transfer));
- if (!bind_req && !set_nphs)
- {
- DEBUG(10,("calling api_fd_command\n"));
+ smb_io_rpc_hdr_ba("", &p->hdr_ba, &p->rdata, 0);
+ mem_realloc_data(p->rdata.data, p->rdata.offset);
- reply = api_fd_commands[i].fn(cnum,vuid,params,data,mdrcnt,mprcnt,
- &rdata,&rparam,&rdata_len,&rparam_len);
- DEBUG(10,("called api_fd_command\n"));
- }
+ /***/
+ /*** now the authentication ***/
+ /***/
- if (rdata_len > mdrcnt || rparam_len > mprcnt)
- {
- reply = api_TooSmall(cnum,vuid,params,data,mdrcnt,mprcnt,
- &rdata,&rparam,&rdata_len,&rparam_len);
- }
-
- /* if we get False back then it's actually unsupported */
- if (!reply)
- {
- api_Unsupported(cnum,vuid,params,data,mdrcnt,mprcnt,
- &rdata,&rparam,&rdata_len,&rparam_len);
- }
-
- /* now send the reply */
- send_trans_reply(outbuf,rdata,rparam,NULL,rdata_len,rparam_len,0);
-
- if (rdata ) free(rdata );
- if (rparam) free(rparam);
-
- return(-1);
+ if (ntlmssp_auth)
+ {
+ uint8 data[16];
+ bzero(data, sizeof(data)); /* first 8 bytes are non-zero */
+
+ make_rpc_auth_ntlmssp_resp(&p->ntlmssp_resp,
+ 0x0a, 0x06, 0,
+ "NTLMSSP", 2,
+ 0x00000000, 0x0000b2b3, 0x000082b1,
+ data);
+ smb_io_rpc_auth_ntlmssp_resp("", &p->ntlmssp_resp, &p->rauth, 0);
+ mem_realloc_data(p->rauth.data, p->rauth.offset);
+ }
+
+ /***/
+ /*** then do the header, now we know the length ***/
+ /***/
+
+ make_rpc_hdr(&p->hdr, RPC_BINDACK, RPC_FLG_FIRST | RPC_FLG_LAST,
+ p->hdr.call_id,
+ p->rdata.offset + p->rauth.offset,
+ p->rauth.offset);
+
+ smb_io_rpc_hdr("", &p->hdr, &p->rhdr, 0);
+ mem_realloc_data(p->rhdr.data, p->rdata.offset);
+
+ /***/
+ /*** link rpc header, bind acknowledgment and authentication responses ***/
+ /***/
+
+ p->rhdr.data->offset.start = 0;
+ p->rhdr.data->offset.end = p->rhdr.offset;
+ p->rhdr.data->next = p->rdata.data;
+
+ if (ntlmssp_auth)
+ {
+ p->rdata.data->offset.start = p->rhdr.offset;
+ p->rdata.data->offset.end = p->rhdr.offset + p->rdata.offset;
+ p->rdata.data->next = p->rauth.data;
+
+ p->rauth.data->offset.start = p->rhdr.offset + p->rdata.offset;
+ p->rauth.data->offset.end = p->rhdr.offset + p->rauth.offset + p->rdata.offset;
+ p->rauth.data->next = NULL;
+ }
+ else
+ {
+ p->rdata.data->offset.start = p->rhdr.offset;
+ p->rdata.data->offset.end = p->rhdr.offset + p->rdata.offset;
+ p->rdata.data->next = NULL;
+ }
+
+ return True;
}
+static BOOL api_pipe_request(pipes_struct *p, prs_struct *pd)
+{
+ int i = 0;
+
+ for (i = 0; api_fd_commands[i].pipe_clnt_name; i++)
+ {
+ if (strequal(api_fd_commands[i].pipe_clnt_name, p->name) &&
+ api_fd_commands[i].fn != NULL)
+ {
+ DEBUG(3,("Doing \\PIPE\\%s\n", api_fd_commands[i].pipe_clnt_name));
+ return api_fd_commands[i].fn(p, pd);
+ }
+ }
+ return False;
+}
+static BOOL api_dce_rpc_command(char *outbuf,
+ pipes_struct *p,
+ prs_struct *pd)
+{
+ BOOL reply = False;
+ if (pd->data == NULL) return False;
+
+ /* process the rpc header */
+ smb_io_rpc_hdr("", &p->hdr, pd, 0);
+
+ if (pd->offset == 0) return False;
+
+ switch (p->hdr.pkt_type)
+ {
+ case RPC_BIND :
+ {
+ reply = api_pipe_bind_req(p, pd);
+ break;
+ }
+ case RPC_REQUEST:
+ {
+ reply = api_pipe_request (p, pd);
+ break;
+ }
+ }
+
+ if (reply)
+ {
+ /* now send the reply */
+ send_trans_reply(outbuf, p->rhdr.data, NULL, NULL, 0, p->max_rdata_len);
+
+ if (mem_buf_len(p->rhdr.data) <= p->max_rdata_len)
+ {
+ /* all of data was sent: no need to wait for SMBreadX calls */
+ mem_free_data(p->rhdr .data);
+ mem_free_data(p->rdata.data);
+ }
+ }
+
+ return reply;
+}
+
+/****************************************************************************
+ SetNamedPipeHandleState
+****************************************************************************/
+static BOOL api_SNPHS(char *outbuf, pipes_struct *p, char *param)
+{
+ uint16 id;
+
+ if (!param) return False;
+
+ id = param[0] + (param[1] << 8);
+ DEBUG(4,("lsarpc SetNamedPipeHandleState to code %x\n", id));
+
+ if (set_rpc_pipe_hnd_state(p, id))
+ {
+ /* now send the reply */
+ send_trans_reply(outbuf, NULL, NULL, NULL, 0, p->max_rdata_len);
+
+ return True;
+ }
+ return False;
+}
+
+
+/****************************************************************************
+ when no reply is generated, indicate unsupported.
+ ****************************************************************************/
+static BOOL api_no_reply(char *outbuf, int max_rdata_len)
+{
+ struct mem_buf rparam;
+
+ mem_init(&rparam, 0);
+ mem_alloc_data(&rparam, 4);
+
+ rparam.offset.start = 0;
+ rparam.offset.end = 4;
+
+ /* unsupported */
+ SSVAL(rparam.data,0,NERR_notsupported);
+ SSVAL(rparam.data,2,0); /* converter word */
+
+ DEBUG(3,("Unsupported API fd command\n"));
+
+ /* now send the reply */
+ send_trans_reply(outbuf, NULL, &rparam, NULL, 0, max_rdata_len);
+
+ mem_free_data(&rparam);
+
+ return(-1);
+}
+
+/****************************************************************************
+ handle remote api calls delivered to a named pipe already opened.
+ ****************************************************************************/
+static int api_fd_reply(int cnum,uint16 vuid,char *outbuf,
+ uint16 *setup,char *data,char *params,
+ int suwcnt,int tdscnt,int tpscnt,int mdrcnt,int mprcnt)
+{
+ BOOL reply = False;
+
+ int pnum;
+ int subcommand;
+ pipes_struct *p = NULL;
+ prs_struct pd;
+ struct mem_buf data_buf;
+
+ DEBUG(5,("api_fd_reply\n"));
+
+ /* fake up a data buffer from the api_fd_reply data parameters */
+ mem_create(&data_buf, data, tdscnt, 0, False);
+ data_buf.offset.start = 0;
+ data_buf.offset.end = tdscnt;
+
+ /* fake up a parsing structure */
+ pd.data = &data_buf;
+ pd.align = 4;
+ pd.io = True;
+ pd.offset = 0;
+
+ /* First find out the name of this file. */
+ if (suwcnt != 2)
+ {
+ DEBUG(0,("Unexpected named pipe transaction.\n"));
+ return(-1);
+ }
+
+ /* Get the file handle and hence the file name. */
+ pnum = setup[1];
+ subcommand = setup[0];
+ get_rpc_pipe(pnum, &p);
+
+ if (p != NULL)
+ {
+ DEBUG(3,("Got API command 0x%x on pipe \"%s\" (pnum %x)",
+ subcommand, p->name, pnum));
+ DEBUG(3,("(tdscnt=%d,tpscnt=%d,mdrcnt=%d,mprcnt=%d,cnum=%d,vuid=%d)\n",
+ tdscnt,tpscnt,mdrcnt,mprcnt,cnum,vuid));
+
+ /* record maximum data length that can be transmitted in an SMBtrans */
+ p->max_rdata_len = mdrcnt;
+
+ switch (subcommand)
+ {
+ case 0x26:
+ {
+ /* dce/rpc command */
+ reply = api_dce_rpc_command(outbuf, p, &pd);
+ break;
+ }
+ case 0x01:
+ {
+ /* Set Named Pipe Handle state */
+ reply = api_SNPHS(outbuf, p, params);
+ break;
+ }
+ }
+ }
+ else
+ {
+ DEBUG(1,("api_fd_reply: INVALID PIPE HANDLE: %x\n", pnum));
+ }
+
+ if (!reply)
+ {
+ return api_no_reply(outbuf, mdrcnt);
+ }
+ return -1;
+}
/****************************************************************************
the buffer was too small
@@ -3145,6 +3387,7 @@ struct
{"RNetShareEnum", 0, (BOOL (*)())api_RNetShareEnum,0},
{"RNetShareGetInfo", 1, (BOOL (*)())api_RNetShareGetInfo,0},
{"RNetServerGetInfo", 13, (BOOL (*)())api_RNetServerGetInfo,0},
+ {"RNetGroupGetUsers", 52, (BOOL (*)())api_RNetGroupGetUsers,0},
{"RNetUserGetInfo", 56, (BOOL (*)())api_RNetUserGetInfo,0},
{"NetUserGetGroups", 59, (BOOL (*)())api_NetUserGetGroups,0},
{"NetWkstaGetInfo", 63, (BOOL (*)())api_NetWkstaGetInfo,0},
@@ -3177,6 +3420,8 @@ static int api_reply(int cnum,uint16 vuid,char *outbuf,char *data,char *params,
int tdscnt,int tpscnt,int mdrcnt,int mprcnt)
{
int api_command = SVAL(params,0);
+ struct mem_buf rdata_buf;
+ struct mem_buf rparam_buf;
char *rdata = NULL;
char *rparam = NULL;
int rdata_len = 0;
@@ -3216,14 +3461,20 @@ static int api_reply(int cnum,uint16 vuid,char *outbuf,char *data,char *params,
&rdata,&rparam,&rdata_len,&rparam_len);
+ mem_create(&rdata_buf , rdata , rdata_len , 0, False);
+ mem_create(&rparam_buf, rparam, rparam_len, 0, False);
+
+ rdata_buf.offset.start = 0;
+ rdata_buf.offset.end = rdata_len;
+
+ rparam_buf.offset.start = 0;
+ rparam_buf.offset.end = rparam_len;
/* now send the reply */
- send_trans_reply(outbuf,rdata,rparam,NULL,rdata_len,rparam_len,0);
+ send_trans_reply(outbuf, &rdata_buf, &rparam_buf, NULL, 0, 0);
- if (rdata)
- free(rdata);
- if (rparam)
- free(rparam);
+ if (rdata ) free(rdata);
+ if (rparam) free(rparam);
return(-1);
}
diff --git a/source3/smbd/password.c b/source3/smbd/password.c
index a51e5f639f..b422dda36c 100644
--- a/source3/smbd/password.c
+++ b/source3/smbd/password.c
@@ -877,6 +877,68 @@ BOOL smb_password_check(char *password, unsigned char *part_passwd, unsigned cha
}
/****************************************************************************
+ Do a specific test for an smb password being correct, given a smb_password and
+ the lanman and NT responses.
+****************************************************************************/
+
+BOOL smb_password_ok(struct smb_passwd *smb_pass,
+ uchar lm_pass[24], uchar nt_pass[24])
+{
+ uchar challenge[8];
+
+ if (!lm_pass || !smb_pass) return(False);
+
+ if(smb_pass->acct_ctrl & ACB_DISABLED)
+ {
+ DEBUG(3,("smb_password_ok: account for user %s was disabled.\n", smb_pass->smb_name));
+ return(False);
+ }
+
+ if (!last_challenge(challenge))
+ {
+ DEBUG(1,("smb_password_ok: no challenge done - password failed\n"));
+ return False;
+ }
+
+ DEBUG(4,("smb_password_ok: Checking SMB password for user %s\n", smb_pass->smb_name));
+
+ if ((Protocol >= PROTOCOL_NT1) && (smb_pass->smb_nt_passwd != NULL))
+ {
+ /* We have the NT MD4 hash challenge available - see if we can
+ use it (ie. does it exist in the smbpasswd file).
+ */
+ DEBUG(4,("smb_password_ok: Checking NT MD4 password\n"));
+ if (smb_password_check(nt_pass, smb_pass->smb_nt_passwd, challenge))
+ {
+ DEBUG(4,("smb_password_ok: NT MD4 password check succeeded\n"));
+ return(True);
+ }
+ DEBUG(4,("smb_password_ok: NT MD4 password check failed\n"));
+ }
+
+ /* Try against the lanman password. smb_pass->smb_passwd == NULL means
+ no password, allow access. */
+
+ DEBUG(4,("Checking LM MD4 password\n"));
+
+ if((smb_pass->smb_passwd == NULL) && (smb_pass->acct_ctrl & ACB_PWNOTREQ))
+ {
+ DEBUG(4,("smb_password_ok: no password required for user %s\n", smb_pass->smb_name));
+ return True;
+ }
+
+ if((smb_pass->smb_passwd != NULL) && smb_password_check(lm_pass, smb_pass->smb_passwd, challenge))
+ {
+ DEBUG(4,("smb_password_ok: LM MD4 password check succeeded\n"));
+ return(True);
+ }
+
+ DEBUG(4,("smb_password_ok: LM MD4 password check failed\n"));
+
+ return False;
+}
+
+/****************************************************************************
check if a username/password is OK
****************************************************************************/
BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd)
@@ -940,6 +1002,13 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd)
return(False);
}
+ /* Quit if the account was disabled. */
+ if(smb_pass->acct_ctrl & ACB_DISABLED)
+ {
+ DEBUG(3,("password_ok: account for user %s was disabled.\n", user));
+ return(False);
+ }
+
/* Ensure the uid's match */
if (smb_pass->smb_userid != pass->pw_uid)
{
@@ -947,35 +1016,13 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd)
return(False);
}
- if (Protocol >= PROTOCOL_NT1)
- {
- /* We have the NT MD4 hash challenge available - see if we can
- use it (ie. does it exist in the smbpasswd file).
- */
- if (smb_pass->smb_nt_passwd != NULL)
- {
- DEBUG(4,("Checking NT MD4 password\n"));
- if (smb_password_check(password,
- smb_pass->smb_nt_passwd,
- (unsigned char *)challenge))
- {
- update_protected_database(user,True);
- return(True);
- }
- DEBUG(4,("NT MD4 password check failed\n"));
- }
- }
-
- /* Try against the lanman password */
-
- if (smb_password_check(password,
- smb_pass->smb_passwd,
- (unsigned char *)challenge)) {
- update_protected_database(user,True);
- return(True);
- }
+ if(smb_password_ok( smb_pass, password, password))
+ {
+ update_protected_database(user,True);
+ return(True);
+ }
- DEBUG(3,("Error smb_password_check failed\n"));
+ DEBUG(3,("Error smb_password_check failed\n"));
}
DEBUG(4,("Checking password for user %s (l=%d)\n",user,pwlen));
diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c
index b5f9700f33..4d425cc2c0 100644
--- a/source3/smbd/pipes.c
+++ b/source3/smbd/pipes.c
@@ -51,17 +51,7 @@ extern fstring myworkgroup;
a packet to ensure chaining works correctly */
#define GETPNUM(buf,where) (chain_pnum!= -1?chain_pnum:SVAL(buf,where))
-char * known_pipes [] =
-{
- "lsarpc",
-#if NTDOMAIN
- "NETLOGON",
- "srvsvc",
- "wkssvc",
- "samr",
-#endif
- NULL
-};
+extern struct pipe_id_info pipe_names[];
/****************************************************************************
reply to an open and X on a named pipe
@@ -72,7 +62,8 @@ char * known_pipes [] =
int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize)
{
pstring fname;
- int cnum = SVAL(inbuf,smb_tid);
+ uint16 cnum = SVAL(inbuf, smb_tid);
+ uint16 vuid = SVAL(inbuf, smb_uid);
int pnum = -1;
int smb_ofun = SVAL(inbuf,smb_vwv8);
int size=0,fmode=0,mtime=0,rmode=0;
@@ -89,23 +80,23 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize)
DEBUG(4,("Opening pipe %s.\n", fname));
- /* Strip \PIPE\ off the name. */
- pstrcpy(fname,smb_buf(inbuf) + PIPELEN);
-
/* See if it is one we want to handle. */
- for( i = 0; known_pipes[i] ; i++ )
- if( strcmp(fname,known_pipes[i]) == 0 )
+ for( i = 0; pipe_names[i].client_pipe ; i++ )
+ if( strcmp(fname,pipe_names[i].client_pipe) == 0 )
break;
- if ( known_pipes[i] == NULL )
+ if ( pipe_names[i].client_pipe == NULL )
return(ERROR(ERRSRV,ERRaccess));
+ /* Strip \PIPE\ off the name. */
+ pstrcpy(fname,smb_buf(inbuf) + PIPELEN);
+
/* Known pipes arrive with DIR attribs. Remove it so a regular file */
/* can be opened and add it in after the open. */
DEBUG(3,("Known pipe %s opening.\n",fname));
smb_ofun |= 0x10; /* Add Create it not exists flag */
- pnum = open_rpc_pipe_hnd(fname, cnum);
+ pnum = open_rpc_pipe_hnd(fname, cnum, vuid);
if (pnum < 0) return(ERROR(ERRSRV,ERRnofids));
/* Prepare the reply */
@@ -133,190 +124,65 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize)
/****************************************************************************
- reply to a close
-****************************************************************************/
-int reply_pipe_close(char *inbuf,char *outbuf)
-{
- int pnum = get_rpc_pipe_num(inbuf,smb_vwv0);
- int cnum = SVAL(inbuf,smb_tid);
- int outsize = set_message(outbuf,0,0,True);
-
- DEBUG(5,("reply_pipe_close: pnum:%x cnum:%x\n", pnum, cnum));
-
- if (!close_rpc_pipe_hnd(pnum, cnum)) return(ERROR(ERRDOS,ERRbadfid));
-
- return(outsize);
-}
-
-
-/****************************************************************************
- api_LsarpcSNPHS
+ reply to a read and X
- SetNamedPipeHandleState on \PIPE\lsarpc.
+ This code is basically stolen from reply_read_and_X with some
+ wrinkles to handle pipes.
****************************************************************************/
-BOOL api_LsarpcSNPHS(int pnum, int cnum, char *param)
+int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize)
{
- uint16 id;
+ int pnum = get_rpc_pipe_num(inbuf,smb_vwv2);
+ uint32 smb_offs = IVAL(inbuf,smb_vwv3);
+ int smb_maxcnt = SVAL(inbuf,smb_vwv5);
+ int smb_mincnt = SVAL(inbuf,smb_vwv6);
+ int cnum;
+ int nread = -1;
+ char *data;
+ BOOL ok = False;
- if (!param) return False;
+ cnum = SVAL(inbuf,smb_tid);
- id = param[0] + (param[1] << 8);
- DEBUG(4,("lsarpc SetNamedPipeHandleState to code %x\n",id));
-
- return set_rpc_pipe_hnd_state(pnum, cnum, id);
-}
-
-
-/****************************************************************************
- api_LsarpcTNP
-
- TransactNamedPipe on \PIPE\lsarpc.
-****************************************************************************/
-static void LsarpcTNP1(char *data,char **rdata, int *rdata_len)
-{
- uint32 dword1, dword2;
- char pname[] = "\\PIPE\\lsass";
+/*
+ CHECK_FNUM(fnum,cnum);
+ CHECK_READ(fnum);
+ CHECK_ERROR(fnum);
+*/
- /* All kinds of mysterious numbers here */
- *rdata_len = 68;
- *rdata = REALLOC(*rdata,*rdata_len);
+ set_message(outbuf,12,0,True);
+ data = smb_buf(outbuf);
- dword1 = IVAL(data,0xC);
- dword2 = IVAL(data,0x10);
+ nread = read_pipe(pnum, data, smb_offs, smb_maxcnt);
- SIVAL(*rdata,0,0xc0005);
- SIVAL(*rdata,4,0x10);
- SIVAL(*rdata,8,0x44);
- SIVAL(*rdata,0xC,dword1);
+ ok = True;
- SIVAL(*rdata,0x10,dword2);
- SIVAL(*rdata,0x14,0x15);
- SSVAL(*rdata,0x18,sizeof(pname));
- strcpy(*rdata + 0x1a,pname);
- SIVAL(*rdata,0x28,1);
- memcpy(*rdata + 0x30, data + 0x34, 0x14);
-}
-
-static void LsarpcTNP2(char *data,char **rdata, int *rdata_len)
-{
- uint32 dword1;
-
- /* All kinds of mysterious numbers here */
- *rdata_len = 48;
- *rdata = REALLOC(*rdata,*rdata_len);
-
- dword1 = IVAL(data,0xC);
-
- SIVAL(*rdata,0,0x03020005);
- SIVAL(*rdata,4,0x10);
- SIVAL(*rdata,8,0x30);
- SIVAL(*rdata,0xC,dword1);
- SIVAL(*rdata,0x10,0x18);
- SIVAL(*rdata,0x1c,0x44332211);
- SIVAL(*rdata,0x20,0x88776655);
- SIVAL(*rdata,0x24,0xCCBBAA99);
- SIVAL(*rdata,0x28,0x11FFEEDD);
-}
-
-static void LsarpcTNP3(char *data,char **rdata, int *rdata_len)
-{
- uint32 dword1;
- uint16 word1;
- char * workgroup = myworkgroup;
- int wglen = strlen(workgroup);
- int i;
-
- /* All kinds of mysterious numbers here */
- *rdata_len = 90 + 2 * wglen;
- *rdata = REALLOC(*rdata,*rdata_len);
-
- dword1 = IVAL(data,0xC);
- word1 = SVAL(data,0x2C);
-
- SIVAL(*rdata,0,0x03020005);
- SIVAL(*rdata,4,0x10);
- SIVAL(*rdata,8,0x60);
- SIVAL(*rdata,0xC,dword1);
- SIVAL(*rdata,0x10,0x48);
- SSVAL(*rdata,0x18,0x5988); /* This changes */
- SSVAL(*rdata,0x1A,0x15);
- SSVAL(*rdata,0x1C,word1);
- SSVAL(*rdata,0x20,6);
- SSVAL(*rdata,0x22,8);
- SSVAL(*rdata,0x24,0x8E8); /* So does this */
- SSVAL(*rdata,0x26,0x15);
- SSVAL(*rdata,0x28,0x4D48); /* And this */
- SSVAL(*rdata,0x2A,0x15);
- SIVAL(*rdata,0x2C,4);
- SIVAL(*rdata,0x34,wglen);
- for ( i = 0 ; i < wglen ; i++ )
- (*rdata)[0x38 + i * 2] = workgroup[i];
-
- /* Now fill in the rest */
- i = 0x38 + wglen * 2;
- SSVAL(*rdata,i,0x648);
- SIVAL(*rdata,i+2,4);
- SIVAL(*rdata,i+6,0x401);
- SSVAL(*rdata,i+0xC,0x500);
- SIVAL(*rdata,i+0xE,0x15);
- SIVAL(*rdata,i+0x12,0x2372FE1);
- SIVAL(*rdata,i+0x16,0x7E831BEF);
- SIVAL(*rdata,i+0x1A,0x4B454B2);
-}
-
-static void LsarpcTNP4(char *data,char **rdata, int *rdata_len)
-{
- uint32 dword1;
-
- /* All kinds of mysterious numbers here */
- *rdata_len = 48;
- *rdata = REALLOC(*rdata,*rdata_len);
+ if (nread < 0)
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+
+ SSVAL(outbuf,smb_vwv5,nread);
+ SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
+ SSVAL(smb_buf(outbuf),-2,nread);
+
+ DEBUG(3,("%s readX pnum=%04x cnum=%d min=%d max=%d nread=%d\n",
+ timestring(),pnum,cnum,
+ smb_mincnt,smb_maxcnt,nread));
- dword1 = IVAL(data,0xC);
+ set_chain_pnum(pnum);
- SIVAL(*rdata,0,0x03020005);
- SIVAL(*rdata,4,0x10);
- SIVAL(*rdata,8,0x30);
- SIVAL(*rdata,0xC,dword1);
- SIVAL(*rdata,0x10,0x18);
+ return chain_reply(inbuf,outbuf,length,bufsize);
}
-
-
-BOOL api_LsarpcTNP(int cnum,int uid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
+/****************************************************************************
+ reply to a close
+****************************************************************************/
+int reply_pipe_close(char *inbuf,char *outbuf)
{
- uint32 id,id2;
+ int pnum = get_rpc_pipe_num(inbuf,smb_vwv0);
+ int cnum = SVAL(inbuf,smb_tid);
+ int outsize = set_message(outbuf,0,0,True);
- id = IVAL(data,0);
+ DEBUG(5,("reply_pipe_close: pnum:%x cnum:%x\n", pnum, cnum));
- DEBUG(4,("lsarpc TransactNamedPipe id %lx\n",id));
- switch (id)
- {
- case 0xb0005:
- LsarpcTNP1(data,rdata,rdata_len);
- break;
+ if (!close_rpc_pipe_hnd(pnum, cnum)) return(ERROR(ERRDOS,ERRbadfid));
- case 0x03000005:
- id2 = IVAL(data,8);
- DEBUG(4,("\t- Suboperation %lx\n",id2));
- switch (id2 & 0xF)
- {
- case 8:
- LsarpcTNP2(data,rdata,rdata_len);
- break;
-
- case 0xC:
- LsarpcTNP4(data,rdata,rdata_len);
- break;
-
- case 0xE:
- LsarpcTNP3(data,rdata,rdata_len);
- break;
- }
- break;
- }
- return(True);
+ return(outsize);
}
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 38380180f9..74cfd797c3 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -366,6 +366,74 @@ int reply_ioctl(char *inbuf,char *outbuf)
#endif
}
+/****************************************************************************
+ always return an error: it's just a matter of which one...
+ ****************************************************************************/
+static int session_trust_account(char *inbuf, char *outbuf, char *user,
+ char *smb_passwd, int smb_passlen,
+ char *smb_nt_passwd, int smb_nt_passlen)
+{
+ struct smb_passwd *smb_trust_acct = NULL; /* check if trust account exists */
+ if (lp_security() == SEC_USER)
+ {
+ smb_trust_acct = get_smbpwd_entry(user, 0);
+ }
+ else
+ {
+ DEBUG(3,("Trust account %s only supported with security = user\n", user));
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_LOGON_FAILURE));
+ }
+
+ if (smb_trust_acct == NULL)
+ {
+ /* lkclXXXX: workstation entry doesn't exist */
+ DEBUG(4,("Trust account %s user doesn't exist\n",user));
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_NO_SUCH_USER));
+ }
+ else
+ {
+ if ((smb_passlen != 24) || (smb_nt_passlen != 24))
+ {
+ DEBUG(4,("Trust account %s - password length wrong.\n", user));
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_LOGON_FAILURE));
+ }
+
+ if (!smb_password_ok(smb_trust_acct, smb_passwd, smb_nt_passwd))
+ {
+ DEBUG(4,("Trust Account %s - password failed\n", user));
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_LOGON_FAILURE));
+ }
+
+ if (IS_BITS_SET_ALL(smb_trust_acct->acct_ctrl, ACB_DOMTRUST))
+ {
+ DEBUG(4,("Domain trust account %s denied by server\n",user));
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT));
+ }
+
+ if (IS_BITS_SET_ALL(smb_trust_acct->acct_ctrl, ACB_SVRTRUST))
+ {
+ DEBUG(4,("Server trust account %s denied by server\n",user));
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT));
+ }
+ if (IS_BITS_SET_ALL(smb_trust_acct->acct_ctrl, ACB_WSTRUST))
+ {
+ DEBUG(4,("Wksta trust account %s denied by server\n", user));
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT));
+ }
+ }
+
+ /* don't know what to do: indicate logon failure */
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_LOGON_FAILURE));
+}
+
/****************************************************************************
reply to a session setup command
@@ -386,7 +454,6 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize)
BOOL valid_nt_password = False;
pstring user;
BOOL guest=False;
- BOOL computer_id=False;
static BOOL done_sesssetup = False;
BOOL doencrypt = SMBENCRYPT();
char *domain = "";
@@ -496,48 +563,13 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize)
/* If name ends in $ then I think it's asking about whether a */
/* computer with that name (minus the $) has access. For now */
/* say yes to everything ending in $. */
- if (user[strlen(user) - 1] == '$')
+ if ((user[strlen(user) - 1] == '$') && (smb_apasslen == 24) && (smb_ntpasslen == 24))
{
-#ifdef NTDOMAIN
- struct smb_passwd *smb_pass; /* To check if machine account exists */
-/*
- PAXX: Ack. We don't want to do this. The workstation trust account
- with a $ on the end should exist in the local password database
- or be mapped to something generic, but not modified. For NT
- domain support we must reject this used in certain circumstances
- with a code to indicate to the client that it is an invalid use
- of a workstation trust account. NTWKS needs this error to join
- a domain. This may be the source of future bugs if we cannot
- be sure whether to reject this or not.
-*/
- /* non-null user name indicates search by username not by smb userid */
- smb_pass = get_smbpwd_entry(user, 0);
-
- if (!smb_pass)
- {
- /* lkclXXXX: if workstation entry doesn't exist, indicate logon failure */
- DEBUG(4,("Workstation trust account %s doesn't exist.",user));
- SSVAL(outbuf, smb_flg2, 0xc003); /* PAXX: Someone please unhack this */
- CVAL(outbuf, smb_reh) = 1; /* PAXX: Someone please unhack this */
- return(ERROR(NT_STATUS_LOGON_FAILURE, 0xc000)); /* decimal 109 NT error, 0xc000 */
- }
- else
- {
- /* PAXX: This is the NO LOGON workstation trust account stuff */
- /* lkclXXXX: if the workstation *does* exist, indicate failure differently! */
- DEBUG(4,("No Workstation trust account %s",user));
- SSVAL(outbuf, smb_flg2, 0xc003); /* PAXX: Someone please unhack this */
- CVAL(outbuf, smb_reh) = 1; /* PAXX: Someone please unhack this */
- return(ERROR(NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT, 0xc000)); /* decimal 409 NT error, 0xc000 */
- }
-
- computer_id = True;
-#else /* not NTDOMAIN, leave this in. PAXX: Someone get rid of this */
- user[strlen(user) - 1] = '\0';
-#endif
+ return session_trust_account(inbuf, outbuf, user,
+ smb_apasswd, smb_apasslen,
+ smb_ntpasswd, smb_ntpasslen);
}
-
/* If no username is sent use the guest account */
if (!*user)
{
@@ -583,7 +615,7 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize)
}
if (!valid_nt_password && !password_ok(user,smb_apasswd,smb_apasslen,NULL))
{
- if (!computer_id && lp_security() >= SEC_USER) {
+ if (lp_security() >= SEC_USER) {
#if (GUEST_SESSSETUP == 0)
return(ERROR(ERRSRV,ERRbadpw));
#endif
@@ -643,7 +675,7 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize)
uid = pw->pw_uid;
}
- if (guest && !computer_id)
+ if (guest)
SSVAL(outbuf,smb_vwv2,1);
/* register the name and uid as being validated, so further connections
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index e290027d0a..774e5c10b9 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -3955,7 +3955,7 @@ reply for the nt protocol
int reply_nt1(char *outbuf)
{
/* dual names + lock_and_read + nt SMBs + remote API calls */
- int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ;
+ int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|CAP_RPC_REMOTE_APIS;
/*
other valid capabilities which we may support at some time...
CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
@@ -5190,10 +5190,8 @@ static void init_structs(void )
/* for RPC pipes */
init_rpc_pipe_hnd();
-#ifdef NTDOMAIN
/* for LSA handles */
init_lsa_policy_hnd();
-#endif
init_dptrs();
}
diff --git a/source3/utils/smbpasswd.c b/source3/utils/smbpasswd.c
index 598944baa5..7ab8d8a0db 100644
--- a/source3/utils/smbpasswd.c
+++ b/source3/utils/smbpasswd.c
@@ -400,7 +400,7 @@ static void usage(char *name)
chmod(pfile, 0600);
/* Lock the smbpasswd file for write. */
- if ((lockfd = pw_file_lock(pfile, F_WRLCK, 5)) < 0) {
+ if ((lockfd = pw_file_lock(fileno(fp), F_WRLCK, 5)) < 0) {
err = errno;
fprintf(stderr, "%s: Failed to lock password file %s.\n",
argv[0], pfile);