Correct PPTP server firewall rules chain.
[tomato/davidwu.git] / release / src / router / samba / source / rpc_parse / parse_net.c
blob9588d1c53b3332a9b1521be5b1cc005b811676ee
1 /*
2 * Unix SMB/Netbios implementation.
3 * Version 1.9.
4 * RPC Pipe client / server routines
5 * Copyright (C) Andrew Tridgell 1992-1997,
6 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
7 * Copyright (C) Paul Ashton 1997.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "includes.h"
25 #include "nterr.h"
27 extern int DEBUGLEVEL;
29 /*******************************************************************
30 Reads or writes a structure.
31 ********************************************************************/
33 static BOOL net_io_neg_flags(char *desc, NEG_FLAGS *neg, prs_struct *ps, int depth)
35 if (neg == NULL)
36 return False;
38 prs_debug(ps, depth, desc, "net_io_neg_flags");
39 depth++;
41 if(!prs_align(ps))
42 return False;
44 if(!prs_uint32("neg_flags", ps, depth, &neg->neg_flags))
45 return False;
47 return True;
50 /*******************************************************************
51 Inits a NETLOGON_INFO_3 structure.
52 ********************************************************************/
54 static void init_netinfo_3(NETLOGON_INFO_3 *info, uint32 flags, uint32 logon_attempts)
56 info->flags = flags;
57 info->logon_attempts = logon_attempts;
58 info->reserved_1 = 0x0;
59 info->reserved_2 = 0x0;
60 info->reserved_3 = 0x0;
61 info->reserved_4 = 0x0;
62 info->reserved_5 = 0x0;
65 /*******************************************************************
66 Reads or writes a NETLOGON_INFO_3 structure.
67 ********************************************************************/
69 static BOOL net_io_netinfo_3(char *desc, NETLOGON_INFO_3 *info, prs_struct *ps, int depth)
71 if (info == NULL)
72 return False;
74 prs_debug(ps, depth, desc, "net_io_netinfo_3");
75 depth++;
77 if(!prs_align(ps))
78 return False;
80 if(!prs_uint32("flags ", ps, depth, &info->flags))
81 return False;
82 if(!prs_uint32("logon_attempts", ps, depth, &info->logon_attempts))
83 return False;
84 if(!prs_uint32("reserved_1 ", ps, depth, &info->reserved_1))
85 return False;
86 if(!prs_uint32("reserved_2 ", ps, depth, &info->reserved_2))
87 return False;
88 if(!prs_uint32("reserved_3 ", ps, depth, &info->reserved_3))
89 return False;
90 if(!prs_uint32("reserved_4 ", ps, depth, &info->reserved_4))
91 return False;
92 if(!prs_uint32("reserved_5 ", ps, depth, &info->reserved_5))
93 return False;
95 return True;
99 /*******************************************************************
100 Inits a NETLOGON_INFO_1 structure.
101 ********************************************************************/
103 static void init_netinfo_1(NETLOGON_INFO_1 *info, uint32 flags, uint32 pdc_status)
105 info->flags = flags;
106 info->pdc_status = pdc_status;
109 /*******************************************************************
110 Reads or writes a NETLOGON_INFO_1 structure.
111 ********************************************************************/
113 static BOOL net_io_netinfo_1(char *desc, NETLOGON_INFO_1 *info, prs_struct *ps, int depth)
115 if (info == NULL)
116 return False;
118 prs_debug(ps, depth, desc, "net_io_netinfo_1");
119 depth++;
121 if(!prs_align(ps))
122 return False;
124 if(!prs_uint32("flags ", ps, depth, &info->flags))
125 return False;
126 if(!prs_uint32("pdc_status", ps, depth, &info->pdc_status))
127 return False;
129 return True;
132 /*******************************************************************
133 Inits a NETLOGON_INFO_2 structure.
134 ********************************************************************/
136 static void init_netinfo_2(NETLOGON_INFO_2 *info, uint32 flags, uint32 pdc_status,
137 uint32 tc_status, char *trusted_dc_name)
139 int len_dc_name = strlen(trusted_dc_name);
140 info->flags = flags;
141 info->pdc_status = pdc_status;
142 info->ptr_trusted_dc_name = 1;
143 info->tc_status = tc_status;
145 if (trusted_dc_name != NULL)
146 init_unistr2(&(info->uni_trusted_dc_name), trusted_dc_name, len_dc_name+1);
147 else
148 init_unistr2(&(info->uni_trusted_dc_name), "", 1);
151 /*******************************************************************
152 Reads or writes a NETLOGON_INFO_2 structure.
153 ********************************************************************/
155 static BOOL net_io_netinfo_2(char *desc, NETLOGON_INFO_2 *info, prs_struct *ps, int depth)
157 if (info == NULL)
158 return False;
160 prs_debug(ps, depth, desc, "net_io_netinfo_2");
161 depth++;
163 if(!prs_align(ps))
164 return False;
166 if(!prs_uint32("flags ", ps, depth, &info->flags))
167 return False;
168 if(!prs_uint32("pdc_status ", ps, depth, &info->pdc_status))
169 return False;
170 if(!prs_uint32("ptr_trusted_dc_name", ps, depth, &info->ptr_trusted_dc_name))
171 return False;
172 if(!prs_uint32("tc_status ", ps, depth, &info->tc_status))
173 return False;
175 if (info->ptr_trusted_dc_name != 0) {
176 if(!smb_io_unistr2("unistr2", &info->uni_trusted_dc_name, info->ptr_trusted_dc_name, ps, depth))
177 return False;
180 if(!prs_align(ps))
181 return False;
183 return True;
186 /*******************************************************************
187 Reads or writes an NET_Q_LOGON_CTRL2 structure.
188 ********************************************************************/
190 BOOL net_io_q_logon_ctrl2(char *desc, NET_Q_LOGON_CTRL2 *q_l, prs_struct *ps, int depth)
192 if (q_l == NULL)
193 return False;
195 prs_debug(ps, depth, desc, "net_io_q_logon_ctrl2");
196 depth++;
198 if(!prs_align(ps))
199 return False;
201 if(!prs_uint32("ptr ", ps, depth, &q_l->ptr))
202 return False;
204 if(!smb_io_unistr2 ("", &q_l->uni_server_name, q_l->ptr, ps, depth))
205 return False;
207 if(!prs_align(ps))
208 return False;
210 if(!prs_uint32("function_code", ps, depth, &q_l->function_code))
211 return False;
212 if(!prs_uint32("query_level ", ps, depth, &q_l->query_level))
213 return False;
214 if(!prs_uint32("switch_value ", ps, depth, &q_l->switch_value))
215 return False;
217 return True;
220 /*******************************************************************
221 Inits an NET_R_LOGON_CTRL2 structure.
222 ********************************************************************/
224 void init_r_logon_ctrl2(NET_R_LOGON_CTRL2 *r_l, uint32 query_level,
225 uint32 flags, uint32 pdc_status, uint32 logon_attempts,
226 uint32 tc_status, char *trusted_domain_name)
228 DEBUG(5,("make_r_logon_ctrl2\n"));
230 r_l->switch_value = query_level; /* should only be 0x1 */
232 switch (query_level) {
233 case 1:
234 r_l->ptr = 1; /* undocumented pointer */
235 init_netinfo_1(&r_l->logon.info1, flags, pdc_status);
236 r_l->status = 0;
237 break;
238 case 2:
239 r_l->ptr = 1; /* undocumented pointer */
240 init_netinfo_2(&r_l->logon.info2, flags, pdc_status,
241 tc_status, trusted_domain_name);
242 r_l->status = 0;
243 break;
244 case 3:
245 r_l->ptr = 1; /* undocumented pointer */
246 init_netinfo_3(&(r_l->logon.info3), flags, logon_attempts);
247 r_l->status = 0;
248 break;
249 default:
250 DEBUG(2,("init_r_logon_ctrl2: unsupported switch value %d\n",
251 r_l->switch_value));
252 r_l->ptr = 0; /* undocumented pointer */
254 /* take a guess at an error code... */
255 r_l->status = NT_STATUS_INVALID_INFO_CLASS;
256 break;
260 /*******************************************************************
261 Reads or writes an NET_R_LOGON_CTRL2 structure.
262 ********************************************************************/
264 BOOL net_io_r_logon_ctrl2(char *desc, NET_R_LOGON_CTRL2 *r_l, prs_struct *ps, int depth)
266 if (r_l == NULL)
267 return False;
269 prs_debug(ps, depth, desc, "net_io_r_logon_ctrl2");
270 depth++;
272 if(!prs_uint32("switch_value ", ps, depth, &r_l->switch_value))
273 return False;
274 if(!prs_uint32("ptr ", ps, depth, &r_l->ptr))
275 return False;
277 if (r_l->ptr != 0) {
278 switch (r_l->switch_value) {
279 case 1:
280 if(!net_io_netinfo_1("", &r_l->logon.info1, ps, depth))
281 return False;
282 break;
283 case 2:
284 if(!net_io_netinfo_2("", &r_l->logon.info2, ps, depth))
285 return False;
286 break;
287 case 3:
288 if(!net_io_netinfo_3("", &r_l->logon.info3, ps, depth))
289 return False;
290 break;
291 default:
292 DEBUG(2,("net_io_r_logon_ctrl2: unsupported switch value %d\n",
293 r_l->switch_value));
294 break;
298 if(!prs_uint32("status ", ps, depth, &r_l->status))
299 return False;
301 return True;
304 /*******************************************************************
305 Inits an NET_R_TRUST_DOM_LIST structure.
306 ********************************************************************/
308 void init_r_trust_dom(NET_R_TRUST_DOM_LIST *r_t,
309 uint32 num_doms, char *dom_name)
311 int i = 0;
313 DEBUG(5,("make_r_trust_dom\n"));
315 for (i = 0; i < MAX_TRUST_DOMS; i++) {
316 r_t->uni_trust_dom_name[i].uni_str_len = 0;
317 r_t->uni_trust_dom_name[i].uni_max_len = 0;
319 if (num_doms > MAX_TRUST_DOMS)
320 num_doms = MAX_TRUST_DOMS;
322 for (i = 0; i < num_doms; i++) {
323 fstring domain_name;
324 fstrcpy(domain_name, dom_name);
325 strupper(domain_name);
326 init_unistr2(&r_t->uni_trust_dom_name[i], domain_name, strlen(domain_name)+1);
327 /* the use of UNISTR2 here is non-standard. */
328 r_t->uni_trust_dom_name[i].undoc = 0x1;
331 r_t->status = 0;
334 /*******************************************************************
335 Reads or writes an NET_R_TRUST_DOM_LIST structure.
336 ********************************************************************/
338 BOOL net_io_r_trust_dom(char *desc, NET_R_TRUST_DOM_LIST *r_t, prs_struct *ps, int depth)
340 int i;
341 if (r_t == NULL)
342 return False;
344 prs_debug(ps, depth, desc, "net_io_r_trust_dom");
345 depth++;
347 for (i = 0; i < MAX_TRUST_DOMS; i++) {
348 if (r_t->uni_trust_dom_name[i].uni_str_len == 0)
349 break;
350 if(!smb_io_unistr2("", &r_t->uni_trust_dom_name[i], True, ps, depth))
351 return False;
354 if(!prs_uint32("status", ps, depth, &r_t->status))
355 return False;
357 return True;
361 /*******************************************************************
362 Reads or writes an NET_Q_TRUST_DOM_LIST structure.
363 ********************************************************************/
365 BOOL net_io_q_trust_dom(char *desc, NET_Q_TRUST_DOM_LIST *q_l, prs_struct *ps, int depth)
367 if (q_l == NULL)
368 return False;
370 prs_debug(ps, depth, desc, "net_io_q_trust_dom");
371 depth++;
373 if(!prs_uint32("ptr ", ps, depth, &q_l->ptr))
374 return False;
375 if(!smb_io_unistr2 ("", &q_l->uni_server_name, q_l->ptr, ps, depth))
376 return False;
378 if(!prs_align(ps))
379 return False;
381 if(!prs_uint32("function_code", ps, depth, &q_l->function_code))
382 return False;
384 return True;
387 /*******************************************************************
388 Inits an NET_Q_REQ_CHAL structure.
389 ********************************************************************/
391 void init_q_req_chal(NET_Q_REQ_CHAL *q_c,
392 char *logon_srv, char *logon_clnt,
393 DOM_CHAL *clnt_chal)
395 DEBUG(5,("make_q_req_chal: %d\n", __LINE__));
397 q_c->undoc_buffer = 1; /* don't know what this buffer is */
399 init_unistr2(&q_c->uni_logon_srv, logon_srv , strlen(logon_srv )+1);
400 init_unistr2(&q_c->uni_logon_clnt, logon_clnt, strlen(logon_clnt)+1);
402 memcpy(q_c->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data));
404 DEBUG(5,("make_q_req_chal: %d\n", __LINE__));
407 /*******************************************************************
408 Reads or writes an NET_Q_REQ_CHAL structure.
409 ********************************************************************/
411 BOOL net_io_q_req_chal(char *desc, NET_Q_REQ_CHAL *q_c, prs_struct *ps, int depth)
413 int old_align;
415 if (q_c == NULL)
416 return False;
418 prs_debug(ps, depth, desc, "net_io_q_req_chal");
419 depth++;
421 if(!prs_align(ps))
422 return False;
424 if(!prs_uint32("undoc_buffer", ps, depth, &q_c->undoc_buffer))
425 return False;
427 if(!smb_io_unistr2("", &q_c->uni_logon_srv, True, ps, depth)) /* logon server unicode string */
428 return False;
429 if(!smb_io_unistr2("", &q_c->uni_logon_clnt, True, ps, depth)) /* logon client unicode string */
430 return False;
432 old_align = ps->align;
433 ps->align = 0;
434 /* client challenge is _not_ aligned after the unicode strings */
435 if(!smb_io_chal("", &q_c->clnt_chal, ps, depth)) {
436 /* client challenge */
437 ps->align = old_align;
438 return False;
440 ps->align = old_align;
442 return True;
445 /*******************************************************************
446 Reads or writes a structure.
447 ********************************************************************/
449 BOOL net_io_r_req_chal(char *desc, NET_R_REQ_CHAL *r_c, prs_struct *ps, int depth)
451 if (r_c == NULL)
452 return False;
454 prs_debug(ps, depth, desc, "net_io_r_req_chal");
455 depth++;
457 if(!prs_align(ps))
458 return False;
460 if(!smb_io_chal("", &r_c->srv_chal, ps, depth)) /* server challenge */
461 return False;
463 if(!prs_uint32("status", ps, depth, &r_c->status))
464 return False;
466 return True;
470 /*******************************************************************
471 Inits a NET_Q_AUTH_2 struct.
472 ********************************************************************/
474 void init_q_auth_2(NET_Q_AUTH_2 *q_a,
475 char *logon_srv, char *acct_name, uint16 sec_chan, char *comp_name,
476 DOM_CHAL *clnt_chal, uint32 clnt_flgs)
478 DEBUG(5,("init_q_auth_2: %d\n", __LINE__));
480 init_log_info(&q_a->clnt_id, logon_srv, acct_name, sec_chan, comp_name);
481 memcpy(q_a->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data));
482 q_a->clnt_flgs.neg_flags = clnt_flgs;
484 DEBUG(5,("init_q_auth_2: %d\n", __LINE__));
487 /*******************************************************************
488 Reads or writes a structure.
489 ********************************************************************/
491 BOOL net_io_q_auth_2(char *desc, NET_Q_AUTH_2 *q_a, prs_struct *ps, int depth)
493 int old_align;
494 if (q_a == NULL)
495 return False;
497 prs_debug(ps, depth, desc, "net_io_q_auth_2");
498 depth++;
500 if(!prs_align(ps))
501 return False;
503 if(!smb_io_log_info ("", &q_a->clnt_id, ps, depth)) /* client identification info */
504 return False;
505 /* client challenge is _not_ aligned */
506 old_align = ps->align;
507 ps->align = 0;
508 if(!smb_io_chal("", &q_a->clnt_chal, ps, depth)) {
509 /* client-calculated credentials */
510 ps->align = old_align;
511 return False;
513 ps->align = old_align;
514 if(!net_io_neg_flags("", &q_a->clnt_flgs, ps, depth))
515 return False;
517 return True;
520 /*******************************************************************
521 Reads or writes a structure.
522 ********************************************************************/
524 BOOL net_io_r_auth_2(char *desc, NET_R_AUTH_2 *r_a, prs_struct *ps, int depth)
526 if (r_a == NULL)
527 return False;
529 prs_debug(ps, depth, desc, "net_io_r_auth_2");
530 depth++;
532 if(!prs_align(ps))
533 return False;
535 if(!smb_io_chal("", &r_a->srv_chal, ps, depth)) /* server challenge */
536 return False;
537 if(!net_io_neg_flags("", &r_a->srv_flgs, ps, depth))
538 return False;
540 if(!prs_uint32("status", ps, depth, &r_a->status))
541 return False;
543 return True;
547 /*******************************************************************
548 Inits a NET_Q_SRV_PWSET.
549 ********************************************************************/
551 void init_q_srv_pwset(NET_Q_SRV_PWSET *q_s, char *logon_srv, char *acct_name,
552 uint16 sec_chan, char *comp_name, DOM_CRED *cred, char nt_cypher[16])
554 DEBUG(5,("make_q_srv_pwset\n"));
556 init_clnt_info(&q_s->clnt_id, logon_srv, acct_name, sec_chan, comp_name, cred);
558 memcpy(q_s->pwd, nt_cypher, sizeof(q_s->pwd));
561 /*******************************************************************
562 Reads or writes a structure.
563 ********************************************************************/
565 BOOL net_io_q_srv_pwset(char *desc, NET_Q_SRV_PWSET *q_s, prs_struct *ps, int depth)
567 if (q_s == NULL)
568 return False;
570 prs_debug(ps, depth, desc, "net_io_q_srv_pwset");
571 depth++;
573 if(!prs_align(ps))
574 return False;
576 if(!smb_io_clnt_info("", &q_s->clnt_id, ps, depth)) /* client identification/authentication info */
577 return False;
578 if(!prs_uint8s (False, "pwd", ps, depth, q_s->pwd, 16)) /* new password - undocumented */
579 return False;
581 return True;
584 /*******************************************************************
585 Reads or writes a structure.
586 ********************************************************************/
588 BOOL net_io_r_srv_pwset(char *desc, NET_R_SRV_PWSET *r_s, prs_struct *ps, int depth)
590 if (r_s == NULL)
591 return False;
593 prs_debug(ps, depth, desc, "net_io_r_srv_pwset");
594 depth++;
596 if(!prs_align(ps))
597 return False;
599 if(!smb_io_cred("", &r_s->srv_cred, ps, depth)) /* server challenge */
600 return False;
602 if(!prs_uint32("status", ps, depth, &r_s->status))
603 return False;
605 return True;
608 /*************************************************************************
609 Init DOM_SID2 array from a string containing multiple sids
610 *************************************************************************/
612 static int init_dom_sid2s(char *sids_str, DOM_SID2 *sids, int max_sids)
614 char *ptr;
615 pstring s2;
616 int count = 0;
618 DEBUG(4,("init_dom_sid2s: %s\n", sids_str ? sids_str:""));
620 if(sids_str) {
621 for (count = 0, ptr = sids_str;
622 next_token(&ptr, s2, NULL, sizeof(s2)) && count < max_sids; count++) {
623 DOM_SID tmpsid;
624 string_to_sid(&tmpsid, s2);
625 init_dom_sid2(&sids[count], &tmpsid);
629 return count;
632 /*******************************************************************
633 Inits a NET_ID_INFO_1 structure.
634 ********************************************************************/
636 void init_id_info1(NET_ID_INFO_1 *id, char *domain_name,
637 uint32 param_ctrl, uint32 log_id_low, uint32 log_id_high,
638 char *user_name, char *wksta_name,
639 char sess_key[16],
640 unsigned char lm_cypher[16], unsigned char nt_cypher[16])
642 int len_domain_name = strlen(domain_name);
643 int len_user_name = strlen(user_name );
644 int len_wksta_name = strlen(wksta_name );
646 unsigned char lm_owf[16];
647 unsigned char nt_owf[16];
649 DEBUG(5,("make_id_info1: %d\n", __LINE__));
651 id->ptr_id_info1 = 1;
653 init_uni_hdr(&id->hdr_domain_name, len_domain_name);
655 id->param_ctrl = param_ctrl;
656 init_logon_id(&id->logon_id, log_id_low, log_id_high);
658 init_uni_hdr(&id->hdr_user_name, len_user_name);
659 init_uni_hdr(&id->hdr_wksta_name, len_wksta_name);
661 if (lm_cypher && nt_cypher) {
662 unsigned char key[16];
663 #ifdef DEBUG_PASSWORD
664 DEBUG(100,("lm cypher:"));
665 dump_data(100, (char *)lm_cypher, 16);
667 DEBUG(100,("nt cypher:"));
668 dump_data(100, (char *)nt_cypher, 16);
669 #endif
671 memset(key, 0, 16);
672 memcpy(key, sess_key, 8);
674 memcpy(lm_owf, lm_cypher, 16);
675 SamOEMhash(lm_owf, key, False);
676 memcpy(nt_owf, nt_cypher, 16);
677 SamOEMhash(nt_owf, key, False);
679 #ifdef DEBUG_PASSWORD
680 DEBUG(100,("encrypt of lm owf password:"));
681 dump_data(100, (char *)lm_owf, 16);
683 DEBUG(100,("encrypt of nt owf password:"));
684 dump_data(100, (char *)nt_owf, 16);
685 #endif
686 /* set up pointers to cypher blocks */
687 lm_cypher = lm_owf;
688 nt_cypher = nt_owf;
691 init_owf_info(&id->lm_owf, lm_cypher);
692 init_owf_info(&id->nt_owf, nt_cypher);
694 init_unistr2(&id->uni_domain_name, domain_name, len_domain_name);
695 init_unistr2(&id->uni_user_name, user_name, len_user_name);
696 init_unistr2(&id->uni_wksta_name, wksta_name, len_wksta_name);
699 /*******************************************************************
700 Reads or writes an NET_ID_INFO_1 structure.
701 ********************************************************************/
703 static BOOL net_io_id_info1(char *desc, NET_ID_INFO_1 *id, prs_struct *ps, int depth)
705 if (id == NULL)
706 return False;
708 prs_debug(ps, depth, desc, "net_io_id_info1");
709 depth++;
711 if(!prs_align(ps))
712 return False;
714 if(!prs_uint32("ptr_id_info1", ps, depth, &id->ptr_id_info1))
715 return False;
717 if (id->ptr_id_info1 != 0) {
718 if(!smb_io_unihdr("unihdr", &id->hdr_domain_name, ps, depth))
719 return False;
721 if(!prs_uint32("param_ctrl", ps, depth, &id->param_ctrl))
722 return False;
723 if(!smb_io_logon_id("", &id->logon_id, ps, depth))
724 return False;
726 if(!smb_io_unihdr("unihdr", &id->hdr_user_name, ps, depth))
727 return False;
728 if(!smb_io_unihdr("unihdr", &id->hdr_wksta_name, ps, depth))
729 return False;
731 if(!smb_io_owf_info("", &id->lm_owf, ps, depth))
732 return False;
733 if(!smb_io_owf_info("", &id->nt_owf, ps, depth))
734 return False;
736 if(!smb_io_unistr2("unistr2", &id->uni_domain_name,
737 id->hdr_domain_name.buffer, ps, depth))
738 return False;
739 if(!smb_io_unistr2("unistr2", &id->uni_user_name,
740 id->hdr_user_name.buffer, ps, depth))
741 return False;
742 if(!smb_io_unistr2("unistr2", &id->uni_wksta_name,
743 id->hdr_wksta_name.buffer, ps, depth))
744 return False;
747 return True;
750 /*******************************************************************
751 Inits a NET_ID_INFO_2 structure.
753 This is a network logon packet. The log_id parameters
754 are what an NT server would generate for LUID once the
755 user is logged on. I don't think we care about them.
757 Note that this has no access to the NT and LM hashed passwords,
758 so it forwards the challenge, and the NT and LM responses (24
759 bytes each) over the secure channel to the Domain controller
760 for it to say yea or nay. This is the preferred method of
761 checking for a logon as it doesn't export the password
762 hashes to anyone who has compromised the secure channel. JRA.
763 ********************************************************************/
765 void init_id_info2(NET_ID_INFO_2 *id, char *domain_name,
766 uint32 param_ctrl, uint32 log_id_low, uint32 log_id_high,
767 char *user_name, char *wksta_name,
768 unsigned char lm_challenge[8],
769 unsigned char lm_chal_resp[24],
770 unsigned char nt_chal_resp[24])
772 int len_domain_name = strlen(domain_name);
773 int len_user_name = strlen(user_name );
774 int len_wksta_name = strlen(wksta_name );
775 int nt_chal_resp_len = ((nt_chal_resp != NULL) ? 24 : 0);
776 int lm_chal_resp_len = ((lm_chal_resp != NULL) ? 24 : 0);
777 unsigned char lm_owf[24];
778 unsigned char nt_owf[24];
780 DEBUG(5,("init_id_info2: %d\n", __LINE__));
782 id->ptr_id_info2 = 1;
784 init_uni_hdr(&id->hdr_domain_name, len_domain_name);
786 id->param_ctrl = param_ctrl;
787 init_logon_id(&id->logon_id, log_id_low, log_id_high);
789 init_uni_hdr(&id->hdr_user_name, len_user_name);
790 init_uni_hdr(&id->hdr_wksta_name, len_wksta_name);
792 if (nt_chal_resp) {
793 /* oops. can only send what-ever-it-is direct */
794 memcpy(nt_owf, nt_chal_resp, 24);
795 nt_chal_resp = nt_owf;
797 if (lm_chal_resp) {
798 /* oops. can only send what-ever-it-is direct */
799 memcpy(lm_owf, lm_chal_resp, 24);
800 lm_chal_resp = lm_owf;
803 memcpy(id->lm_chal, lm_challenge, sizeof(id->lm_chal));
804 init_str_hdr(&id->hdr_nt_chal_resp, 24, nt_chal_resp_len, (nt_chal_resp != NULL) ? 1 : 0);
805 init_str_hdr(&id->hdr_lm_chal_resp, 24, lm_chal_resp_len, (lm_chal_resp != NULL) ? 1 : 0);
807 init_unistr2(&id->uni_domain_name, domain_name, len_domain_name);
808 init_unistr2(&id->uni_user_name, user_name, len_user_name);
809 init_unistr2(&id->uni_wksta_name, wksta_name, len_wksta_name);
811 init_string2(&id->nt_chal_resp, (char *)nt_chal_resp, nt_chal_resp_len);
812 init_string2(&id->lm_chal_resp, (char *)lm_chal_resp, lm_chal_resp_len);
815 /*******************************************************************
816 Reads or writes an NET_ID_INFO_2 structure.
817 ********************************************************************/
819 static BOOL net_io_id_info2(char *desc, NET_ID_INFO_2 *id, prs_struct *ps, int depth)
821 if (id == NULL)
822 return False;
824 prs_debug(ps, depth, desc, "net_io_id_info2");
825 depth++;
827 if(!prs_align(ps))
828 return False;
830 if(!prs_uint32("ptr_id_info2", ps, depth, &id->ptr_id_info2))
831 return False;
833 if (id->ptr_id_info2 != 0) {
834 if(!smb_io_unihdr("unihdr", &id->hdr_domain_name, ps, depth))
835 return False;
837 if(!prs_uint32("param_ctrl", ps, depth, &id->param_ctrl))
838 return False;
839 if(!smb_io_logon_id("", &id->logon_id, ps, depth))
840 return False;
842 if(!smb_io_unihdr("unihdr", &id->hdr_user_name, ps, depth))
843 return False;
844 if(!smb_io_unihdr("unihdr", &id->hdr_wksta_name, ps, depth))
845 return False;
847 if(!prs_uint8s (False, "lm_chal", ps, depth, id->lm_chal, 8)) /* lm 8 byte challenge */
848 return False;
850 if(!smb_io_strhdr("hdr_nt_chal_resp", &id->hdr_nt_chal_resp, ps, depth))
851 return False;
852 if(!smb_io_strhdr("hdr_lm_chal_resp", &id->hdr_lm_chal_resp, ps, depth))
853 return False;
855 if(!smb_io_unistr2("uni_domain_name", &id->uni_domain_name,
856 id->hdr_domain_name.buffer, ps, depth))
857 return False;
858 if(!smb_io_unistr2("uni_user_name ", &id->uni_user_name,
859 id->hdr_user_name.buffer, ps, depth))
860 return False;
861 if(!smb_io_unistr2("uni_wksta_name ", &id->uni_wksta_name,
862 id->hdr_wksta_name.buffer, ps, depth))
863 return False;
864 if(!smb_io_string2("nt_chal_resp", &id->nt_chal_resp,
865 id->hdr_nt_chal_resp.buffer, ps, depth))
866 return False;
867 if(!smb_io_string2("lm_chal_resp", &id->lm_chal_resp,
868 id->hdr_lm_chal_resp.buffer, ps, depth))
869 return False;
872 return True;
876 /*******************************************************************
877 Inits a DOM_SAM_INFO structure.
878 ********************************************************************/
880 void init_sam_info(DOM_SAM_INFO *sam,
881 char *logon_srv, char *comp_name, DOM_CRED *clnt_cred,
882 DOM_CRED *rtn_cred, uint16 logon_level,
883 NET_ID_INFO_CTR *ctr)
885 DEBUG(5,("init_sam_info: %d\n", __LINE__));
887 init_clnt_info2(&(sam->client), logon_srv, comp_name, clnt_cred);
889 if (rtn_cred != NULL) {
890 sam->ptr_rtn_cred = 1;
891 memcpy(&sam->rtn_cred, rtn_cred, sizeof(sam->rtn_cred));
892 } else {
893 sam->ptr_rtn_cred = 0;
896 sam->logon_level = logon_level;
897 sam->ctr = ctr;
900 /*******************************************************************
901 Reads or writes a DOM_SAM_INFO structure.
902 ********************************************************************/
904 static BOOL net_io_id_info_ctr(char *desc, NET_ID_INFO_CTR *ctr, prs_struct *ps, int depth)
906 if (ctr == NULL)
907 return False;
909 prs_debug(ps, depth, desc, "smb_io_sam_info");
910 depth++;
912 /* don't 4-byte align here! */
914 if(!prs_uint16("switch_value ", ps, depth, &ctr->switch_value))
915 return False;
917 switch (ctr->switch_value) {
918 case 1:
919 if(!net_io_id_info1("", &ctr->auth.id1, ps, depth))
920 return False;
921 break;
922 case 2:
923 if(!net_io_id_info2("", &ctr->auth.id2, ps, depth))
924 return False;
925 break;
926 default:
927 /* PANIC! */
928 DEBUG(4,("smb_io_sam_info: unknown switch_value!\n"));
929 break;
932 return True;
935 /*******************************************************************
936 Reads or writes a DOM_SAM_INFO structure.
937 ********************************************************************/
939 static BOOL smb_io_sam_info(char *desc, DOM_SAM_INFO *sam, prs_struct *ps, int depth)
941 if (sam == NULL)
942 return False;
944 prs_debug(ps, depth, desc, "smb_io_sam_info");
945 depth++;
947 if(!prs_align(ps))
948 return False;
950 if(!smb_io_clnt_info2("", &sam->client, ps, depth))
951 return False;
953 if(!prs_uint32("ptr_rtn_cred ", ps, depth, &sam->ptr_rtn_cred))
954 return False;
955 if(!smb_io_cred("", &sam->rtn_cred, ps, depth))
956 return False;
958 if(!prs_uint16("logon_level ", ps, depth, &sam->logon_level))
959 return False;
961 if (sam->logon_level != 0 && sam->ctr != NULL) {
962 if(!net_io_id_info_ctr("logon_info", sam->ctr, ps, depth))
963 return False;
966 return True;
969 /*************************************************************************
970 Init
971 *************************************************************************/
973 void init_net_user_info3(NET_USER_INFO_3 *usr,
975 NTTIME *logon_time,
976 NTTIME *logoff_time,
977 NTTIME *kickoff_time,
978 NTTIME *pass_last_set_time,
979 NTTIME *pass_can_change_time,
980 NTTIME *pass_must_change_time,
982 char *user_name,
983 char *full_name,
984 char *logon_script,
985 char *profile_path,
986 char *home_dir,
987 char *dir_drive,
989 uint16 logon_count,
990 uint16 bad_pw_count,
992 uint32 user_id,
993 uint32 group_id,
994 uint32 num_groups,
995 DOM_GID *gids,
996 uint32 user_flgs,
998 char sess_key[16],
1000 char *logon_srv,
1001 char *logon_dom,
1003 DOM_SID *dom_sid,
1004 char *other_sids)
1006 /* only cope with one "other" sid, right now. */
1007 /* need to count the number of space-delimited sids */
1008 int i;
1009 int num_other_sids = 0;
1011 int len_user_name = strlen(user_name );
1012 int len_full_name = strlen(full_name );
1013 int len_logon_script = strlen(logon_script);
1014 int len_profile_path = strlen(profile_path);
1015 int len_home_dir = strlen(home_dir );
1016 int len_dir_drive = strlen(dir_drive );
1018 int len_logon_srv = strlen(logon_srv);
1019 int len_logon_dom = strlen(logon_dom);
1021 memset(usr, '\0', sizeof(*usr));
1023 usr->ptr_user_info = 1; /* yes, we're bothering to put USER_INFO data here */
1025 usr->logon_time = *logon_time;
1026 usr->logoff_time = *logoff_time;
1027 usr->kickoff_time = *kickoff_time;
1028 usr->pass_last_set_time = *pass_last_set_time;
1029 usr->pass_can_change_time = *pass_can_change_time;
1030 usr->pass_must_change_time = *pass_must_change_time;
1032 init_uni_hdr(&usr->hdr_user_name, len_user_name);
1033 init_uni_hdr(&usr->hdr_full_name, len_full_name);
1034 init_uni_hdr(&usr->hdr_logon_script, len_logon_script);
1035 init_uni_hdr(&usr->hdr_profile_path, len_profile_path);
1036 init_uni_hdr(&usr->hdr_home_dir, len_home_dir);
1037 init_uni_hdr(&usr->hdr_dir_drive, len_dir_drive);
1039 usr->logon_count = logon_count;
1040 usr->bad_pw_count = bad_pw_count;
1042 usr->user_id = user_id;
1043 usr->group_id = group_id;
1044 usr->num_groups = num_groups;
1045 usr->buffer_groups = 1; /* indicates fill in groups, below, even if there are none */
1046 usr->user_flgs = user_flgs;
1048 if (sess_key != NULL)
1049 memcpy(usr->user_sess_key, sess_key, sizeof(usr->user_sess_key));
1050 else
1051 memset((char *)usr->user_sess_key, '\0', sizeof(usr->user_sess_key));
1053 init_uni_hdr(&usr->hdr_logon_srv, len_logon_srv);
1054 init_uni_hdr(&usr->hdr_logon_dom, len_logon_dom);
1056 usr->buffer_dom_id = dom_sid ? 1 : 0; /* yes, we're bothering to put a domain SID in */
1058 memset((char *)usr->padding, '\0', sizeof(usr->padding));
1060 num_other_sids = init_dom_sid2s(other_sids, usr->other_sids, LSA_MAX_SIDS);
1062 usr->num_other_sids = num_other_sids;
1063 usr->buffer_other_sids = (num_other_sids != 0) ? 1 : 0;
1065 init_unistr2(&usr->uni_user_name, user_name, len_user_name);
1066 init_unistr2(&usr->uni_full_name, full_name, len_full_name);
1067 init_unistr2(&usr->uni_logon_script, logon_script, len_logon_script);
1068 init_unistr2(&usr->uni_profile_path, profile_path, len_profile_path);
1069 init_unistr2(&usr->uni_home_dir, home_dir, len_home_dir);
1070 init_unistr2(&usr->uni_dir_drive, dir_drive, len_dir_drive);
1072 usr->num_groups2 = num_groups;
1074 SMB_ASSERT_ARRAY(usr->gids, num_groups);
1076 for (i = 0; i < num_groups; i++)
1077 usr->gids[i] = gids[i];
1079 init_unistr2(&usr->uni_logon_srv, logon_srv, len_logon_srv);
1080 init_unistr2(&usr->uni_logon_dom, logon_dom, len_logon_dom);
1082 init_dom_sid2(&usr->dom_sid, dom_sid);
1083 /* "other" sids are set up above */
1087 /*******************************************************************
1088 Reads or writes a structure.
1089 ********************************************************************/
1091 static BOOL net_io_user_info3(char *desc, NET_USER_INFO_3 *usr, prs_struct *ps, int depth)
1093 int i;
1095 if (usr == NULL)
1096 return False;
1098 prs_debug(ps, depth, desc, "lsa_io_lsa_user_info");
1099 depth++;
1101 if(!prs_align(ps))
1102 return False;
1104 if(!prs_uint32("ptr_user_info ", ps, depth, &usr->ptr_user_info))
1105 return False;
1107 if (usr->ptr_user_info == 0)
1108 return True;
1110 if(!smb_io_time("time", &usr->logon_time, ps, depth)) /* logon time */
1111 return False;
1112 if(!smb_io_time("time", &usr->logoff_time, ps, depth)) /* logoff time */
1113 return False;
1114 if(!smb_io_time("time", &usr->kickoff_time, ps, depth)) /* kickoff time */
1115 return False;
1116 if(!smb_io_time("time", &usr->pass_last_set_time, ps, depth)) /* password last set time */
1117 return False;
1118 if(!smb_io_time("time", &usr->pass_can_change_time , ps, depth)) /* password can change time */
1119 return False;
1120 if(!smb_io_time("time", &usr->pass_must_change_time, ps, depth)) /* password must change time */
1121 return False;
1123 if(!smb_io_unihdr("unihdr", &usr->hdr_user_name, ps, depth)) /* username unicode string header */
1124 return False;
1125 if(!smb_io_unihdr("unihdr", &usr->hdr_full_name, ps, depth)) /* user's full name unicode string header */
1126 return False;
1127 if(!smb_io_unihdr("unihdr", &usr->hdr_logon_script, ps, depth)) /* logon script unicode string header */
1128 return False;
1129 if(!smb_io_unihdr("unihdr", &usr->hdr_profile_path, ps, depth)) /* profile path unicode string header */
1130 return False;
1131 if(!smb_io_unihdr("unihdr", &usr->hdr_home_dir, ps, depth)) /* home directory unicode string header */
1132 return False;
1133 if(!smb_io_unihdr("unihdr", &usr->hdr_dir_drive, ps, depth)) /* home directory drive unicode string header */
1134 return False;
1136 if(!prs_uint16("logon_count ", ps, depth, &usr->logon_count)) /* logon count */
1137 return False;
1138 if(!prs_uint16("bad_pw_count ", ps, depth, &usr->bad_pw_count)) /* bad password count */
1139 return False;
1141 if(!prs_uint32("user_id ", ps, depth, &usr->user_id)) /* User ID */
1142 return False;
1143 if(!prs_uint32("group_id ", ps, depth, &usr->group_id)) /* Group ID */
1144 return False;
1145 if(!prs_uint32("num_groups ", ps, depth, &usr->num_groups)) /* num groups */
1146 return False;
1147 if(!prs_uint32("buffer_groups ", ps, depth, &usr->buffer_groups)) /* undocumented buffer pointer to groups. */
1148 return False;
1149 if(!prs_uint32("user_flgs ", ps, depth, &usr->user_flgs)) /* user flags */
1150 return False;
1152 if(!prs_uint8s(False, "user_sess_key", ps, depth, usr->user_sess_key, 16)) /* unused user session key */
1153 return False;
1155 if(!smb_io_unihdr("unihdr", &usr->hdr_logon_srv, ps, depth)) /* logon server unicode string header */
1156 return False;
1157 if(!smb_io_unihdr("unihdr", &usr->hdr_logon_dom, ps, depth)) /* logon domain unicode string header */
1158 return False;
1160 if(!prs_uint32("buffer_dom_id ", ps, depth, &usr->buffer_dom_id)) /* undocumented logon domain id pointer */
1161 return False;
1162 if(!prs_uint8s (False, "padding ", ps, depth, usr->padding, 40)) /* unused padding bytes? */
1163 return False;
1165 if(!prs_uint32("num_other_sids", ps, depth, &usr->num_other_sids)) /* 0 - num_sids */
1166 return False;
1167 if(!prs_uint32("buffer_other_sids", ps, depth, &usr->buffer_other_sids)) /* NULL - undocumented pointer to SIDs. */
1168 return False;
1170 if(!smb_io_unistr2("unistr2", &usr->uni_user_name, usr->hdr_user_name.buffer, ps, depth)) /* username unicode string */
1171 return False;
1172 if(!smb_io_unistr2("unistr2", &usr->uni_full_name, usr->hdr_full_name.buffer, ps, depth)) /* user's full name unicode string */
1173 return False;
1174 if(!smb_io_unistr2("unistr2", &usr->uni_logon_script, usr->hdr_logon_script.buffer, ps, depth)) /* logon script unicode string */
1175 return False;
1176 if(!smb_io_unistr2("unistr2", &usr->uni_profile_path, usr->hdr_profile_path.buffer, ps, depth)) /* profile path unicode string */
1177 return False;
1178 if(!smb_io_unistr2("unistr2", &usr->uni_home_dir, usr->hdr_home_dir.buffer, ps, depth)) /* home directory unicode string */
1179 return False;
1180 if(!smb_io_unistr2("unistr2", &usr->uni_dir_drive, usr->hdr_dir_drive.buffer, ps, depth)) /* home directory drive unicode string */
1181 return False;
1183 if(!prs_align(ps))
1184 return False;
1185 if(!prs_uint32("num_groups2 ", ps, depth, &usr->num_groups2)) /* num groups */
1186 return False;
1187 SMB_ASSERT_ARRAY(usr->gids, usr->num_groups2);
1188 for (i = 0; i < usr->num_groups2; i++) {
1189 if(!smb_io_gid("", &usr->gids[i], ps, depth)) /* group info */
1190 return False;
1193 if(!smb_io_unistr2("unistr2", &usr->uni_logon_srv, usr->hdr_logon_srv.buffer, ps, depth)) /* logon server unicode string */
1194 return False;
1195 if(!smb_io_unistr2("unistr2", &usr->uni_logon_dom, usr->hdr_logon_srv.buffer, ps, depth)) /* logon domain unicode string */
1196 return False;
1198 if(!smb_io_dom_sid2("", &usr->dom_sid, ps, depth)) /* domain SID */
1199 return False;
1201 SMB_ASSERT_ARRAY(usr->other_sids, usr->num_other_sids);
1203 for (i = 0; i < usr->num_other_sids; i++) {
1204 if(!smb_io_dom_sid2("", &usr->other_sids[i], ps, depth)) /* other domain SIDs */
1205 return False;
1208 return True;
1211 /*******************************************************************
1212 Reads or writes a structure.
1213 ********************************************************************/
1215 BOOL net_io_q_sam_logon(char *desc, NET_Q_SAM_LOGON *q_l, prs_struct *ps, int depth)
1217 if (q_l == NULL)
1218 return False;
1220 prs_debug(ps, depth, desc, "net_io_q_sam_logon");
1221 depth++;
1223 if(!prs_align(ps))
1224 return False;
1226 if(!smb_io_sam_info("", &q_l->sam_id, ps, depth)) /* domain SID */
1227 return False;
1229 if(!prs_uint16("validation_level", ps, depth, &q_l->validation_level))
1230 return False;
1232 return True;
1235 /*******************************************************************
1236 Reads or writes a structure.
1237 ********************************************************************/
1239 BOOL net_io_r_sam_logon(char *desc, NET_R_SAM_LOGON *r_l, prs_struct *ps, int depth)
1241 if (r_l == NULL)
1242 return False;
1244 prs_debug(ps, depth, desc, "net_io_r_sam_logon");
1245 depth++;
1247 if(!prs_uint32("buffer_creds", ps, depth, &r_l->buffer_creds)) /* undocumented buffer pointer */
1248 return False;
1249 if(!smb_io_cred("", &r_l->srv_creds, ps, depth)) /* server credentials. server time stamp appears to be ignored. */
1250 return False;
1252 if(!prs_uint16("switch_value", ps, depth, &r_l->switch_value))
1253 return False;
1254 if(!prs_align(ps))
1255 return False;
1257 if (r_l->switch_value != 0) {
1258 if(!net_io_user_info3("", r_l->user, ps, depth))
1259 return False;
1262 if(!prs_uint32("auth_resp ", ps, depth, &r_l->auth_resp)) /* 1 - Authoritative response; 0 - Non-Auth? */
1263 return False;
1265 if(!prs_uint32("status ", ps, depth, &r_l->status))
1266 return False;
1268 if(!prs_align(ps))
1269 return False;
1271 return True;
1274 /*******************************************************************
1275 Reads or writes a structure.
1276 ********************************************************************/
1278 BOOL net_io_q_sam_logoff(char *desc, NET_Q_SAM_LOGOFF *q_l, prs_struct *ps, int depth)
1280 if (q_l == NULL)
1281 return False;
1283 prs_debug(ps, depth, desc, "net_io_q_sam_logoff");
1284 depth++;
1286 if(!prs_align(ps))
1287 return False;
1289 if(!smb_io_sam_info("", &q_l->sam_id, ps, depth)) /* domain SID */
1290 return False;
1292 return True;
1295 /*******************************************************************
1296 Reads or writes a structure.
1297 ********************************************************************/
1299 BOOL net_io_r_sam_logoff(char *desc, NET_R_SAM_LOGOFF *r_l, prs_struct *ps, int depth)
1301 if (r_l == NULL)
1302 return False;
1304 prs_debug(ps, depth, desc, "net_io_r_sam_logoff");
1305 depth++;
1307 if(!prs_align(ps))
1308 return False;
1310 if(!prs_uint32("buffer_creds", ps, depth, &r_l->buffer_creds)) /* undocumented buffer pointer */
1311 return False;
1312 if(!smb_io_cred("", &r_l->srv_creds, ps, depth)) /* server credentials. server time stamp appears to be ignored. */
1313 return False;
1315 if(!prs_uint32("status ", ps, depth, &r_l->status))
1316 return False;
1318 return True;