1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-27 03:21:53 +03:00
samba-mirror/source3/rpc_parse/parse_net.c

1130 lines
36 KiB
C
Raw Normal View History

/*
* 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 lm_owf[16];
unsigned char 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);
if (lm_cypher && nt_cypher)
{
void arcfour(uint8 key[16], uint8 out[16], uint8 in[16]);
unsigned char owf_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
memcpy(owf_key, sess_key, 16);
memcpy(lm_owf, lm_cypher, 16);
memcpy(nt_owf, nt_cypher, 16);
SamOEMhash(lm_owf, owf_key, False);
SamOEMhash(nt_owf, owf_key, False);
#ifdef DEBUG_PASSWORD
DEBUG(100,("hash of lm owf password:"));
dump_data(100, lm_owf, 16);
DEBUG(100,("hash of nt owf password:"));
dump_data(100, nt_owf, 16);
#endif
/* set up pointers to blocks */
lm_cypher = lm_owf;
nt_cypher = nt_owf;
}
make_owf_info(&(id->lm_owf), lm_cypher);
make_owf_info(&(id->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_owf_info("", &(id->lm_owf), ps, depth);
smb_io_owf_info("", &(id->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 lm_owf[24];
unsigned char 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(nt_owf, nt_chal_resp, 24);
nt_chal_resp = nt_owf;
}
if (lm_chal_resp)
{
/* oops. can only send what-ever-it-is direct */
memcpy(lm_owf, lm_chal_resp, 24);
lm_chal_resp = 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));
}