Merge of new 2.2 code into HEAD (Gerald I hate you :-) :-). Allows new SAMR
[tprouty/samba.git] / source / 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_R_LOGON_CTRL2 structure.
221 ********************************************************************/
222
223 void init_r_logon_ctrl2(NET_R_LOGON_CTRL2 *r_l, uint32 query_level,
224                                 uint32 flags, uint32 pdc_status, uint32 logon_attempts,
225                                 uint32 tc_status, char *trusted_domain_name)
226 {
227         DEBUG(5,("make_r_logon_ctrl2\n"));
228
229         r_l->switch_value  = query_level; /* should only be 0x1 */
230
231         switch (query_level) {
232         case 1:
233                 r_l->ptr = 1; /* undocumented pointer */
234                 init_netinfo_1(&r_l->logon.info1, flags, pdc_status);   
235                 r_l->status = 0;
236                 break;
237         case 2:
238                 r_l->ptr = 1; /* undocumented pointer */
239                 init_netinfo_2(&r_l->logon.info2, flags, pdc_status,
240                                tc_status, trusted_domain_name); 
241                 r_l->status = 0;
242                 break;
243         case 3:
244                 r_l->ptr = 1; /* undocumented pointer */
245                 init_netinfo_3(&(r_l->logon.info3), flags, logon_attempts);     
246                 r_l->status = 0;
247                 break;
248         default:
249                 DEBUG(2,("init_r_logon_ctrl2: unsupported switch value %d\n",
250                         r_l->switch_value));
251                 r_l->ptr = 0; /* undocumented pointer */
252
253                 /* take a guess at an error code... */
254                 r_l->status = NT_STATUS_INVALID_INFO_CLASS;
255                 break;
256         }
257 }
258
259 /*******************************************************************
260  Reads or writes an NET_R_LOGON_CTRL2 structure.
261 ********************************************************************/
262
263 BOOL net_io_r_logon_ctrl2(char *desc, NET_R_LOGON_CTRL2 *r_l, prs_struct *ps, int depth)
264 {
265         if (r_l == NULL)
266                 return False;
267
268         prs_debug(ps, depth, desc, "net_io_r_logon_ctrl2");
269         depth++;
270
271         if(!prs_uint32("switch_value ", ps, depth, &r_l->switch_value))
272                 return False;
273         if(!prs_uint32("ptr          ", ps, depth, &r_l->ptr))
274                 return False;
275
276         if (r_l->ptr != 0) {
277                 switch (r_l->switch_value) {
278                 case 1:
279                         if(!net_io_netinfo_1("", &r_l->logon.info1, ps, depth))
280                                 return False;
281                         break;
282                 case 2:
283                         if(!net_io_netinfo_2("", &r_l->logon.info2, ps, depth))
284                                 return False;
285                         break;
286                 case 3:
287                         if(!net_io_netinfo_3("", &r_l->logon.info3, ps, depth))
288                                 return False;
289                         break;
290                 default:
291                         DEBUG(2,("net_io_r_logon_ctrl2: unsupported switch value %d\n",
292                                 r_l->switch_value));
293                         break;
294                 }
295         }
296
297         if(!prs_uint32("status       ", ps, depth, &r_l->status))
298                 return False;
299
300         return True;
301 }
302
303 /*******************************************************************
304  Inits an NET_R_TRUST_DOM_LIST structure.
305 ********************************************************************/
306
307 void init_r_trust_dom(NET_R_TRUST_DOM_LIST *r_t,
308                         uint32 num_doms, char *dom_name)
309 {
310         int i = 0;
311
312         DEBUG(5,("make_r_trust_dom\n"));
313
314         for (i = 0; i < MAX_TRUST_DOMS; i++) {
315                 r_t->uni_trust_dom_name[i].uni_str_len = 0;
316                 r_t->uni_trust_dom_name[i].uni_max_len = 0;
317         }
318         if (num_doms > MAX_TRUST_DOMS)
319                 num_doms = MAX_TRUST_DOMS;
320
321         for (i = 0; i < num_doms; i++) {
322                 fstring domain_name;
323                 fstrcpy(domain_name, dom_name);
324                 strupper(domain_name);
325                 init_unistr2(&r_t->uni_trust_dom_name[i], domain_name, strlen(domain_name)+1);
326                 /* the use of UNISTR2 here is non-standard. */
327                 r_t->uni_trust_dom_name[i].undoc = 0x1;
328         }
329         
330         r_t->status = 0;
331 }
332
333 /*******************************************************************
334  Reads or writes an NET_R_TRUST_DOM_LIST structure.
335 ********************************************************************/
336
337 BOOL net_io_r_trust_dom(char *desc, NET_R_TRUST_DOM_LIST *r_t, prs_struct *ps, int depth)
338 {
339         uint32 value;
340
341         if (r_t == NULL)
342                  return False;
343
344         prs_debug(ps, depth, desc, "net_io_r_trust_dom");
345         depth++;
346
347         /* temporary code to give a valid response */
348         value=2;
349         if(!prs_uint32("status", ps, depth, &value))
350                  return False;
351
352         value=1;
353         if(!prs_uint32("status", ps, depth, &value))
354                  return False;
355         value=2;
356         if(!prs_uint32("status", ps, depth, &value))
357                  return False;
358
359         value=0;
360         if(!prs_uint32("status", ps, depth, &value))
361                  return False;
362
363         value=0;
364         if(!prs_uint32("status", ps, depth, &value))
365                  return False;
366
367 /* old non working code */
368 #if 0
369         int i;
370
371         for (i = 0; i < MAX_TRUST_DOMS; i++) {
372                 if (r_t->uni_trust_dom_name[i].uni_str_len == 0)
373                         break;
374                 if(!smb_io_unistr2("", &r_t->uni_trust_dom_name[i], True, ps, depth))
375                          return False;
376         }
377
378         if(!prs_uint32("status", ps, depth, &r_t->status))
379                  return False;
380 #endif
381         return True;
382 }
383
384
385 /*******************************************************************
386  Reads or writes an NET_Q_TRUST_DOM_LIST structure.
387 ********************************************************************/
388
389 BOOL net_io_q_trust_dom(char *desc, NET_Q_TRUST_DOM_LIST *q_l, prs_struct *ps, int depth)
390 {
391         if (q_l == NULL)
392                  return False;
393
394         prs_debug(ps, depth, desc, "net_io_q_trust_dom");
395         depth++;
396
397         if(!prs_uint32("ptr          ", ps, depth, &q_l->ptr))
398                  return False;
399         if(!smb_io_unistr2 ("", &q_l->uni_server_name, q_l->ptr, ps, depth))
400                  return False;
401
402         return True;
403 }
404
405 /*******************************************************************
406  Inits an NET_Q_REQ_CHAL structure.
407 ********************************************************************/
408
409 void init_q_req_chal(NET_Q_REQ_CHAL *q_c,
410                                 char *logon_srv, char *logon_clnt,
411                                 DOM_CHAL *clnt_chal)
412 {
413         DEBUG(5,("make_q_req_chal: %d\n", __LINE__));
414
415         q_c->undoc_buffer = 1; /* don't know what this buffer is */
416
417         init_unistr2(&q_c->uni_logon_srv, logon_srv , strlen(logon_srv )+1);
418         init_unistr2(&q_c->uni_logon_clnt, logon_clnt, strlen(logon_clnt)+1);
419
420         memcpy(q_c->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data));
421
422         DEBUG(5,("make_q_req_chal: %d\n", __LINE__));
423 }
424
425 /*******************************************************************
426  Reads or writes an NET_Q_REQ_CHAL structure.
427 ********************************************************************/
428
429 BOOL net_io_q_req_chal(char *desc,  NET_Q_REQ_CHAL *q_c, prs_struct *ps, int depth)
430 {
431         int old_align;
432
433         if (q_c == NULL)
434                 return False;
435
436         prs_debug(ps, depth, desc, "net_io_q_req_chal");
437         depth++;
438
439         if(!prs_align(ps))
440                 return False;
441     
442         if(!prs_uint32("undoc_buffer", ps, depth, &q_c->undoc_buffer))
443                 return False;
444
445         if(!smb_io_unistr2("", &q_c->uni_logon_srv, True, ps, depth)) /* logon server unicode string */
446                 return False;
447         if(!smb_io_unistr2("", &q_c->uni_logon_clnt, True, ps, depth)) /* logon client unicode string */
448                 return False;
449
450         old_align = ps->align;
451         ps->align = 0;
452         /* client challenge is _not_ aligned after the unicode strings */
453         if(!smb_io_chal("", &q_c->clnt_chal, ps, depth)) {
454                 /* client challenge */
455                 ps->align = old_align;
456                 return False;
457         }
458         ps->align = old_align;
459
460         return True;
461 }
462
463 /*******************************************************************
464  Reads or writes a structure.
465 ********************************************************************/
466
467 BOOL net_io_r_req_chal(char *desc, NET_R_REQ_CHAL *r_c, prs_struct *ps, int depth)
468 {
469         if (r_c == NULL)
470                 return False;
471
472         prs_debug(ps, depth, desc, "net_io_r_req_chal");
473         depth++;
474
475         if(!prs_align(ps))
476                 return False;
477     
478         if(!smb_io_chal("", &r_c->srv_chal, ps, depth)) /* server challenge */
479                 return False;
480
481         if(!prs_uint32("status", ps, depth, &r_c->status))
482                 return False;
483
484         return True;
485 }
486
487
488 /*******************************************************************
489  Inits a NET_Q_AUTH_2 struct.
490 ********************************************************************/
491
492 void init_q_auth_2(NET_Q_AUTH_2 *q_a,
493                 char *logon_srv, char *acct_name, uint16 sec_chan, char *comp_name,
494                 DOM_CHAL *clnt_chal, uint32 clnt_flgs)
495 {
496         DEBUG(5,("init_q_auth_2: %d\n", __LINE__));
497
498         init_log_info(&q_a->clnt_id, logon_srv, acct_name, sec_chan, comp_name);
499         memcpy(q_a->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data));
500         q_a->clnt_flgs.neg_flags = clnt_flgs;
501
502         DEBUG(5,("init_q_auth_2: %d\n", __LINE__));
503 }
504
505 /*******************************************************************
506  Reads or writes a structure.
507 ********************************************************************/
508
509 BOOL net_io_q_auth_2(char *desc, NET_Q_AUTH_2 *q_a, prs_struct *ps, int depth)
510 {
511         int old_align;
512         if (q_a == NULL)
513                 return False;
514
515         prs_debug(ps, depth, desc, "net_io_q_auth_2");
516         depth++;
517
518         if(!prs_align(ps))
519                 return False;
520     
521         if(!smb_io_log_info ("", &q_a->clnt_id, ps, depth)) /* client identification info */
522                 return False;
523         /* client challenge is _not_ aligned */
524         old_align = ps->align;
525         ps->align = 0;
526         if(!smb_io_chal("", &q_a->clnt_chal, ps, depth)) {
527                 /* client-calculated credentials */
528                 ps->align = old_align;
529                 return False;
530         }
531         ps->align = old_align;
532         if(!net_io_neg_flags("", &q_a->clnt_flgs, ps, depth))
533                 return False;
534
535         return True;
536 }
537
538 /*******************************************************************
539  Reads or writes a structure.
540 ********************************************************************/
541
542 BOOL net_io_r_auth_2(char *desc, NET_R_AUTH_2 *r_a, prs_struct *ps, int depth)
543 {
544         if (r_a == NULL)
545                 return False;
546
547         prs_debug(ps, depth, desc, "net_io_r_auth_2");
548         depth++;
549
550         if(!prs_align(ps))
551                 return False;
552     
553         if(!smb_io_chal("", &r_a->srv_chal, ps, depth)) /* server challenge */
554                 return False;
555         if(!net_io_neg_flags("", &r_a->srv_flgs, ps, depth))
556                 return False;
557
558         if(!prs_uint32("status", ps, depth, &r_a->status))
559                 return False;
560
561         return True;
562 }
563
564
565 /*******************************************************************
566  Inits a NET_Q_SRV_PWSET.
567 ********************************************************************/
568
569 void init_q_srv_pwset(NET_Q_SRV_PWSET *q_s, char *logon_srv, char *acct_name, 
570                 uint16 sec_chan, char *comp_name, DOM_CRED *cred, char nt_cypher[16])
571 {
572         DEBUG(5,("make_q_srv_pwset\n"));
573
574         init_clnt_info(&q_s->clnt_id, logon_srv, acct_name, sec_chan, comp_name, cred);
575
576         memcpy(q_s->pwd, nt_cypher, sizeof(q_s->pwd)); 
577 }
578
579 /*******************************************************************
580  Reads or writes a structure.
581 ********************************************************************/
582
583 BOOL net_io_q_srv_pwset(char *desc, NET_Q_SRV_PWSET *q_s, prs_struct *ps, int depth)
584 {
585         if (q_s == NULL)
586                 return False;
587
588         prs_debug(ps, depth, desc, "net_io_q_srv_pwset");
589         depth++;
590
591         if(!prs_align(ps))
592                 return False;
593     
594         if(!smb_io_clnt_info("", &q_s->clnt_id, ps, depth)) /* client identification/authentication info */
595                 return False;
596         if(!prs_uint8s (False, "pwd", ps, depth, q_s->pwd, 16)) /* new password - undocumented */
597                 return False;
598
599         return True;
600 }
601
602 /*******************************************************************
603  Reads or writes a structure.
604 ********************************************************************/
605
606 BOOL net_io_r_srv_pwset(char *desc, NET_R_SRV_PWSET *r_s, prs_struct *ps, int depth)
607 {
608         if (r_s == NULL)
609                 return False;
610
611         prs_debug(ps, depth, desc, "net_io_r_srv_pwset");
612         depth++;
613
614         if(!prs_align(ps))
615                 return False;
616     
617         if(!smb_io_cred("", &r_s->srv_cred, ps, depth)) /* server challenge */
618                 return False;
619
620         if(!prs_uint32("status", ps, depth, &r_s->status))
621                 return False;
622
623         return True;
624 }
625
626 /*************************************************************************
627  Init DOM_SID2 array from a string containing multiple sids
628  *************************************************************************/
629
630 static int init_dom_sid2s(TALLOC_CTX *ctx, char *sids_str, DOM_SID2 **ppsids)
631 {
632         char *ptr;
633         pstring s2;
634         int count = 0;
635
636         DEBUG(4,("init_dom_sid2s: %s\n", sids_str ? sids_str:""));
637
638         *ppsids = NULL;
639
640         if(sids_str) {
641                 int number;
642                 DOM_SID2 *sids;
643
644                 /* Count the number of SIDs. */
645                 for (count = 0, ptr = sids_str; 
646                   next_token(&ptr, s2, NULL, sizeof(s2)); count++)
647                         ;
648
649                 /* Now allocate space for them. */
650                 *ppsids = (DOM_SID2 *)talloc_zero(ctx, count * sizeof(DOM_SID2));
651                 if (*ppsids == NULL)
652                         return 0;
653
654                 sids = *ppsids;
655
656                 for (number = 0, ptr = sids_str; 
657                   next_token(&ptr, s2, NULL, sizeof(s2)); number++) {
658                         DOM_SID tmpsid;
659                         string_to_sid(&tmpsid, s2);
660                         init_dom_sid2(&sids[number], &tmpsid);
661                 }
662         }
663
664         return count;
665 }
666
667 /*******************************************************************
668  Inits a NET_ID_INFO_1 structure.
669 ********************************************************************/
670
671 void init_id_info1(NET_ID_INFO_1 *id, char *domain_name,
672                                 uint32 param_ctrl, uint32 log_id_low, uint32 log_id_high,
673                                 char *user_name, char *wksta_name,
674                                 char *sess_key,
675                                 unsigned char lm_cypher[16], unsigned char nt_cypher[16])
676 {
677         int len_domain_name = strlen(domain_name);
678         int len_user_name   = strlen(user_name  );
679         int len_wksta_name  = strlen(wksta_name );
680
681         unsigned char lm_owf[16];
682         unsigned char nt_owf[16];
683
684         DEBUG(5,("make_id_info1: %d\n", __LINE__));
685
686         id->ptr_id_info1 = 1;
687
688         init_uni_hdr(&id->hdr_domain_name, len_domain_name);
689
690         id->param_ctrl = param_ctrl;
691         init_logon_id(&id->logon_id, log_id_low, log_id_high);
692
693         init_uni_hdr(&id->hdr_user_name, len_user_name);
694         init_uni_hdr(&id->hdr_wksta_name, len_wksta_name);
695
696         if (lm_cypher && nt_cypher) {
697                 unsigned char key[16];
698 #ifdef DEBUG_PASSWORD
699                 DEBUG(100,("lm cypher:"));
700                 dump_data(100, (char *)lm_cypher, 16);
701
702                 DEBUG(100,("nt cypher:"));
703                 dump_data(100, (char *)nt_cypher, 16);
704 #endif
705
706                 memset(key, 0, 16);
707                 memcpy(key, sess_key, 8);
708
709                 memcpy(lm_owf, lm_cypher, 16);
710                 SamOEMhash(lm_owf, key, False);
711                 memcpy(nt_owf, nt_cypher, 16);
712                 SamOEMhash(nt_owf, key, False);
713
714 #ifdef DEBUG_PASSWORD
715                 DEBUG(100,("encrypt of lm owf password:"));
716                 dump_data(100, (char *)lm_owf, 16);
717
718                 DEBUG(100,("encrypt of nt owf password:"));
719                 dump_data(100, (char *)nt_owf, 16);
720 #endif
721                 /* set up pointers to cypher blocks */
722                 lm_cypher = lm_owf;
723                 nt_cypher = nt_owf;
724         }
725
726         init_owf_info(&id->lm_owf, lm_cypher);
727         init_owf_info(&id->nt_owf, nt_cypher);
728
729         init_unistr2(&id->uni_domain_name, domain_name, len_domain_name);
730         init_unistr2(&id->uni_user_name, user_name, len_user_name);
731         init_unistr2(&id->uni_wksta_name, wksta_name, len_wksta_name);
732 }
733
734 /*******************************************************************
735  Reads or writes an NET_ID_INFO_1 structure.
736 ********************************************************************/
737
738 static BOOL net_io_id_info1(char *desc,  NET_ID_INFO_1 *id, prs_struct *ps, int depth)
739 {
740         if (id == NULL)
741                 return False;
742
743         prs_debug(ps, depth, desc, "net_io_id_info1");
744         depth++;
745
746         if(!prs_align(ps))
747                 return False;
748         
749         if(!prs_uint32("ptr_id_info1", ps, depth, &id->ptr_id_info1))
750                 return False;
751
752         if (id->ptr_id_info1 != 0) {
753                 if(!smb_io_unihdr("unihdr", &id->hdr_domain_name, ps, depth))
754                         return False;
755
756                 if(!prs_uint32("param_ctrl", ps, depth, &id->param_ctrl))
757                         return False;
758                 if(!smb_io_logon_id("", &id->logon_id, ps, depth))
759                         return False;
760
761                 if(!smb_io_unihdr("unihdr", &id->hdr_user_name, ps, depth))
762                         return False;
763                 if(!smb_io_unihdr("unihdr", &id->hdr_wksta_name, ps, depth))
764                         return False;
765
766                 if(!smb_io_owf_info("", &id->lm_owf, ps, depth))
767                         return False;
768                 if(!smb_io_owf_info("", &id->nt_owf, ps, depth))
769                         return False;
770
771                 if(!smb_io_unistr2("unistr2", &id->uni_domain_name,
772                                 id->hdr_domain_name.buffer, ps, depth))
773                         return False;
774                 if(!smb_io_unistr2("unistr2", &id->uni_user_name,
775                                 id->hdr_user_name.buffer, ps, depth))
776                         return False;
777                 if(!smb_io_unistr2("unistr2", &id->uni_wksta_name,
778                                 id->hdr_wksta_name.buffer, ps, depth))
779                         return False;
780         }
781
782         return True;
783 }
784
785 /*******************************************************************
786 Inits a NET_ID_INFO_2 structure.
787
788 This is a network logon packet. The log_id parameters
789 are what an NT server would generate for LUID once the
790 user is logged on. I don't think we care about them.
791
792 Note that this has no access to the NT and LM hashed passwords,
793 so it forwards the challenge, and the NT and LM responses (24
794 bytes each) over the secure channel to the Domain controller
795 for it to say yea or nay. This is the preferred method of 
796 checking for a logon as it doesn't export the password
797 hashes to anyone who has compromised the secure channel. JRA.
798 ********************************************************************/
799
800 void init_id_info2(NET_ID_INFO_2 *id, char *domain_name,
801                                 uint32 param_ctrl, uint32 log_id_low, uint32 log_id_high,
802                                 char *user_name, char *wksta_name,
803                                 unsigned char lm_challenge[8],
804                                 unsigned char *lm_chal_resp,
805                                 unsigned char *nt_chal_resp)
806 {
807         int len_domain_name = strlen(domain_name);
808         int len_user_name   = strlen(user_name  );
809         int len_wksta_name  = strlen(wksta_name );
810         int nt_chal_resp_len = ((nt_chal_resp != NULL) ? 24 : 0);
811         int lm_chal_resp_len = ((lm_chal_resp != NULL) ? 24 : 0);
812         unsigned char lm_owf[24];
813         unsigned char nt_owf[24];
814
815         DEBUG(5,("init_id_info2: %d\n", __LINE__));
816
817         id->ptr_id_info2 = 1;
818
819         init_uni_hdr(&id->hdr_domain_name, len_domain_name);
820
821         id->param_ctrl = param_ctrl;
822         init_logon_id(&id->logon_id, log_id_low, log_id_high);
823
824         init_uni_hdr(&id->hdr_user_name, len_user_name);
825         init_uni_hdr(&id->hdr_wksta_name, len_wksta_name);
826
827         if (nt_chal_resp) {
828                 /* oops.  can only send what-ever-it-is direct */
829                 memcpy(nt_owf, nt_chal_resp, 24);
830                 nt_chal_resp = nt_owf;
831         }
832         if (lm_chal_resp) {
833                 /* oops.  can only send what-ever-it-is direct */
834                 memcpy(lm_owf, lm_chal_resp, 24);
835                 lm_chal_resp = lm_owf;
836         }
837
838         memcpy(id->lm_chal, lm_challenge, sizeof(id->lm_chal));
839         init_str_hdr(&id->hdr_nt_chal_resp, 24, nt_chal_resp_len, (nt_chal_resp != NULL) ? 1 : 0);
840         init_str_hdr(&id->hdr_lm_chal_resp, 24, lm_chal_resp_len, (lm_chal_resp != NULL) ? 1 : 0);
841
842         init_unistr2(&id->uni_domain_name, domain_name, len_domain_name);
843         init_unistr2(&id->uni_user_name, user_name, len_user_name);
844         init_unistr2(&id->uni_wksta_name, wksta_name, len_wksta_name);
845
846         init_string2(&id->nt_chal_resp, (char *)nt_chal_resp, nt_chal_resp_len);
847         init_string2(&id->lm_chal_resp, (char *)lm_chal_resp, lm_chal_resp_len);
848 }
849
850 /*******************************************************************
851  Reads or writes an NET_ID_INFO_2 structure.
852 ********************************************************************/
853
854 static BOOL net_io_id_info2(char *desc,  NET_ID_INFO_2 *id, prs_struct *ps, int depth)
855 {
856         if (id == NULL)
857                 return False;
858
859         prs_debug(ps, depth, desc, "net_io_id_info2");
860         depth++;
861
862         if(!prs_align(ps))
863                 return False;
864         
865         if(!prs_uint32("ptr_id_info2", ps, depth, &id->ptr_id_info2))
866                 return False;
867
868         if (id->ptr_id_info2 != 0) {
869                 if(!smb_io_unihdr("unihdr", &id->hdr_domain_name, ps, depth))
870                         return False;
871
872                 if(!prs_uint32("param_ctrl", ps, depth, &id->param_ctrl))
873                         return False;
874                 if(!smb_io_logon_id("", &id->logon_id, ps, depth))
875                         return False;
876
877                 if(!smb_io_unihdr("unihdr", &id->hdr_user_name, ps, depth))
878                         return False;
879                 if(!smb_io_unihdr("unihdr", &id->hdr_wksta_name, ps, depth))
880                         return False;
881
882                 if(!prs_uint8s (False, "lm_chal", ps, depth, id->lm_chal, 8)) /* lm 8 byte challenge */
883                         return False;
884
885                 if(!smb_io_strhdr("hdr_nt_chal_resp", &id->hdr_nt_chal_resp, ps, depth))
886                         return False;
887                 if(!smb_io_strhdr("hdr_lm_chal_resp", &id->hdr_lm_chal_resp, ps, depth))
888                         return False;
889
890                 if(!smb_io_unistr2("uni_domain_name", &id->uni_domain_name,
891                                 id->hdr_domain_name.buffer, ps, depth))
892                         return False;
893                 if(!smb_io_unistr2("uni_user_name  ", &id->uni_user_name,
894                                 id->hdr_user_name.buffer, ps, depth))
895                         return False;
896                 if(!smb_io_unistr2("uni_wksta_name ", &id->uni_wksta_name,
897                                 id->hdr_wksta_name.buffer, ps, depth))
898                         return False;
899                 if(!smb_io_string2("nt_chal_resp", &id->nt_chal_resp,
900                                 id->hdr_nt_chal_resp.buffer, ps, depth))
901                         return False;
902                 if(!smb_io_string2("lm_chal_resp", &id->lm_chal_resp,
903                                 id->hdr_lm_chal_resp.buffer, ps, depth))
904                         return False;
905         }
906
907         return True;
908 }
909
910
911 /*******************************************************************
912  Inits a DOM_SAM_INFO structure.
913 ********************************************************************/
914
915 void init_sam_info(DOM_SAM_INFO *sam,
916                                 char *logon_srv, char *comp_name, DOM_CRED *clnt_cred,
917                                 DOM_CRED *rtn_cred, uint16 logon_level,
918                                 NET_ID_INFO_CTR *ctr)
919 {
920         DEBUG(5,("init_sam_info: %d\n", __LINE__));
921
922         init_clnt_info2(&(sam->client), logon_srv, comp_name, clnt_cred);
923
924         if (rtn_cred != NULL) {
925                 sam->ptr_rtn_cred = 1;
926                 memcpy(&sam->rtn_cred, rtn_cred, sizeof(sam->rtn_cred));
927         } else {
928                 sam->ptr_rtn_cred = 0;
929         }
930
931         sam->logon_level  = logon_level;
932         sam->ctr          = ctr;
933 }
934
935 /*******************************************************************
936  Reads or writes a DOM_SAM_INFO structure.
937 ********************************************************************/
938
939 static BOOL net_io_id_info_ctr(char *desc, NET_ID_INFO_CTR **pp_ctr, prs_struct *ps, int depth)
940 {
941         NET_ID_INFO_CTR *ctr = *pp_ctr;
942
943         prs_debug(ps, depth, desc, "smb_io_sam_info");
944         depth++;
945
946         if (UNMARSHALLING(ps)) {
947                 ctr = *pp_ctr = (NET_ID_INFO_CTR *)prs_alloc_mem(ps, sizeof(NET_ID_INFO_CTR));
948                 if (ctr == NULL)
949                         return False;
950         }
951         
952         if (ctr == NULL)
953                 return False;
954
955         /* don't 4-byte align here! */
956
957         if(!prs_uint16("switch_value ", ps, depth, &ctr->switch_value))
958                 return False;
959
960         switch (ctr->switch_value) {
961         case 1:
962                 if(!net_io_id_info1("", &ctr->auth.id1, ps, depth))
963                         return False;
964                 break;
965         case 2:
966                 if(!net_io_id_info2("", &ctr->auth.id2, ps, depth))
967                         return False;
968                 break;
969         default:
970                 /* PANIC! */
971                 DEBUG(4,("smb_io_sam_info: unknown switch_value!\n"));
972                 break;
973         }
974
975         return True;
976 }
977
978 /*******************************************************************
979  Reads or writes a DOM_SAM_INFO structure.
980  ********************************************************************/
981
982 static BOOL smb_io_sam_info(char *desc, DOM_SAM_INFO *sam, prs_struct *ps, int depth)
983 {
984         if (sam == NULL)
985                 return False;
986
987         prs_debug(ps, depth, desc, "smb_io_sam_info");
988         depth++;
989
990         if(!prs_align(ps))
991                 return False;
992         
993         if(!smb_io_clnt_info2("", &sam->client, ps, depth))
994                 return False;
995
996         if(!prs_uint32("ptr_rtn_cred ", ps, depth, &sam->ptr_rtn_cred))
997                 return False;
998         if(!smb_io_cred("", &sam->rtn_cred, ps, depth))
999                 return False;
1000
1001         if(!prs_uint16("logon_level  ", ps, depth, &sam->logon_level))
1002                 return False;
1003
1004         if (sam->logon_level != 0) {
1005                 if(!net_io_id_info_ctr("logon_info", &sam->ctr, ps, depth))
1006                         return False;
1007         }
1008
1009         return True;
1010 }
1011
1012 /*************************************************************************
1013  Init
1014  *************************************************************************/
1015
1016 void init_net_user_info3(TALLOC_CTX *ctx, NET_USER_INFO_3 *usr, SAM_ACCOUNT *sampw,
1017                          uint16 logon_count, uint16 bad_pw_count,
1018                          uint32 num_groups, DOM_GID *gids,
1019                          uint32 user_flgs, char *sess_key,
1020                          char *logon_srv, char *logon_dom,
1021                          DOM_SID *dom_sid, char *other_sids)
1022 {
1023         /* only cope with one "other" sid, right now. */
1024         /* need to count the number of space-delimited sids */
1025         int i;
1026         int num_other_sids = 0;
1027         
1028         NTTIME          logon_time, logoff_time, kickoff_time,
1029                         pass_last_set_time, pass_can_change_time,
1030                         pass_must_change_time;
1031
1032         int             len_user_name, len_full_name, len_home_dir,
1033                         len_dir_drive, len_logon_script, len_profile_path;
1034                         
1035         char*           user_name = pdb_get_username(sampw);
1036         char*           full_name = pdb_get_fullname(sampw);
1037         char*           home_dir  = pdb_get_homedir(sampw);
1038         char*           dir_drive = pdb_get_dirdrive(sampw);
1039         char*           logon_script = pdb_get_logon_script(sampw);
1040         char*           profile_path = pdb_get_profile_path(sampw);
1041
1042         int len_logon_srv    = strlen(logon_srv);
1043         int len_logon_dom    = strlen(logon_dom);
1044
1045         len_user_name    = strlen(user_name   );
1046         len_full_name    = strlen(full_name   );
1047         len_home_dir     = strlen(home_dir    );
1048         len_dir_drive    = strlen(dir_drive   );
1049         len_logon_script = strlen(logon_script);
1050         len_profile_path = strlen(profile_path);
1051
1052
1053         ZERO_STRUCTP(usr);
1054
1055         usr->ptr_user_info = 1; /* yes, we're bothering to put USER_INFO data here */
1056
1057
1058         /* Create NTTIME structs */
1059         unix_to_nt_time (&logon_time,           pdb_get_logon_time(sampw));
1060         unix_to_nt_time (&logoff_time,          pdb_get_logoff_time(sampw));
1061         unix_to_nt_time (&kickoff_time,         pdb_get_kickoff_time(sampw));
1062         unix_to_nt_time (&pass_last_set_time,   pdb_get_pass_last_set_time(sampw));
1063         unix_to_nt_time (&pass_can_change_time, pdb_get_pass_can_change_time(sampw));
1064         unix_to_nt_time (&pass_must_change_time,pdb_get_pass_must_change_time(sampw));
1065
1066         usr->logon_time            = logon_time;
1067         usr->logoff_time           = logoff_time;
1068         usr->kickoff_time          = kickoff_time;
1069         usr->pass_last_set_time    = pass_last_set_time;
1070         usr->pass_can_change_time  = pass_can_change_time;
1071         usr->pass_must_change_time = pass_must_change_time;
1072
1073         init_uni_hdr(&usr->hdr_user_name, len_user_name);
1074         init_uni_hdr(&usr->hdr_full_name, len_full_name);
1075         init_uni_hdr(&usr->hdr_logon_script, len_logon_script);
1076         init_uni_hdr(&usr->hdr_profile_path, len_profile_path);
1077         init_uni_hdr(&usr->hdr_home_dir, len_home_dir);
1078         init_uni_hdr(&usr->hdr_dir_drive, len_dir_drive);
1079
1080         usr->logon_count = logon_count;
1081         usr->bad_pw_count = bad_pw_count;
1082
1083         usr->user_id = pdb_get_user_rid(sampw);
1084         usr->group_id = pdb_get_group_rid(sampw);
1085         usr->num_groups = num_groups;
1086         usr->buffer_groups = 1; /* indicates fill in groups, below, even if there are none */
1087         usr->user_flgs = user_flgs;
1088
1089         if (sess_key != NULL)
1090                 memcpy(usr->user_sess_key, sess_key, sizeof(usr->user_sess_key));
1091         else
1092                 memset((char *)usr->user_sess_key, '\0', sizeof(usr->user_sess_key));
1093
1094         init_uni_hdr(&usr->hdr_logon_srv, len_logon_srv);
1095         init_uni_hdr(&usr->hdr_logon_dom, len_logon_dom);
1096
1097         usr->buffer_dom_id = dom_sid ? 1 : 0; /* yes, we're bothering to put a domain SID in */
1098
1099         memset((char *)usr->padding, '\0', sizeof(usr->padding));
1100
1101         num_other_sids = init_dom_sid2s(ctx, other_sids, &usr->other_sids);
1102
1103         usr->num_other_sids = num_other_sids;
1104         usr->buffer_other_sids = (num_other_sids != 0) ? 1 : 0; 
1105         
1106         init_unistr2(&usr->uni_user_name, user_name, len_user_name);
1107         init_unistr2(&usr->uni_full_name, full_name, len_full_name);
1108         init_unistr2(&usr->uni_logon_script, logon_script, len_logon_script);
1109         init_unistr2(&usr->uni_profile_path, profile_path, len_profile_path);
1110         init_unistr2(&usr->uni_home_dir, home_dir, len_home_dir);
1111         init_unistr2(&usr->uni_dir_drive, dir_drive, len_dir_drive);
1112
1113         usr->num_groups2 = num_groups;
1114
1115         if (num_groups > 0) {
1116                 usr->gids = (DOM_GID *)talloc_zero(ctx,sizeof(DOM_GID) * num_groups);
1117                 if (usr->gids == NULL)
1118                         return;
1119                 for (i = 0; i < num_groups; i++)
1120                         usr->gids[i] = gids[i];
1121         }
1122
1123         init_unistr2(&usr->uni_logon_srv, logon_srv, len_logon_srv);
1124         init_unistr2(&usr->uni_logon_dom, logon_dom, len_logon_dom);
1125
1126         init_dom_sid2(&usr->dom_sid, dom_sid);
1127         /* "other" sids are set up above */
1128 }
1129
1130 /*******************************************************************
1131  This code has been modified to cope with a NET_USER_INFO_2 - which is
1132  exactly the same as a NET_USER_INFO_3, minus the other sids parameters.
1133  We use validation level to determine if we're marshalling a info 2 or
1134  INFO_3 - be we always return an INFO_3. Based on code donated by Marc
1135  Jacobsen at HP. JRA.
1136 ********************************************************************/
1137
1138 static BOOL net_io_user_info3(char *desc, NET_USER_INFO_3 *usr, prs_struct *ps, int depth, uint16 validation_level)
1139 {
1140         int i;
1141
1142         if (usr == NULL)
1143                 return False;
1144
1145         prs_debug(ps, depth, desc, "lsa_io_lsa_user_info");
1146         depth++;
1147
1148         if (UNMARSHALLING(ps))
1149                 ZERO_STRUCTP(usr);
1150
1151         if(!prs_align(ps))
1152                 return False;
1153         
1154         if(!prs_uint32("ptr_user_info ", ps, depth, &usr->ptr_user_info))
1155                 return False;
1156
1157         if (usr->ptr_user_info == 0)
1158                 return True;
1159
1160         if(!smb_io_time("time", &usr->logon_time, ps, depth)) /* logon time */
1161                 return False;
1162         if(!smb_io_time("time", &usr->logoff_time, ps, depth)) /* logoff time */
1163                 return False;
1164         if(!smb_io_time("time", &usr->kickoff_time, ps, depth)) /* kickoff time */
1165                 return False;
1166         if(!smb_io_time("time", &usr->pass_last_set_time, ps, depth)) /* password last set time */
1167                 return False;
1168         if(!smb_io_time("time", &usr->pass_can_change_time , ps, depth)) /* password can change time */
1169                 return False;
1170         if(!smb_io_time("time", &usr->pass_must_change_time, ps, depth)) /* password must change time */
1171                 return False;
1172
1173         if(!smb_io_unihdr("unihdr", &usr->hdr_user_name, ps, depth)) /* username unicode string header */
1174                 return False;
1175         if(!smb_io_unihdr("unihdr", &usr->hdr_full_name, ps, depth)) /* user's full name unicode string header */
1176                 return False;
1177         if(!smb_io_unihdr("unihdr", &usr->hdr_logon_script, ps, depth)) /* logon script unicode string header */
1178                 return False;
1179         if(!smb_io_unihdr("unihdr", &usr->hdr_profile_path, ps, depth)) /* profile path unicode string header */
1180                 return False;
1181         if(!smb_io_unihdr("unihdr", &usr->hdr_home_dir, ps, depth)) /* home directory unicode string header */
1182                 return False;
1183         if(!smb_io_unihdr("unihdr", &usr->hdr_dir_drive, ps, depth)) /* home directory drive unicode string header */
1184                 return False;
1185
1186         if(!prs_uint16("logon_count   ", ps, depth, &usr->logon_count))  /* logon count */
1187                 return False;
1188         if(!prs_uint16("bad_pw_count  ", ps, depth, &usr->bad_pw_count)) /* bad password count */
1189                 return False;
1190
1191         if(!prs_uint32("user_id       ", ps, depth, &usr->user_id))       /* User ID */
1192                 return False;
1193         if(!prs_uint32("group_id      ", ps, depth, &usr->group_id))      /* Group ID */
1194                 return False;
1195         if(!prs_uint32("num_groups    ", ps, depth, &usr->num_groups))    /* num groups */
1196                 return False;
1197         if(!prs_uint32("buffer_groups ", ps, depth, &usr->buffer_groups)) /* undocumented buffer pointer to groups. */
1198                 return False;
1199         if(!prs_uint32("user_flgs     ", ps, depth, &usr->user_flgs))     /* user flags */
1200                 return False;
1201
1202         if(!prs_uint8s(False, "user_sess_key", ps, depth, usr->user_sess_key, 16)) /* unused user session key */
1203                 return False;
1204
1205         if(!smb_io_unihdr("unihdr", &usr->hdr_logon_srv, ps, depth)) /* logon server unicode string header */
1206                 return False;
1207         if(!smb_io_unihdr("unihdr", &usr->hdr_logon_dom, ps, depth)) /* logon domain unicode string header */
1208                 return False;
1209
1210         if(!prs_uint32("buffer_dom_id ", ps, depth, &usr->buffer_dom_id)) /* undocumented logon domain id pointer */
1211                 return False;
1212         if(!prs_uint8s (False, "padding       ", ps, depth, usr->padding, 40)) /* unused padding bytes? */
1213                 return False;
1214
1215         if (validation_level == 3) {
1216                 if(!prs_uint32("num_other_sids", ps, depth, &usr->num_other_sids)) /* 0 - num_sids */
1217                         return False;
1218                 if(!prs_uint32("buffer_other_sids", ps, depth, &usr->buffer_other_sids)) /* NULL - undocumented pointer to SIDs. */
1219                         return False;
1220         } else {
1221                 if (UNMARSHALLING(ps)) {
1222                         usr->num_other_sids = 0;
1223                         usr->buffer_other_sids = 0;
1224                 }
1225         }
1226                 
1227         if(!smb_io_unistr2("unistr2", &usr->uni_user_name, usr->hdr_user_name.buffer, ps, depth)) /* username unicode string */
1228                 return False;
1229         if(!smb_io_unistr2("unistr2", &usr->uni_full_name, usr->hdr_full_name.buffer, ps, depth)) /* user's full name unicode string */
1230                 return False;
1231         if(!smb_io_unistr2("unistr2", &usr->uni_logon_script, usr->hdr_logon_script.buffer, ps, depth)) /* logon script unicode string */
1232                 return False;
1233         if(!smb_io_unistr2("unistr2", &usr->uni_profile_path, usr->hdr_profile_path.buffer, ps, depth)) /* profile path unicode string */
1234                 return False;
1235         if(!smb_io_unistr2("unistr2", &usr->uni_home_dir, usr->hdr_home_dir.buffer, ps, depth)) /* home directory unicode string */
1236                 return False;
1237         if(!smb_io_unistr2("unistr2", &usr->uni_dir_drive, usr->hdr_dir_drive.buffer, ps, depth)) /* home directory drive unicode string */
1238                 return False;
1239
1240         if(!prs_align(ps))
1241                 return False;
1242         if(!prs_uint32("num_groups2   ", ps, depth, &usr->num_groups2))        /* num groups */
1243                 return False;
1244
1245         if (UNMARSHALLING(ps) && usr->num_groups2 > 0) {
1246                 usr->gids = (DOM_GID *)prs_alloc_mem(ps, sizeof(DOM_GID)*usr->num_groups2);
1247                 if (usr->gids == NULL)
1248                         return False;
1249         }
1250
1251         for (i = 0; i < usr->num_groups2; i++) {
1252                 if(!smb_io_gid("", &usr->gids[i], ps, depth)) /* group info */
1253                         return False;
1254         }
1255
1256         if(!smb_io_unistr2("unistr2", &usr->uni_logon_srv, usr->hdr_logon_srv.buffer, ps, depth)) /* logon server unicode string */
1257                 return False;
1258         if(!smb_io_unistr2("unistr2", &usr->uni_logon_dom, usr->hdr_logon_srv.buffer, ps, depth)) /* logon domain unicode string */
1259                 return False;
1260
1261         if(!smb_io_dom_sid2("", &usr->dom_sid, ps, depth))           /* domain SID */
1262                 return False;
1263
1264         if (usr->num_other_sids) {
1265
1266                 if (UNMARSHALLING(ps)) {
1267                         usr->other_sids = (DOM_SID2 *)prs_alloc_mem(ps, sizeof(DOM_SID2)*usr->num_other_sids);
1268                         if (usr->other_sids == NULL)
1269                                 return False;
1270                 }
1271         
1272                 if(!prs_uint32("num_other_groups", ps, depth, &usr->num_other_groups))
1273                         return False;
1274
1275                 if (UNMARSHALLING(ps) && usr->num_other_groups > 0) {
1276                         usr->other_gids = (DOM_GID *)prs_alloc_mem(ps, sizeof(DOM_GID)*usr->num_other_groups);
1277                         if (usr->other_gids == NULL)
1278                                 return False;
1279                 }
1280         
1281                 for (i = 0; i < usr->num_other_groups; i++) {
1282                         if(!smb_io_gid("", &usr->other_gids[i], ps, depth)) /* other GIDs */
1283                                 return False;
1284                 }
1285                 for (i = 0; i < usr->num_other_sids; i++) {
1286                         if(!smb_io_dom_sid2("", &usr->other_sids[i], ps, depth)) /* other domain SIDs */
1287                                 return False;
1288                 }
1289         }
1290
1291         return True;
1292 }
1293
1294 /*******************************************************************
1295  Reads or writes a structure.
1296 ********************************************************************/
1297
1298 BOOL net_io_q_sam_logon(char *desc, NET_Q_SAM_LOGON *q_l, prs_struct *ps, int depth)
1299 {
1300         if (q_l == NULL)
1301                 return False;
1302
1303         prs_debug(ps, depth, desc, "net_io_q_sam_logon");
1304         depth++;
1305
1306         if(!prs_align(ps))
1307                 return False;
1308         
1309         if(!smb_io_sam_info("", &q_l->sam_id, ps, depth))           /* domain SID */
1310                 return False;
1311
1312         if(!prs_uint16("validation_level", ps, depth, &q_l->validation_level))
1313                 return False;
1314
1315         return True;
1316 }
1317
1318 /*******************************************************************
1319  Reads or writes a structure.
1320 ********************************************************************/
1321
1322 BOOL net_io_r_sam_logon(char *desc, NET_R_SAM_LOGON *r_l, prs_struct *ps, int depth)
1323 {
1324         if (r_l == NULL)
1325                 return False;
1326
1327         prs_debug(ps, depth, desc, "net_io_r_sam_logon");
1328         depth++;
1329
1330         if(!prs_uint32("buffer_creds", ps, depth, &r_l->buffer_creds)) /* undocumented buffer pointer */
1331                 return False;
1332         if(!smb_io_cred("", &r_l->srv_creds, ps, depth)) /* server credentials.  server time stamp appears to be ignored. */
1333                 return False;
1334
1335         if(!prs_uint16("switch_value", ps, depth, &r_l->switch_value))
1336                 return False;
1337         if(!prs_align(ps))
1338                 return False;
1339
1340         if (r_l->switch_value != 0) {
1341                 if(!net_io_user_info3("", r_l->user, ps, depth, r_l->switch_value))
1342                         return False;
1343         }
1344
1345         if(!prs_uint32("auth_resp   ", ps, depth, &r_l->auth_resp)) /* 1 - Authoritative response; 0 - Non-Auth? */
1346                 return False;
1347
1348         if(!prs_uint32("status      ", ps, depth, &r_l->status))
1349                 return False;
1350
1351         if(!prs_align(ps))
1352                 return False;
1353
1354         return True;
1355 }
1356
1357 /*******************************************************************
1358  Reads or writes a structure.
1359 ********************************************************************/
1360
1361 BOOL net_io_q_sam_logoff(char *desc,  NET_Q_SAM_LOGOFF *q_l, prs_struct *ps, int depth)
1362 {
1363         if (q_l == NULL)
1364                 return False;
1365
1366         prs_debug(ps, depth, desc, "net_io_q_sam_logoff");
1367         depth++;
1368
1369         if(!prs_align(ps))
1370                 return False;
1371         
1372         if(!smb_io_sam_info("", &q_l->sam_id, ps, depth))           /* domain SID */
1373                 return False;
1374
1375         return True;
1376 }
1377
1378 /*******************************************************************
1379  Reads or writes a structure.
1380 ********************************************************************/
1381
1382 BOOL net_io_r_sam_logoff(char *desc, NET_R_SAM_LOGOFF *r_l, prs_struct *ps, int depth)
1383 {
1384         if (r_l == NULL)
1385                 return False;
1386
1387         prs_debug(ps, depth, desc, "net_io_r_sam_logoff");
1388         depth++;
1389
1390         if(!prs_align(ps))
1391                 return False;
1392         
1393         if(!prs_uint32("buffer_creds", ps, depth, &r_l->buffer_creds)) /* undocumented buffer pointer */
1394                 return False;
1395         if(!smb_io_cred("", &r_l->srv_creds, ps, depth)) /* server credentials.  server time stamp appears to be ignored. */
1396                 return False;
1397
1398         if(!prs_uint32("status      ", ps, depth, &r_l->status))
1399                 return False;
1400
1401         return True;
1402 }