summaryrefslogtreecommitdiffstats
path: root/source/rpc_parse/parse_net.c
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>1998-03-11 21:11:04 +0000
committerJeremy Allison <jra@samba.org>1998-03-11 21:11:04 +0000
commit118ba4d77a33248e762a2cf843fb7cbc906ee6e7 (patch)
treef32d11769b73ccfb19c9b42bed5cbd49b050de3d /source/rpc_parse/parse_net.c
parentbafc7768925109d0e8e87152054d37ec3f4e7fdd (diff)
downloadsamba-118ba4d77a33248e762a2cf843fb7cbc906ee6e7.tar.gz
samba-118ba4d77a33248e762a2cf843fb7cbc906ee6e7.tar.xz
samba-118ba4d77a33248e762a2cf843fb7cbc906ee6e7.zip
"For I have laboured mightily on Luke's code, and hath broken
all I saw" - the book of Jeremy, chapter 1 :-). So here is the mega-merge of the NTDOM branch server code. It doesn't include the new client side pieces, we'll look at that later. This should give the same functionality, server wise, as the NTDOM branch does, only merged into the main branch. Any fixes to domain controler functionality should be added to the main branch, not the NTDOM branch. This code compiles without warnings on gcc2.8, but will need further testing before we are sure all the working functionality of the NTDOM server branch has been correctly carried over. I hereby declare the server side of the NTDOM branch dead (and all who sail in her :-). Jeremy.
Diffstat (limited to 'source/rpc_parse/parse_net.c')
-rw-r--r--source/rpc_parse/parse_net.c1147
1 files changed, 1147 insertions, 0 deletions
diff --git a/source/rpc_parse/parse_net.c b/source/rpc_parse/parse_net.c
new file mode 100644
index 00000000000..69d6ac08ede
--- /dev/null
+++ b/source/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));
+}
+
+