sync this function with 2.2 (single check for NULL parameter)
[samba.git] / source3 / rpc_parse / parse_net.c
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.
13  *  
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.
18  *  
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.
22  */
23
24 #include "includes.h"
25
26 extern int DEBUGLEVEL;
27
28 /*******************************************************************
29  Reads or writes a structure.
30 ********************************************************************/
31
32 static BOOL net_io_neg_flags(char *desc, NEG_FLAGS *neg, prs_struct *ps, int depth)
33 {
34         if (neg == NULL)
35                 return False;
36
37         prs_debug(ps, depth, desc, "net_io_neg_flags");
38         depth++;
39
40         if(!prs_align(ps))
41                 return False;
42         
43         if(!prs_uint32("neg_flags", ps, depth, &neg->neg_flags))
44                 return False;
45
46         return True;
47 }
48
49 /*******************************************************************
50  Inits a NETLOGON_INFO_3 structure.
51 ********************************************************************/
52
53 static void init_netinfo_3(NETLOGON_INFO_3 *info, uint32 flags, uint32 logon_attempts)
54 {
55         info->flags          = flags;
56         info->logon_attempts = logon_attempts;
57         info->reserved_1     = 0x0;
58         info->reserved_2     = 0x0;
59         info->reserved_3     = 0x0;
60         info->reserved_4     = 0x0;
61         info->reserved_5     = 0x0;
62 }
63
64 /*******************************************************************
65  Reads or writes a NETLOGON_INFO_3 structure.
66 ********************************************************************/
67
68 static BOOL net_io_netinfo_3(char *desc,  NETLOGON_INFO_3 *info, prs_struct *ps, int depth)
69 {
70         if (info == NULL)
71                 return False;
72
73         prs_debug(ps, depth, desc, "net_io_netinfo_3");
74         depth++;
75
76         if(!prs_align(ps))
77                 return False;
78
79         if(!prs_uint32("flags         ", ps, depth, &info->flags))
80                 return False;
81         if(!prs_uint32("logon_attempts", ps, depth, &info->logon_attempts))
82                 return False;
83         if(!prs_uint32("reserved_1    ", ps, depth, &info->reserved_1))
84                 return False;
85         if(!prs_uint32("reserved_2    ", ps, depth, &info->reserved_2))
86                 return False;
87         if(!prs_uint32("reserved_3    ", ps, depth, &info->reserved_3))
88                 return False;
89         if(!prs_uint32("reserved_4    ", ps, depth, &info->reserved_4))
90                 return False;
91         if(!prs_uint32("reserved_5    ", ps, depth, &info->reserved_5))
92                 return False;
93
94         return True;
95 }
96
97
98 /*******************************************************************
99  Inits a NETLOGON_INFO_1 structure.
100 ********************************************************************/
101
102 static void init_netinfo_1(NETLOGON_INFO_1 *info, uint32 flags, uint32 pdc_status)
103 {
104         info->flags      = flags;
105         info->pdc_status = pdc_status;
106 }
107
108 /*******************************************************************
109  Reads or writes a NETLOGON_INFO_1 structure.
110 ********************************************************************/
111
112 static BOOL net_io_netinfo_1(char *desc, NETLOGON_INFO_1 *info, prs_struct *ps, int depth)
113 {
114         if (info == NULL)
115                 return False;
116
117         prs_debug(ps, depth, desc, "net_io_netinfo_1");
118         depth++;
119
120         if(!prs_align(ps))
121                 return False;
122         
123         if(!prs_uint32("flags     ", ps, depth, &info->flags))
124                 return False;
125         if(!prs_uint32("pdc_status", ps, depth, &info->pdc_status))
126                 return False;
127
128         return True;
129 }
130
131 /*******************************************************************
132  Inits a NETLOGON_INFO_2 structure.
133 ********************************************************************/
134
135 static void init_netinfo_2(NETLOGON_INFO_2 *info, uint32 flags, uint32 pdc_status,
136                                 uint32 tc_status, char *trusted_dc_name)
137 {
138         int len_dc_name = strlen(trusted_dc_name);
139         info->flags      = flags;
140         info->pdc_status = pdc_status;
141         info->ptr_trusted_dc_name = 1;
142         info->tc_status  = tc_status;
143
144         if (trusted_dc_name != NULL)
145                 init_unistr2(&(info->uni_trusted_dc_name), trusted_dc_name, len_dc_name+1);
146         else
147                 init_unistr2(&(info->uni_trusted_dc_name), "", 1);
148 }
149
150 /*******************************************************************
151  Reads or writes a NETLOGON_INFO_2 structure.
152 ********************************************************************/
153
154 static BOOL net_io_netinfo_2(char *desc, NETLOGON_INFO_2 *info, prs_struct *ps, int depth)
155 {
156         if (info == NULL)
157                 return False;
158
159         prs_debug(ps, depth, desc, "net_io_netinfo_2");
160         depth++;
161
162         if(!prs_align(ps))
163                 return False;
164         
165         if(!prs_uint32("flags              ", ps, depth, &info->flags))
166                 return False;
167         if(!prs_uint32("pdc_status         ", ps, depth, &info->pdc_status))
168                 return False;
169         if(!prs_uint32("ptr_trusted_dc_name", ps, depth, &info->ptr_trusted_dc_name))
170                 return False;
171         if(!prs_uint32("tc_status          ", ps, depth, &info->tc_status))
172                 return False;
173
174         if (info->ptr_trusted_dc_name != 0) {
175                 if(!smb_io_unistr2("unistr2", &info->uni_trusted_dc_name, info->ptr_trusted_dc_name, ps, depth))
176                         return False;
177         }
178
179         if(!prs_align(ps))
180                 return False;
181
182         return True;
183 }
184
185 /*******************************************************************
186  Reads or writes an NET_Q_LOGON_CTRL2 structure.
187 ********************************************************************/
188
189 BOOL net_io_q_logon_ctrl2(char *desc, NET_Q_LOGON_CTRL2 *q_l, prs_struct *ps, int depth)
190 {
191         if (q_l == NULL)
192                 return False;
193
194         prs_debug(ps, depth, desc, "net_io_q_logon_ctrl2");
195         depth++;
196
197         if(!prs_align(ps))
198                 return False;
199
200         if(!prs_uint32("ptr          ", ps, depth, &q_l->ptr))
201                 return False;
202
203         if(!smb_io_unistr2 ("", &q_l->uni_server_name, q_l->ptr, ps, depth))
204                 return False;
205
206         if(!prs_align(ps))
207                 return False;
208
209         if(!prs_uint32("function_code", ps, depth, &q_l->function_code))
210                 return False;
211         if(!prs_uint32("query_level  ", ps, depth, &q_l->query_level))
212                 return False;
213         if(!prs_uint32("switch_value ", ps, depth, &q_l->switch_value))
214                 return False;
215
216         return True;
217 }
218
219 /*******************************************************************
220  Inits an NET_Q_LOGON_CTRL2 structure.
221 ********************************************************************/
222
223 void init_net_q_logon_ctrl2(NET_Q_LOGON_CTRL2 *q_l, char *srv_name,
224                             uint32 query_level)
225 {
226         DEBUG(5,("init_q_logon_ctrl2\n"));
227
228         q_l->function_code = 0x01;
229         q_l->query_level = query_level;
230         q_l->switch_value  = 0x01;
231
232         init_unistr2(&q_l->uni_server_name, srv_name, strlen(srv_name) + 1);
233 }
234
235 /*******************************************************************
236  Inits an NET_R_LOGON_CTRL2 structure.
237 ********************************************************************/
238
239 void init_net_r_logon_ctrl2(NET_R_LOGON_CTRL2 *r_l, uint32 query_level,
240                             uint32 flags, uint32 pdc_status, 
241                             uint32 logon_attempts, uint32 tc_status, 
242                             char *trusted_domain_name)
243 {
244         DEBUG(5,("init_r_logon_ctrl2\n"));
245
246         r_l->switch_value  = query_level; /* should only be 0x1 */
247
248         switch (query_level) {
249         case 1:
250                 r_l->ptr = 1; /* undocumented pointer */
251                 init_netinfo_1(&r_l->logon.info1, flags, pdc_status);   
252                 r_l->status = 0;
253                 break;
254         case 2:
255                 r_l->ptr = 1; /* undocumented pointer */
256                 init_netinfo_2(&r_l->logon.info2, flags, pdc_status,
257                                tc_status, trusted_domain_name); 
258                 r_l->status = 0;
259                 break;
260         case 3:
261                 r_l->ptr = 1; /* undocumented pointer */
262                 init_netinfo_3(&(r_l->logon.info3), flags, logon_attempts);     
263                 r_l->status = 0;
264                 break;
265         default:
266                 DEBUG(2,("init_r_logon_ctrl2: unsupported switch value %d\n",
267                         r_l->switch_value));
268                 r_l->ptr = 0; /* undocumented pointer */
269
270                 /* take a guess at an error code... */
271                 r_l->status = NT_STATUS_INVALID_INFO_CLASS;
272                 break;
273         }
274 }
275
276 /*******************************************************************
277  Reads or writes an NET_R_LOGON_CTRL2 structure.
278 ********************************************************************/
279
280 BOOL net_io_r_logon_ctrl2(char *desc, NET_R_LOGON_CTRL2 *r_l, prs_struct *ps, int depth)
281 {
282         if (r_l == NULL)
283                 return False;
284
285         prs_debug(ps, depth, desc, "net_io_r_logon_ctrl2");
286         depth++;
287
288         if(!prs_uint32("switch_value ", ps, depth, &r_l->switch_value))
289                 return False;
290         if(!prs_uint32("ptr          ", ps, depth, &r_l->ptr))
291                 return False;
292
293         if (r_l->ptr != 0) {
294                 switch (r_l->switch_value) {
295                 case 1:
296                         if(!net_io_netinfo_1("", &r_l->logon.info1, ps, depth))
297                                 return False;
298                         break;
299                 case 2:
300                         if(!net_io_netinfo_2("", &r_l->logon.info2, ps, depth))
301                                 return False;
302                         break;
303                 case 3:
304                         if(!net_io_netinfo_3("", &r_l->logon.info3, ps, depth))
305                                 return False;
306                         break;
307                 default:
308                         DEBUG(2,("net_io_r_logon_ctrl2: unsupported switch value %d\n",
309                                 r_l->switch_value));
310                         break;
311                 }
312         }
313
314         if(!prs_uint32("status       ", ps, depth, &r_l->status))
315                 return False;
316
317         return True;
318 }
319
320 /*******************************************************************
321  Reads or writes an NET_Q_LOGON_CTRL structure.
322 ********************************************************************/
323
324 BOOL net_io_q_logon_ctrl(char *desc, NET_Q_LOGON_CTRL *q_l, prs_struct *ps, 
325                          int depth)
326 {
327         prs_debug(ps, depth, desc, "net_io_q_logon_ctrl");
328         depth++;
329
330         if(!prs_align(ps))
331                 return False;
332
333         if(!prs_uint32("ptr          ", ps, depth, &q_l->ptr))
334                 return False;
335
336         if(!smb_io_unistr2 ("", &q_l->uni_server_name, q_l->ptr, ps, depth))
337                 return False;
338
339         if(!prs_align(ps))
340                 return False;
341
342         if(!prs_uint32("function_code", ps, depth, &q_l->function_code))
343                 return False;
344         if(!prs_uint32("query_level  ", ps, depth, &q_l->query_level))
345                 return False;
346
347         return True;
348 }
349
350 /*******************************************************************
351  Inits an NET_Q_LOGON_CTRL structure.
352 ********************************************************************/
353
354 void init_net_q_logon_ctrl(NET_Q_LOGON_CTRL *q_l, char *srv_name,
355                            uint32 query_level)
356 {
357         DEBUG(5,("init_q_logon_ctrl\n"));
358
359         q_l->function_code = 0x01; /* ??? */
360         q_l->query_level = query_level;
361
362         init_unistr2(&q_l->uni_server_name, srv_name, strlen(srv_name) + 1);
363 }
364
365 /*******************************************************************
366  Inits an NET_R_LOGON_CTRL structure.
367 ********************************************************************/
368
369 void init_net_r_logon_ctrl(NET_R_LOGON_CTRL *r_l, uint32 query_level,
370                            uint32 flags, uint32 pdc_status)
371 {
372         DEBUG(5,("init_r_logon_ctrl\n"));
373
374         r_l->switch_value  = query_level; /* should only be 0x1 */
375
376         switch (query_level) {
377         case 1:
378                 r_l->ptr = 1; /* undocumented pointer */
379                 init_netinfo_1(&r_l->logon.info1, flags, pdc_status);   
380                 r_l->status = 0;
381                 break;
382         default:
383                 DEBUG(2,("init_r_logon_ctrl: unsupported switch value %d\n",
384                         r_l->switch_value));
385                 r_l->ptr = 0; /* undocumented pointer */
386
387                 /* take a guess at an error code... */
388                 r_l->status = NT_STATUS_INVALID_INFO_CLASS;
389                 break;
390         }
391 }
392
393 /*******************************************************************
394  Reads or writes an NET_R_LOGON_CTRL structure.
395 ********************************************************************/
396
397 BOOL net_io_r_logon_ctrl(char *desc, NET_R_LOGON_CTRL *r_l, prs_struct *ps, 
398                          int depth)
399 {
400         prs_debug(ps, depth, desc, "net_io_r_logon_ctrl");
401         depth++;
402
403         if(!prs_uint32("switch_value ", ps, depth, &r_l->switch_value))
404                 return False;
405         if(!prs_uint32("ptr          ", ps, depth, &r_l->ptr))
406                 return False;
407
408         if (r_l->ptr != 0) {
409                 switch (r_l->switch_value) {
410                 case 1:
411                         if(!net_io_netinfo_1("", &r_l->logon.info1, ps, depth))
412                                 return False;
413                         break;
414                 default:
415                         DEBUG(2,("net_io_r_logon_ctrl: unsupported switch value %d\n",
416                                 r_l->switch_value));
417                         break;
418                 }
419         }
420
421         if(!prs_uint32("status       ", ps, depth, &r_l->status))
422                 return False;
423
424         return True;
425 }
426
427 /*******************************************************************
428  Inits an NET_R_TRUST_DOM_LIST structure.
429 ********************************************************************/
430
431 void init_r_trust_dom(NET_R_TRUST_DOM_LIST *r_t,
432                         uint32 num_doms, char *dom_name)
433 {
434         int i = 0;
435
436         DEBUG(5,("init_r_trust_dom\n"));
437
438         for (i = 0; i < MAX_TRUST_DOMS; i++) {
439                 r_t->uni_trust_dom_name[i].uni_str_len = 0;
440                 r_t->uni_trust_dom_name[i].uni_max_len = 0;
441         }
442         if (num_doms > MAX_TRUST_DOMS)
443                 num_doms = MAX_TRUST_DOMS;
444
445         for (i = 0; i < num_doms; i++) {
446                 fstring domain_name;
447                 fstrcpy(domain_name, dom_name);
448                 strupper(domain_name);
449                 init_unistr2(&r_t->uni_trust_dom_name[i], domain_name, strlen(domain_name)+1);
450                 /* the use of UNISTR2 here is non-standard. */
451                 r_t->uni_trust_dom_name[i].undoc = 0x1;
452         }
453         
454         r_t->status = 0;
455 }
456
457 /*******************************************************************
458  Reads or writes an NET_R_TRUST_DOM_LIST structure.
459 ********************************************************************/
460
461 BOOL net_io_r_trust_dom(char *desc, NET_R_TRUST_DOM_LIST *r_t, prs_struct *ps, int depth)
462 {
463         uint32 value;
464
465         if (r_t == NULL)
466                  return False;
467
468         prs_debug(ps, depth, desc, "net_io_r_trust_dom");
469         depth++;
470
471         /* temporary code to give a valid response */
472         value=2;
473         if(!prs_uint32("status", ps, depth, &value))
474                  return False;
475
476         value=1;
477         if(!prs_uint32("status", ps, depth, &value))
478                  return False;
479         value=2;
480         if(!prs_uint32("status", ps, depth, &value))
481                  return False;
482
483         value=0;
484         if(!prs_uint32("status", ps, depth, &value))
485                  return False;
486
487         value=0;
488         if(!prs_uint32("status", ps, depth, &value))
489                  return False;
490
491 /* old non working code */
492 #if 0
493         int i;
494
495         for (i = 0; i < MAX_TRUST_DOMS; i++) {
496                 if (r_t->uni_trust_dom_name[i].uni_str_len == 0)
497                         break;
498                 if(!smb_io_unistr2("", &r_t->uni_trust_dom_name[i], True, ps, depth))
499                          return False;
500         }
501
502         if(!prs_uint32("status", ps, depth, &r_t->status))
503                  return False;
504 #endif
505         return True;
506 }
507
508
509 /*******************************************************************
510  Reads or writes an NET_Q_TRUST_DOM_LIST structure.
511 ********************************************************************/
512
513 BOOL net_io_q_trust_dom(char *desc, NET_Q_TRUST_DOM_LIST *q_l, prs_struct *ps, int depth)
514 {
515         if (q_l == NULL)
516                  return False;
517
518         prs_debug(ps, depth, desc, "net_io_q_trust_dom");
519         depth++;
520
521         if(!prs_uint32("ptr          ", ps, depth, &q_l->ptr))
522                  return False;
523         if(!smb_io_unistr2 ("", &q_l->uni_server_name, q_l->ptr, ps, depth))
524                  return False;
525
526         return True;
527 }
528
529 /*******************************************************************
530  Inits an NET_Q_REQ_CHAL structure.
531 ********************************************************************/
532
533 void init_q_req_chal(NET_Q_REQ_CHAL *q_c,
534                                 char *logon_srv, char *logon_clnt,
535                                 DOM_CHAL *clnt_chal)
536 {
537         DEBUG(5,("init_q_req_chal: %d\n", __LINE__));
538
539         q_c->undoc_buffer = 1; /* don't know what this buffer is */
540
541         init_unistr2(&q_c->uni_logon_srv, logon_srv , strlen(logon_srv )+1);
542         init_unistr2(&q_c->uni_logon_clnt, logon_clnt, strlen(logon_clnt)+1);
543
544         memcpy(q_c->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data));
545
546         DEBUG(5,("init_q_req_chal: %d\n", __LINE__));
547 }
548
549 /*******************************************************************
550  Reads or writes an NET_Q_REQ_CHAL structure.
551 ********************************************************************/
552
553 BOOL net_io_q_req_chal(char *desc,  NET_Q_REQ_CHAL *q_c, prs_struct *ps, int depth)
554 {
555         int old_align;
556
557         if (q_c == NULL)
558                 return False;
559
560         prs_debug(ps, depth, desc, "net_io_q_req_chal");
561         depth++;
562
563         if(!prs_align(ps))
564                 return False;
565     
566         if(!prs_uint32("undoc_buffer", ps, depth, &q_c->undoc_buffer))
567                 return False;
568
569         if(!smb_io_unistr2("", &q_c->uni_logon_srv, True, ps, depth)) /* logon server unicode string */
570                 return False;
571         if(!smb_io_unistr2("", &q_c->uni_logon_clnt, True, ps, depth)) /* logon client unicode string */
572                 return False;
573
574         old_align = ps->align;
575         ps->align = 0;
576         /* client challenge is _not_ aligned after the unicode strings */
577         if(!smb_io_chal("", &q_c->clnt_chal, ps, depth)) {
578                 /* client challenge */
579                 ps->align = old_align;
580                 return False;
581         }
582         ps->align = old_align;
583
584         return True;
585 }
586
587 /*******************************************************************
588  Reads or writes a structure.
589 ********************************************************************/
590
591 BOOL net_io_r_req_chal(char *desc, NET_R_REQ_CHAL *r_c, prs_struct *ps, int depth)
592 {
593         if (r_c == NULL)
594                 return False;
595
596         prs_debug(ps, depth, desc, "net_io_r_req_chal");
597         depth++;
598
599         if(!prs_align(ps))
600                 return False;
601     
602         if(!smb_io_chal("", &r_c->srv_chal, ps, depth)) /* server challenge */
603                 return False;
604
605         if(!prs_uint32("status", ps, depth, &r_c->status))
606                 return False;
607
608         return True;
609 }
610
611
612 /*******************************************************************
613  Reads or writes a structure.
614 ********************************************************************/
615
616 BOOL net_io_q_auth(char *desc, NET_Q_AUTH *q_a, prs_struct *ps, int depth)
617 {
618         int old_align;
619         if (q_a == NULL)
620                 return False;
621
622         prs_debug(ps, depth, desc, "net_io_q_auth");
623         depth++;
624
625         if(!prs_align(ps))
626                 return False;
627     
628         if(!smb_io_log_info ("", &q_a->clnt_id, ps, depth)) /* client identification info */
629                 return False;
630         /* client challenge is _not_ aligned */
631         old_align = ps->align;
632         ps->align = 0;
633         if(!smb_io_chal("", &q_a->clnt_chal, ps, depth)) {
634                 /* client-calculated credentials */
635                 ps->align = old_align;
636                 return False;
637         }
638         ps->align = old_align;
639
640         return True;
641 }
642
643 /*******************************************************************
644  Reads or writes a structure.
645 ********************************************************************/
646
647 BOOL net_io_r_auth(char *desc, NET_R_AUTH *r_a, prs_struct *ps, int depth)
648 {
649         if (r_a == NULL)
650                 return False;
651
652         prs_debug(ps, depth, desc, "net_io_r_auth");
653         depth++;
654
655         if(!prs_align(ps))
656                 return False;
657     
658         if(!smb_io_chal("", &r_a->srv_chal, ps, depth)) /* server challenge */
659                 return False;
660
661         if(!prs_uint32("status", ps, depth, &r_a->status))
662                 return False;
663
664         return True;
665 }
666
667 /*******************************************************************
668  Inits a NET_Q_AUTH_2 struct.
669 ********************************************************************/
670
671 void init_q_auth_2(NET_Q_AUTH_2 *q_a,
672                 char *logon_srv, char *acct_name, uint16 sec_chan, char *comp_name,
673                 DOM_CHAL *clnt_chal, uint32 clnt_flgs)
674 {
675         DEBUG(5,("init_q_auth_2: %d\n", __LINE__));
676
677         init_log_info(&q_a->clnt_id, logon_srv, acct_name, sec_chan, comp_name);
678         memcpy(q_a->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data));
679         q_a->clnt_flgs.neg_flags = clnt_flgs;
680
681         DEBUG(5,("init_q_auth_2: %d\n", __LINE__));
682 }
683
684 /*******************************************************************
685  Reads or writes a structure.
686 ********************************************************************/
687
688 BOOL net_io_q_auth_2(char *desc, NET_Q_AUTH_2 *q_a, prs_struct *ps, int depth)
689 {
690         int old_align;
691         if (q_a == NULL)
692                 return False;
693
694         prs_debug(ps, depth, desc, "net_io_q_auth_2");
695         depth++;
696
697         if(!prs_align(ps))
698                 return False;
699     
700         if(!smb_io_log_info ("", &q_a->clnt_id, ps, depth)) /* client identification info */
701                 return False;
702         /* client challenge is _not_ aligned */
703         old_align = ps->align;
704         ps->align = 0;
705         if(!smb_io_chal("", &q_a->clnt_chal, ps, depth)) {
706                 /* client-calculated credentials */
707                 ps->align = old_align;
708                 return False;
709         }
710         ps->align = old_align;
711         if(!net_io_neg_flags("", &q_a->clnt_flgs, ps, depth))
712                 return False;
713
714         return True;
715 }
716
717 /*******************************************************************
718  Reads or writes a structure.
719 ********************************************************************/
720
721 BOOL net_io_r_auth_2(char *desc, NET_R_AUTH_2 *r_a, prs_struct *ps, int depth)
722 {
723         if (r_a == NULL)
724                 return False;
725
726         prs_debug(ps, depth, desc, "net_io_r_auth_2");
727         depth++;
728
729         if(!prs_align(ps))
730                 return False;
731     
732         if(!smb_io_chal("", &r_a->srv_chal, ps, depth)) /* server challenge */
733                 return False;
734         if(!net_io_neg_flags("", &r_a->srv_flgs, ps, depth))
735                 return False;
736
737         if(!prs_uint32("status", ps, depth, &r_a->status))
738                 return False;
739
740         return True;
741 }
742
743
744 /*******************************************************************
745  Inits a NET_Q_SRV_PWSET.
746 ********************************************************************/
747
748 void init_q_srv_pwset(NET_Q_SRV_PWSET *q_s, char *logon_srv, char *acct_name, 
749                 uint16 sec_chan, char *comp_name, DOM_CRED *cred, char nt_cypher[16])
750 {
751         DEBUG(5,("init_q_srv_pwset\n"));
752
753         init_clnt_info(&q_s->clnt_id, logon_srv, acct_name, sec_chan, comp_name, cred);
754
755         memcpy(q_s->pwd, nt_cypher, sizeof(q_s->pwd)); 
756 }
757
758 /*******************************************************************
759  Reads or writes a structure.
760 ********************************************************************/
761
762 BOOL net_io_q_srv_pwset(char *desc, NET_Q_SRV_PWSET *q_s, prs_struct *ps, int depth)
763 {
764         if (q_s == NULL)
765                 return False;
766
767         prs_debug(ps, depth, desc, "net_io_q_srv_pwset");
768         depth++;
769
770         if(!prs_align(ps))
771                 return False;
772     
773         if(!smb_io_clnt_info("", &q_s->clnt_id, ps, depth)) /* client identification/authentication info */
774                 return False;
775         if(!prs_uint8s (False, "pwd", ps, depth, q_s->pwd, 16)) /* new password - undocumented */
776                 return False;
777
778         return True;
779 }
780
781 /*******************************************************************
782  Reads or writes a structure.
783 ********************************************************************/
784
785 BOOL net_io_r_srv_pwset(char *desc, NET_R_SRV_PWSET *r_s, prs_struct *ps, int depth)
786 {
787         if (r_s == NULL)
788                 return False;
789
790         prs_debug(ps, depth, desc, "net_io_r_srv_pwset");
791         depth++;
792
793         if(!prs_align(ps))
794                 return False;
795     
796         if(!smb_io_cred("", &r_s->srv_cred, ps, depth)) /* server challenge */
797                 return False;
798
799         if(!prs_uint32("status", ps, depth, &r_s->status))
800                 return False;
801
802         return True;
803 }
804
805 /*************************************************************************
806  Init DOM_SID2 array from a string containing multiple sids
807  *************************************************************************/
808
809 static int init_dom_sid2s(TALLOC_CTX *ctx, char *sids_str, DOM_SID2 **ppsids)
810 {
811         char *ptr;
812         pstring s2;
813         int count = 0;
814
815         DEBUG(4,("init_dom_sid2s: %s\n", sids_str ? sids_str:""));
816
817         *ppsids = NULL;
818
819         if(sids_str) {
820                 int number;
821                 DOM_SID2 *sids;
822
823                 /* Count the number of SIDs. */
824                 for (count = 0, ptr = sids_str; 
825                   next_token(&ptr, s2, NULL, sizeof(s2)); count++)
826                         ;
827
828                 /* Now allocate space for them. */
829                 *ppsids = (DOM_SID2 *)talloc_zero(ctx, count * sizeof(DOM_SID2));
830                 if (*ppsids == NULL)
831                         return 0;
832
833                 sids = *ppsids;
834
835                 for (number = 0, ptr = sids_str; 
836                   next_token(&ptr, s2, NULL, sizeof(s2)); number++) {
837                         DOM_SID tmpsid;
838                         string_to_sid(&tmpsid, s2);
839                         init_dom_sid2(&sids[number], &tmpsid);
840                 }
841         }
842
843         return count;
844 }
845
846 /*******************************************************************
847  Inits a NET_ID_INFO_1 structure.
848 ********************************************************************/
849
850 void init_id_info1(NET_ID_INFO_1 *id, char *domain_name,
851                                 uint32 param_ctrl, uint32 log_id_low, uint32 log_id_high,
852                                 char *user_name, char *wksta_name,
853                                 char *sess_key,
854                                 unsigned char lm_cypher[16], unsigned char nt_cypher[16])
855 {
856         int len_domain_name = strlen(domain_name);
857         int len_user_name   = strlen(user_name  );
858         int len_wksta_name  = strlen(wksta_name );
859
860         unsigned char lm_owf[16];
861         unsigned char nt_owf[16];
862
863         DEBUG(5,("init_id_info1: %d\n", __LINE__));
864
865         id->ptr_id_info1 = 1;
866
867         init_uni_hdr(&id->hdr_domain_name, len_domain_name);
868
869         id->param_ctrl = param_ctrl;
870         init_logon_id(&id->logon_id, log_id_low, log_id_high);
871
872         init_uni_hdr(&id->hdr_user_name, len_user_name);
873         init_uni_hdr(&id->hdr_wksta_name, len_wksta_name);
874
875         if (lm_cypher && nt_cypher) {
876                 unsigned char key[16];
877 #ifdef DEBUG_PASSWORD
878                 DEBUG(100,("lm cypher:"));
879                 dump_data(100, (char *)lm_cypher, 16);
880
881                 DEBUG(100,("nt cypher:"));
882                 dump_data(100, (char *)nt_cypher, 16);
883 #endif
884
885                 memset(key, 0, 16);
886                 memcpy(key, sess_key, 8);
887
888                 memcpy(lm_owf, lm_cypher, 16);
889                 SamOEMhash(lm_owf, key, 16);
890                 memcpy(nt_owf, nt_cypher, 16);
891                 SamOEMhash(nt_owf, key, 16);
892
893 #ifdef DEBUG_PASSWORD
894                 DEBUG(100,("encrypt of lm owf password:"));
895                 dump_data(100, (char *)lm_owf, 16);
896
897                 DEBUG(100,("encrypt of nt owf password:"));
898                 dump_data(100, (char *)nt_owf, 16);
899 #endif
900                 /* set up pointers to cypher blocks */
901                 lm_cypher = lm_owf;
902                 nt_cypher = nt_owf;
903         }
904
905         init_owf_info(&id->lm_owf, lm_cypher);
906         init_owf_info(&id->nt_owf, nt_cypher);
907
908         init_unistr2(&id->uni_domain_name, domain_name, len_domain_name);
909         init_unistr2(&id->uni_user_name, user_name, len_user_name);
910         init_unistr2(&id->uni_wksta_name, wksta_name, len_wksta_name);
911 }
912
913 /*******************************************************************
914  Reads or writes an NET_ID_INFO_1 structure.
915 ********************************************************************/
916
917 static BOOL net_io_id_info1(char *desc,  NET_ID_INFO_1 *id, prs_struct *ps, int depth)
918 {
919         if (id == NULL)
920                 return False;
921
922         prs_debug(ps, depth, desc, "net_io_id_info1");
923         depth++;
924
925         if(!prs_align(ps))
926                 return False;
927         
928         if(!prs_uint32("ptr_id_info1", ps, depth, &id->ptr_id_info1))
929                 return False;
930
931         if (id->ptr_id_info1 != 0) {
932                 if(!smb_io_unihdr("unihdr", &id->hdr_domain_name, ps, depth))
933                         return False;
934
935                 if(!prs_uint32("param_ctrl", ps, depth, &id->param_ctrl))
936                         return False;
937                 if(!smb_io_logon_id("", &id->logon_id, ps, depth))
938                         return False;
939
940                 if(!smb_io_unihdr("unihdr", &id->hdr_user_name, ps, depth))
941                         return False;
942                 if(!smb_io_unihdr("unihdr", &id->hdr_wksta_name, ps, depth))
943                         return False;
944
945                 if(!smb_io_owf_info("", &id->lm_owf, ps, depth))
946                         return False;
947                 if(!smb_io_owf_info("", &id->nt_owf, ps, depth))
948                         return False;
949
950                 if(!smb_io_unistr2("unistr2", &id->uni_domain_name,
951                                 id->hdr_domain_name.buffer, ps, depth))
952                         return False;
953                 if(!smb_io_unistr2("unistr2", &id->uni_user_name,
954                                 id->hdr_user_name.buffer, ps, depth))
955                         return False;
956                 if(!smb_io_unistr2("unistr2", &id->uni_wksta_name,
957                                 id->hdr_wksta_name.buffer, ps, depth))
958                         return False;
959         }
960
961         return True;
962 }
963
964 /*******************************************************************
965 Inits a NET_ID_INFO_2 structure.
966
967 This is a network logon packet. The log_id parameters
968 are what an NT server would generate for LUID once the
969 user is logged on. I don't think we care about them.
970
971 Note that this has no access to the NT and LM hashed passwords,
972 so it forwards the challenge, and the NT and LM responses (24
973 bytes each) over the secure channel to the Domain controller
974 for it to say yea or nay. This is the preferred method of 
975 checking for a logon as it doesn't export the password
976 hashes to anyone who has compromised the secure channel. JRA.
977 ********************************************************************/
978
979 void init_id_info2(NET_ID_INFO_2 *id, char *domain_name,
980                                 uint32 param_ctrl, uint32 log_id_low, uint32 log_id_high,
981                                 char *user_name, char *wksta_name,
982                                 unsigned char lm_challenge[8],
983                                 unsigned char *lm_chal_resp,
984                                 unsigned char *nt_chal_resp)
985 {
986         int len_domain_name = strlen(domain_name);
987         int len_user_name   = strlen(user_name  );
988         int len_wksta_name  = strlen(wksta_name );
989         int nt_chal_resp_len = ((nt_chal_resp != NULL) ? 24 : 0);
990         int lm_chal_resp_len = ((lm_chal_resp != NULL) ? 24 : 0);
991         unsigned char lm_owf[24];
992         unsigned char nt_owf[24];
993
994         DEBUG(5,("init_id_info2: %d\n", __LINE__));
995
996         id->ptr_id_info2 = 1;
997
998         init_uni_hdr(&id->hdr_domain_name, len_domain_name);
999
1000         id->param_ctrl = param_ctrl;
1001         init_logon_id(&id->logon_id, log_id_low, log_id_high);
1002
1003         init_uni_hdr(&id->hdr_user_name, len_user_name);
1004         init_uni_hdr(&id->hdr_wksta_name, len_wksta_name);
1005
1006         if (nt_chal_resp) {
1007                 /* oops.  can only send what-ever-it-is direct */
1008                 memcpy(nt_owf, nt_chal_resp, 24);
1009                 nt_chal_resp = nt_owf;
1010         }
1011         if (lm_chal_resp) {
1012                 /* oops.  can only send what-ever-it-is direct */
1013                 memcpy(lm_owf, lm_chal_resp, 24);
1014                 lm_chal_resp = lm_owf;
1015         }
1016
1017         memcpy(id->lm_chal, lm_challenge, sizeof(id->lm_chal));
1018         init_str_hdr(&id->hdr_nt_chal_resp, 24, nt_chal_resp_len, (nt_chal_resp != NULL) ? 1 : 0);
1019         init_str_hdr(&id->hdr_lm_chal_resp, 24, lm_chal_resp_len, (lm_chal_resp != NULL) ? 1 : 0);
1020
1021         init_unistr2(&id->uni_domain_name, domain_name, len_domain_name);
1022         init_unistr2(&id->uni_user_name, user_name, len_user_name);
1023         init_unistr2(&id->uni_wksta_name, wksta_name, len_wksta_name);
1024
1025         init_string2(&id->nt_chal_resp, (char *)nt_chal_resp, nt_chal_resp_len);
1026         init_string2(&id->lm_chal_resp, (char *)lm_chal_resp, lm_chal_resp_len);
1027 }
1028
1029 /*******************************************************************
1030  Reads or writes an NET_ID_INFO_2 structure.
1031 ********************************************************************/
1032
1033 static BOOL net_io_id_info2(char *desc,  NET_ID_INFO_2 *id, prs_struct *ps, int depth)
1034 {
1035         if (id == NULL)
1036                 return False;
1037
1038         prs_debug(ps, depth, desc, "net_io_id_info2");
1039         depth++;
1040
1041         if(!prs_align(ps))
1042                 return False;
1043         
1044         if(!prs_uint32("ptr_id_info2", ps, depth, &id->ptr_id_info2))
1045                 return False;
1046
1047         if (id->ptr_id_info2 != 0) {
1048                 if(!smb_io_unihdr("unihdr", &id->hdr_domain_name, ps, depth))
1049                         return False;
1050
1051                 if(!prs_uint32("param_ctrl", ps, depth, &id->param_ctrl))
1052                         return False;
1053                 if(!smb_io_logon_id("", &id->logon_id, ps, depth))
1054                         return False;
1055
1056                 if(!smb_io_unihdr("unihdr", &id->hdr_user_name, ps, depth))
1057                         return False;
1058                 if(!smb_io_unihdr("unihdr", &id->hdr_wksta_name, ps, depth))
1059                         return False;
1060
1061                 if(!prs_uint8s (False, "lm_chal", ps, depth, id->lm_chal, 8)) /* lm 8 byte challenge */
1062                         return False;
1063
1064                 if(!smb_io_strhdr("hdr_nt_chal_resp", &id->hdr_nt_chal_resp, ps, depth))
1065                         return False;
1066                 if(!smb_io_strhdr("hdr_lm_chal_resp", &id->hdr_lm_chal_resp, ps, depth))
1067                         return False;
1068
1069                 if(!smb_io_unistr2("uni_domain_name", &id->uni_domain_name,
1070                                 id->hdr_domain_name.buffer, ps, depth))
1071                         return False;
1072                 if(!smb_io_unistr2("uni_user_name  ", &id->uni_user_name,
1073                                 id->hdr_user_name.buffer, ps, depth))
1074                         return False;
1075                 if(!smb_io_unistr2("uni_wksta_name ", &id->uni_wksta_name,
1076                                 id->hdr_wksta_name.buffer, ps, depth))
1077                         return False;
1078                 if(!smb_io_string2("nt_chal_resp", &id->nt_chal_resp,
1079                                 id->hdr_nt_chal_resp.buffer, ps, depth))
1080                         return False;
1081                 if(!smb_io_string2("lm_chal_resp", &id->lm_chal_resp,
1082                                 id->hdr_lm_chal_resp.buffer, ps, depth))
1083                         return False;
1084         }
1085
1086         return True;
1087 }
1088
1089
1090 /*******************************************************************
1091  Inits a DOM_SAM_INFO structure.
1092 ********************************************************************/
1093
1094 void init_sam_info(DOM_SAM_INFO *sam,
1095                                 char *logon_srv, char *comp_name, DOM_CRED *clnt_cred,
1096                                 DOM_CRED *rtn_cred, uint16 logon_level,
1097                                 NET_ID_INFO_CTR *ctr)
1098 {
1099         DEBUG(5,("init_sam_info: %d\n", __LINE__));
1100
1101         init_clnt_info2(&(sam->client), logon_srv, comp_name, clnt_cred);
1102
1103         if (rtn_cred != NULL) {
1104                 sam->ptr_rtn_cred = 1;
1105                 memcpy(&sam->rtn_cred, rtn_cred, sizeof(sam->rtn_cred));
1106         } else {
1107                 sam->ptr_rtn_cred = 0;
1108         }
1109
1110         sam->logon_level  = logon_level;
1111         sam->ctr          = ctr;
1112 }
1113
1114 /*******************************************************************
1115  Reads or writes a DOM_SAM_INFO structure.
1116 ********************************************************************/
1117
1118 static BOOL net_io_id_info_ctr(char *desc, NET_ID_INFO_CTR **pp_ctr, prs_struct *ps, int depth)
1119 {
1120         NET_ID_INFO_CTR *ctr = *pp_ctr;
1121
1122         prs_debug(ps, depth, desc, "smb_io_sam_info");
1123         depth++;
1124
1125         if (UNMARSHALLING(ps)) {
1126                 ctr = *pp_ctr = (NET_ID_INFO_CTR *)prs_alloc_mem(ps, sizeof(NET_ID_INFO_CTR));
1127                 if (ctr == NULL)
1128                         return False;
1129         }
1130         
1131         if (ctr == NULL)
1132                 return False;
1133
1134         /* don't 4-byte align here! */
1135
1136         if(!prs_uint16("switch_value ", ps, depth, &ctr->switch_value))
1137                 return False;
1138
1139         switch (ctr->switch_value) {
1140         case 1:
1141                 if(!net_io_id_info1("", &ctr->auth.id1, ps, depth))
1142                         return False;
1143                 break;
1144         case 2:
1145                 if(!net_io_id_info2("", &ctr->auth.id2, ps, depth))
1146                         return False;
1147                 break;
1148         default:
1149                 /* PANIC! */
1150                 DEBUG(4,("smb_io_sam_info: unknown switch_value!\n"));
1151                 break;
1152         }
1153
1154         return True;
1155 }
1156
1157 /*******************************************************************
1158  Reads or writes a DOM_SAM_INFO structure.
1159  ********************************************************************/
1160
1161 static BOOL smb_io_sam_info(char *desc, DOM_SAM_INFO *sam, prs_struct *ps, int depth)
1162 {
1163         if (sam == NULL)
1164                 return False;
1165
1166         prs_debug(ps, depth, desc, "smb_io_sam_info");
1167         depth++;
1168
1169         if(!prs_align(ps))
1170                 return False;
1171         
1172         if(!smb_io_clnt_info2("", &sam->client, ps, depth))
1173                 return False;
1174
1175         if(!prs_uint32("ptr_rtn_cred ", ps, depth, &sam->ptr_rtn_cred))
1176                 return False;
1177         if(!smb_io_cred("", &sam->rtn_cred, ps, depth))
1178                 return False;
1179
1180         if(!prs_uint16("logon_level  ", ps, depth, &sam->logon_level))
1181                 return False;
1182
1183         if (sam->logon_level != 0) {
1184                 if(!net_io_id_info_ctr("logon_info", &sam->ctr, ps, depth))
1185                         return False;
1186         }
1187
1188         return True;
1189 }
1190
1191 /*************************************************************************
1192  Init
1193  *************************************************************************/
1194
1195 void init_net_user_info3(TALLOC_CTX *ctx, NET_USER_INFO_3 *usr, SAM_ACCOUNT *sampw,
1196                          uint16 logon_count, uint16 bad_pw_count,
1197                          uint32 num_groups, DOM_GID *gids,
1198                          uint32 user_flgs, char *sess_key,
1199                          char *logon_srv, char *logon_dom,
1200                          DOM_SID *dom_sid, char *other_sids)
1201 {
1202         /* only cope with one "other" sid, right now. */
1203         /* need to count the number of space-delimited sids */
1204         int i;
1205         int num_other_sids = 0;
1206         
1207         NTTIME          logon_time, logoff_time, kickoff_time,
1208                         pass_last_set_time, pass_can_change_time,
1209                         pass_must_change_time;
1210
1211         int             len_user_name, len_full_name, len_home_dir,
1212                         len_dir_drive, len_logon_script, len_profile_path;
1213                         
1214         char*           user_name = pdb_get_username(sampw);
1215         char*           full_name = pdb_get_fullname(sampw);
1216         char*           home_dir  = pdb_get_homedir(sampw);
1217         char*           dir_drive = pdb_get_dirdrive(sampw);
1218         char*           logon_script = pdb_get_logon_script(sampw);
1219         char*           profile_path = pdb_get_profile_path(sampw);
1220
1221         int len_logon_srv    = strlen(logon_srv);
1222         int len_logon_dom    = strlen(logon_dom);
1223
1224         len_user_name    = strlen(user_name   );
1225         len_full_name    = strlen(full_name   );
1226         len_home_dir     = strlen(home_dir    );
1227         len_dir_drive    = strlen(dir_drive   );
1228         len_logon_script = strlen(logon_script);
1229         len_profile_path = strlen(profile_path);
1230
1231
1232         ZERO_STRUCTP(usr);
1233
1234         usr->ptr_user_info = 1; /* yes, we're bothering to put USER_INFO data here */
1235
1236
1237         /* Create NTTIME structs */
1238         unix_to_nt_time (&logon_time,           pdb_get_logon_time(sampw));
1239         unix_to_nt_time (&logoff_time,          pdb_get_logoff_time(sampw));
1240         unix_to_nt_time (&kickoff_time,         pdb_get_kickoff_time(sampw));
1241         unix_to_nt_time (&pass_last_set_time,   pdb_get_pass_last_set_time(sampw));
1242         unix_to_nt_time (&pass_can_change_time, pdb_get_pass_can_change_time(sampw));
1243         unix_to_nt_time (&pass_must_change_time,pdb_get_pass_must_change_time(sampw));
1244
1245         usr->logon_time            = logon_time;
1246         usr->logoff_time           = logoff_time;
1247         usr->kickoff_time          = kickoff_time;
1248         usr->pass_last_set_time    = pass_last_set_time;
1249         usr->pass_can_change_time  = pass_can_change_time;
1250         usr->pass_must_change_time = pass_must_change_time;
1251
1252         init_uni_hdr(&usr->hdr_user_name, len_user_name);
1253         init_uni_hdr(&usr->hdr_full_name, len_full_name);
1254         init_uni_hdr(&usr->hdr_logon_script, len_logon_script);
1255         init_uni_hdr(&usr->hdr_profile_path, len_profile_path);
1256         init_uni_hdr(&usr->hdr_home_dir, len_home_dir);
1257         init_uni_hdr(&usr->hdr_dir_drive, len_dir_drive);
1258
1259         usr->logon_count = logon_count;
1260         usr->bad_pw_count = bad_pw_count;
1261
1262         usr->user_id = pdb_get_user_rid(sampw);
1263         usr->group_id = pdb_get_group_rid(sampw);
1264         usr->num_groups = num_groups;
1265         usr->buffer_groups = 1; /* indicates fill in groups, below, even if there are none */
1266         usr->user_flgs = user_flgs;
1267
1268         if (sess_key != NULL)
1269                 memcpy(usr->user_sess_key, sess_key, sizeof(usr->user_sess_key));
1270         else
1271                 memset((char *)usr->user_sess_key, '\0', sizeof(usr->user_sess_key));
1272
1273         init_uni_hdr(&usr->hdr_logon_srv, len_logon_srv);
1274         init_uni_hdr(&usr->hdr_logon_dom, len_logon_dom);
1275
1276         usr->buffer_dom_id = dom_sid ? 1 : 0; /* yes, we're bothering to put a domain SID in */
1277
1278         memset((char *)usr->padding, '\0', sizeof(usr->padding));
1279
1280         num_other_sids = init_dom_sid2s(ctx, other_sids, &usr->other_sids);
1281
1282         usr->num_other_sids = num_other_sids;
1283         usr->buffer_other_sids = (num_other_sids != 0) ? 1 : 0; 
1284         
1285         init_unistr2(&usr->uni_user_name, user_name, len_user_name);
1286         init_unistr2(&usr->uni_full_name, full_name, len_full_name);
1287         init_unistr2(&usr->uni_logon_script, logon_script, len_logon_script);
1288         init_unistr2(&usr->uni_profile_path, profile_path, len_profile_path);
1289         init_unistr2(&usr->uni_home_dir, home_dir, len_home_dir);
1290         init_unistr2(&usr->uni_dir_drive, dir_drive, len_dir_drive);
1291
1292         usr->num_groups2 = num_groups;
1293
1294         if (num_groups > 0) {
1295                 usr->gids = (DOM_GID *)talloc_zero(ctx,sizeof(DOM_GID) * num_groups);
1296                 if (usr->gids == NULL)
1297                         return;
1298                 for (i = 0; i < num_groups; i++)
1299                         usr->gids[i] = gids[i];
1300         }
1301
1302         init_unistr2(&usr->uni_logon_srv, logon_srv, len_logon_srv);
1303         init_unistr2(&usr->uni_logon_dom, logon_dom, len_logon_dom);
1304
1305         init_dom_sid2(&usr->dom_sid, dom_sid);
1306         /* "other" sids are set up above */
1307 }
1308
1309 /*******************************************************************
1310  This code has been modified to cope with a NET_USER_INFO_2 - which is
1311  exactly the same as a NET_USER_INFO_3, minus the other sids parameters.
1312  We use validation level to determine if we're marshalling a info 2 or
1313  INFO_3 - be we always return an INFO_3. Based on code donated by Marc
1314  Jacobsen at HP. JRA.
1315 ********************************************************************/
1316
1317 static BOOL net_io_user_info3(char *desc, NET_USER_INFO_3 *usr, prs_struct *ps, int depth, uint16 validation_level)
1318 {
1319         int i;
1320
1321         if (usr == NULL)
1322                 return False;
1323
1324         prs_debug(ps, depth, desc, "lsa_io_lsa_user_info");
1325         depth++;
1326
1327         if (UNMARSHALLING(ps))
1328                 ZERO_STRUCTP(usr);
1329
1330         if(!prs_align(ps))
1331                 return False;
1332         
1333         if(!prs_uint32("ptr_user_info ", ps, depth, &usr->ptr_user_info))
1334                 return False;
1335
1336         if (usr->ptr_user_info == 0)
1337                 return True;
1338
1339         if(!smb_io_time("time", &usr->logon_time, ps, depth)) /* logon time */
1340                 return False;
1341         if(!smb_io_time("time", &usr->logoff_time, ps, depth)) /* logoff time */
1342                 return False;
1343         if(!smb_io_time("time", &usr->kickoff_time, ps, depth)) /* kickoff time */
1344                 return False;
1345         if(!smb_io_time("time", &usr->pass_last_set_time, ps, depth)) /* password last set time */
1346                 return False;
1347         if(!smb_io_time("time", &usr->pass_can_change_time , ps, depth)) /* password can change time */
1348                 return False;
1349         if(!smb_io_time("time", &usr->pass_must_change_time, ps, depth)) /* password must change time */
1350                 return False;
1351
1352         if(!smb_io_unihdr("unihdr", &usr->hdr_user_name, ps, depth)) /* username unicode string header */
1353                 return False;
1354         if(!smb_io_unihdr("unihdr", &usr->hdr_full_name, ps, depth)) /* user's full name unicode string header */
1355                 return False;
1356         if(!smb_io_unihdr("unihdr", &usr->hdr_logon_script, ps, depth)) /* logon script unicode string header */
1357                 return False;
1358         if(!smb_io_unihdr("unihdr", &usr->hdr_profile_path, ps, depth)) /* profile path unicode string header */
1359                 return False;
1360         if(!smb_io_unihdr("unihdr", &usr->hdr_home_dir, ps, depth)) /* home directory unicode string header */
1361                 return False;
1362         if(!smb_io_unihdr("unihdr", &usr->hdr_dir_drive, ps, depth)) /* home directory drive unicode string header */
1363                 return False;
1364
1365         if(!prs_uint16("logon_count   ", ps, depth, &usr->logon_count))  /* logon count */
1366                 return False;
1367         if(!prs_uint16("bad_pw_count  ", ps, depth, &usr->bad_pw_count)) /* bad password count */
1368                 return False;
1369
1370         if(!prs_uint32("user_id       ", ps, depth, &usr->user_id))       /* User ID */
1371                 return False;
1372         if(!prs_uint32("group_id      ", ps, depth, &usr->group_id))      /* Group ID */
1373                 return False;
1374         if(!prs_uint32("num_groups    ", ps, depth, &usr->num_groups))    /* num groups */
1375                 return False;
1376         if(!prs_uint32("buffer_groups ", ps, depth, &usr->buffer_groups)) /* undocumented buffer pointer to groups. */
1377                 return False;
1378         if(!prs_uint32("user_flgs     ", ps, depth, &usr->user_flgs))     /* user flags */
1379                 return False;
1380
1381         if(!prs_uint8s(False, "user_sess_key", ps, depth, usr->user_sess_key, 16)) /* unused user session key */
1382                 return False;
1383
1384         if(!smb_io_unihdr("unihdr", &usr->hdr_logon_srv, ps, depth)) /* logon server unicode string header */
1385                 return False;
1386         if(!smb_io_unihdr("unihdr", &usr->hdr_logon_dom, ps, depth)) /* logon domain unicode string header */
1387                 return False;
1388
1389         if(!prs_uint32("buffer_dom_id ", ps, depth, &usr->buffer_dom_id)) /* undocumented logon domain id pointer */
1390                 return False;
1391         if(!prs_uint8s (False, "padding       ", ps, depth, usr->padding, 40)) /* unused padding bytes? */
1392                 return False;
1393
1394         if (validation_level == 3) {
1395                 if(!prs_uint32("num_other_sids", ps, depth, &usr->num_other_sids)) /* 0 - num_sids */
1396                         return False;
1397                 if(!prs_uint32("buffer_other_sids", ps, depth, &usr->buffer_other_sids)) /* NULL - undocumented pointer to SIDs. */
1398                         return False;
1399         } else {
1400                 if (UNMARSHALLING(ps)) {
1401                         usr->num_other_sids = 0;
1402                         usr->buffer_other_sids = 0;
1403                 }
1404         }
1405                 
1406         if(!smb_io_unistr2("unistr2", &usr->uni_user_name, usr->hdr_user_name.buffer, ps, depth)) /* username unicode string */
1407                 return False;
1408         if(!smb_io_unistr2("unistr2", &usr->uni_full_name, usr->hdr_full_name.buffer, ps, depth)) /* user's full name unicode string */
1409                 return False;
1410         if(!smb_io_unistr2("unistr2", &usr->uni_logon_script, usr->hdr_logon_script.buffer, ps, depth)) /* logon script unicode string */
1411                 return False;
1412         if(!smb_io_unistr2("unistr2", &usr->uni_profile_path, usr->hdr_profile_path.buffer, ps, depth)) /* profile path unicode string */
1413                 return False;
1414         if(!smb_io_unistr2("unistr2", &usr->uni_home_dir, usr->hdr_home_dir.buffer, ps, depth)) /* home directory unicode string */
1415                 return False;
1416         if(!smb_io_unistr2("unistr2", &usr->uni_dir_drive, usr->hdr_dir_drive.buffer, ps, depth)) /* home directory drive unicode string */
1417                 return False;
1418
1419         if(!prs_align(ps))
1420                 return False;
1421         if(!prs_uint32("num_groups2   ", ps, depth, &usr->num_groups2))        /* num groups */
1422                 return False;
1423
1424         if (UNMARSHALLING(ps) && usr->num_groups2 > 0) {
1425                 usr->gids = (DOM_GID *)prs_alloc_mem(ps, sizeof(DOM_GID)*usr->num_groups2);
1426                 if (usr->gids == NULL)
1427                         return False;
1428         }
1429
1430         for (i = 0; i < usr->num_groups2; i++) {
1431                 if(!smb_io_gid("", &usr->gids[i], ps, depth)) /* group info */
1432                         return False;
1433         }
1434
1435         if(!smb_io_unistr2("unistr2", &usr->uni_logon_srv, usr->hdr_logon_srv.buffer, ps, depth)) /* logon server unicode string */
1436                 return False;
1437         if(!smb_io_unistr2("unistr2", &usr->uni_logon_dom, usr->hdr_logon_srv.buffer, ps, depth)) /* logon domain unicode string */
1438                 return False;
1439
1440         if(!smb_io_dom_sid2("", &usr->dom_sid, ps, depth))           /* domain SID */
1441                 return False;
1442
1443         if (usr->num_other_sids) {
1444
1445                 if (UNMARSHALLING(ps)) {
1446                         usr->other_sids = (DOM_SID2 *)prs_alloc_mem(ps, sizeof(DOM_SID2)*usr->num_other_sids);
1447                         if (usr->other_sids == NULL)
1448                                 return False;
1449                 }
1450         
1451                 if(!prs_uint32("num_other_groups", ps, depth, &usr->num_other_groups))
1452                         return False;
1453
1454                 if (UNMARSHALLING(ps) && usr->num_other_groups > 0) {
1455                         usr->other_gids = (DOM_GID *)prs_alloc_mem(ps, sizeof(DOM_GID)*usr->num_other_groups);
1456                         if (usr->other_gids == NULL)
1457                                 return False;
1458                 }
1459         
1460                 for (i = 0; i < usr->num_other_groups; i++) {
1461                         if(!smb_io_gid("", &usr->other_gids[i], ps, depth)) /* other GIDs */
1462                                 return False;
1463                 }
1464                 for (i = 0; i < usr->num_other_sids; i++) {
1465                         if(!smb_io_dom_sid2("", &usr->other_sids[i], ps, depth)) /* other domain SIDs */
1466                                 return False;
1467                 }
1468         }
1469
1470         return True;
1471 }
1472
1473 /*******************************************************************
1474  Reads or writes a structure.
1475 ********************************************************************/
1476
1477 BOOL net_io_q_sam_logon(char *desc, NET_Q_SAM_LOGON *q_l, prs_struct *ps, int depth)
1478 {
1479         if (q_l == NULL)
1480                 return False;
1481
1482         prs_debug(ps, depth, desc, "net_io_q_sam_logon");
1483         depth++;
1484
1485         if(!prs_align(ps))
1486                 return False;
1487         
1488         if(!smb_io_sam_info("", &q_l->sam_id, ps, depth))           /* domain SID */
1489                 return False;
1490
1491         if(!prs_uint16("validation_level", ps, depth, &q_l->validation_level))
1492                 return False;
1493
1494         return True;
1495 }
1496
1497 /*******************************************************************
1498  Reads or writes a structure.
1499 ********************************************************************/
1500
1501 BOOL net_io_r_sam_logon(char *desc, NET_R_SAM_LOGON *r_l, prs_struct *ps, int depth)
1502 {
1503         if (r_l == NULL)
1504                 return False;
1505
1506         prs_debug(ps, depth, desc, "net_io_r_sam_logon");
1507         depth++;
1508
1509         if(!prs_uint32("buffer_creds", ps, depth, &r_l->buffer_creds)) /* undocumented buffer pointer */
1510                 return False;
1511         if(!smb_io_cred("", &r_l->srv_creds, ps, depth)) /* server credentials.  server time stamp appears to be ignored. */
1512                 return False;
1513
1514         if(!prs_uint16("switch_value", ps, depth, &r_l->switch_value))
1515                 return False;
1516         if(!prs_align(ps))
1517                 return False;
1518
1519 #if 1 /* W2k always needs this - even for bad passwd. JRA */
1520         if(!net_io_user_info3("", r_l->user, ps, depth, r_l->switch_value))
1521                 return False;
1522 #else
1523         if (r_l->switch_value != 0) {
1524                 if(!net_io_user_info3("", r_l->user, ps, depth, r_l->switch_value))
1525                         return False;
1526         }
1527 #endif
1528
1529         if(!prs_uint32("auth_resp   ", ps, depth, &r_l->auth_resp)) /* 1 - Authoritative response; 0 - Non-Auth? */
1530                 return False;
1531
1532         if(!prs_uint32("status      ", ps, depth, &r_l->status))
1533                 return False;
1534
1535         if(!prs_align(ps))
1536                 return False;
1537
1538         return True;
1539 }
1540
1541 /*******************************************************************
1542  Reads or writes a structure.
1543 ********************************************************************/
1544
1545 BOOL net_io_q_sam_logoff(char *desc,  NET_Q_SAM_LOGOFF *q_l, prs_struct *ps, int depth)
1546 {
1547         if (q_l == NULL)
1548                 return False;
1549
1550         prs_debug(ps, depth, desc, "net_io_q_sam_logoff");
1551         depth++;
1552
1553         if(!prs_align(ps))
1554                 return False;
1555         
1556         if(!smb_io_sam_info("", &q_l->sam_id, ps, depth))           /* domain SID */
1557                 return False;
1558
1559         return True;
1560 }
1561
1562 /*******************************************************************
1563  Reads or writes a structure.
1564 ********************************************************************/
1565
1566 BOOL net_io_r_sam_logoff(char *desc, NET_R_SAM_LOGOFF *r_l, prs_struct *ps, int depth)
1567 {
1568         if (r_l == NULL)
1569                 return False;
1570
1571         prs_debug(ps, depth, desc, "net_io_r_sam_logoff");
1572         depth++;
1573
1574         if(!prs_align(ps))
1575                 return False;
1576         
1577         if(!prs_uint32("buffer_creds", ps, depth, &r_l->buffer_creds)) /* undocumented buffer pointer */
1578                 return False;
1579         if(!smb_io_cred("", &r_l->srv_creds, ps, depth)) /* server credentials.  server time stamp appears to be ignored. */
1580                 return False;
1581
1582         if(!prs_uint32("status      ", ps, depth, &r_l->status))
1583                 return False;
1584
1585         return True;
1586 }