it now all compiles - so try enabling it by default and see what explodes on the...
[kai/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_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 = NT_STATUS_OK;
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 = NT_STATUS_OK;
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 = NT_STATUS_OK;
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_ntstatus("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 = NT_STATUS_OK;
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_ntstatus("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 = NT_STATUS_OK;
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_ntstatus("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_ntstatus("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_ntstatus("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_ntstatus("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_ntstatus("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, const char *domain_name,
980                    uint32 param_ctrl,
981                    uint32 log_id_low, uint32 log_id_high,
982                    const char *user_name, const char *wksta_name,
983                    const uchar lm_challenge[8],
984                    const uchar * lm_chal_resp, int lm_chal_resp_len,
985                    const uchar * nt_chal_resp, int nt_chal_resp_len)
986 {
987         int len_domain_name = strlen(domain_name);
988         int len_user_name   = strlen(user_name  );
989         int len_wksta_name  = strlen(wksta_name );
990         unsigned char lm_owf[24];
991         unsigned char nt_owf[128];
992
993         DEBUG(5,("init_id_info2: %d\n", __LINE__));
994
995         id->ptr_id_info2 = 1;
996
997         init_uni_hdr(&id->hdr_domain_name, len_domain_name);
998
999         id->param_ctrl = param_ctrl;
1000         init_logon_id(&id->logon_id, log_id_low, log_id_high);
1001
1002         init_uni_hdr(&id->hdr_user_name, len_user_name);
1003         init_uni_hdr(&id->hdr_wksta_name, len_wksta_name);
1004
1005         if (nt_chal_resp) {
1006                 /* oops.  can only send what-ever-it-is direct */
1007                 memcpy(nt_owf, nt_chal_resp, 24);
1008                 nt_chal_resp = nt_owf;
1009         }
1010         if (lm_chal_resp) {
1011                 /* oops.  can only send what-ever-it-is direct */
1012                 memcpy(lm_owf, lm_chal_resp, 24);
1013                 lm_chal_resp = lm_owf;
1014         }
1015
1016         memcpy(id->lm_chal, lm_challenge, sizeof(id->lm_chal));
1017         init_str_hdr(&id->hdr_nt_chal_resp, sizeof(lm_owf), nt_chal_resp_len, (nt_chal_resp != NULL) ? 1 : 0);
1018         init_str_hdr(&id->hdr_lm_chal_resp, sizeof(nt_owf), lm_chal_resp_len, (lm_chal_resp != NULL) ? 1 : 0);
1019
1020         init_unistr2(&id->uni_domain_name, domain_name, len_domain_name);
1021         init_unistr2(&id->uni_user_name, user_name, len_user_name);
1022         init_unistr2(&id->uni_wksta_name, wksta_name, len_wksta_name);
1023
1024         init_string2(&id->nt_chal_resp, (const char *)nt_chal_resp, nt_chal_resp_len);
1025         init_string2(&id->lm_chal_resp, (const char *)lm_chal_resp, lm_chal_resp_len);
1026
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+1;
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         /* always have at least one group == the user's primary group */
1293         usr->num_groups2 = num_groups+1;
1294
1295         usr->gids = (DOM_GID *)talloc_zero(ctx,sizeof(DOM_GID) * (num_groups+1));
1296         if (usr->gids == NULL)
1297                 return;
1298
1299         /* primary group **MUST** go first.  NT4's winmsd.exe will give
1300            "The Network statistics are currently not available.  9-5"
1301            What the heck is this?     -- jerry  */
1302         usr->gids[0].g_rid = usr->group_id;
1303         usr->gids[0].attr  = 0x07;
1304         for (i = 0; i < num_groups; i++) 
1305                 usr->gids[i+1] = gids[i];       
1306                 
1307         init_unistr2(&usr->uni_logon_srv, logon_srv, len_logon_srv);
1308         init_unistr2(&usr->uni_logon_dom, logon_dom, len_logon_dom);
1309
1310         init_dom_sid2(&usr->dom_sid, dom_sid);
1311         /* "other" sids are set up above */
1312 }
1313
1314 /*******************************************************************
1315  This code has been modified to cope with a NET_USER_INFO_2 - which is
1316  exactly the same as a NET_USER_INFO_3, minus the other sids parameters.
1317  We use validation level to determine if we're marshalling a info 2 or
1318  INFO_3 - be we always return an INFO_3. Based on code donated by Marc
1319  Jacobsen at HP. JRA.
1320 ********************************************************************/
1321
1322 static BOOL net_io_user_info3(char *desc, NET_USER_INFO_3 *usr, prs_struct *ps, int depth, uint16 validation_level)
1323 {
1324         int i;
1325
1326         if (usr == NULL)
1327                 return False;
1328
1329         prs_debug(ps, depth, desc, "lsa_io_lsa_user_info");
1330         depth++;
1331
1332         if (UNMARSHALLING(ps))
1333                 ZERO_STRUCTP(usr);
1334
1335         if(!prs_align(ps))
1336                 return False;
1337         
1338         if(!prs_uint32("ptr_user_info ", ps, depth, &usr->ptr_user_info))
1339                 return False;
1340
1341         if (usr->ptr_user_info == 0)
1342                 return True;
1343
1344         if(!smb_io_time("time", &usr->logon_time, ps, depth)) /* logon time */
1345                 return False;
1346         if(!smb_io_time("time", &usr->logoff_time, ps, depth)) /* logoff time */
1347                 return False;
1348         if(!smb_io_time("time", &usr->kickoff_time, ps, depth)) /* kickoff time */
1349                 return False;
1350         if(!smb_io_time("time", &usr->pass_last_set_time, ps, depth)) /* password last set time */
1351                 return False;
1352         if(!smb_io_time("time", &usr->pass_can_change_time , ps, depth)) /* password can change time */
1353                 return False;
1354         if(!smb_io_time("time", &usr->pass_must_change_time, ps, depth)) /* password must change time */
1355                 return False;
1356
1357         if(!smb_io_unihdr("unihdr", &usr->hdr_user_name, ps, depth)) /* username unicode string header */
1358                 return False;
1359         if(!smb_io_unihdr("unihdr", &usr->hdr_full_name, ps, depth)) /* user's full name unicode string header */
1360                 return False;
1361         if(!smb_io_unihdr("unihdr", &usr->hdr_logon_script, ps, depth)) /* logon script unicode string header */
1362                 return False;
1363         if(!smb_io_unihdr("unihdr", &usr->hdr_profile_path, ps, depth)) /* profile path unicode string header */
1364                 return False;
1365         if(!smb_io_unihdr("unihdr", &usr->hdr_home_dir, ps, depth)) /* home directory unicode string header */
1366                 return False;
1367         if(!smb_io_unihdr("unihdr", &usr->hdr_dir_drive, ps, depth)) /* home directory drive unicode string header */
1368                 return False;
1369
1370         if(!prs_uint16("logon_count   ", ps, depth, &usr->logon_count))  /* logon count */
1371                 return False;
1372         if(!prs_uint16("bad_pw_count  ", ps, depth, &usr->bad_pw_count)) /* bad password count */
1373                 return False;
1374
1375         if(!prs_uint32("user_id       ", ps, depth, &usr->user_id))       /* User ID */
1376                 return False;
1377         if(!prs_uint32("group_id      ", ps, depth, &usr->group_id))      /* Group ID */
1378                 return False;
1379         if(!prs_uint32("num_groups    ", ps, depth, &usr->num_groups))    /* num groups */
1380                 return False;
1381         if(!prs_uint32("buffer_groups ", ps, depth, &usr->buffer_groups)) /* undocumented buffer pointer to groups. */
1382                 return False;
1383         if(!prs_uint32("user_flgs     ", ps, depth, &usr->user_flgs))     /* user flags */
1384                 return False;
1385
1386         if(!prs_uint8s(False, "user_sess_key", ps, depth, usr->user_sess_key, 16)) /* unused user session key */
1387                 return False;
1388
1389         if(!smb_io_unihdr("unihdr", &usr->hdr_logon_srv, ps, depth)) /* logon server unicode string header */
1390                 return False;
1391         if(!smb_io_unihdr("unihdr", &usr->hdr_logon_dom, ps, depth)) /* logon domain unicode string header */
1392                 return False;
1393
1394         if(!prs_uint32("buffer_dom_id ", ps, depth, &usr->buffer_dom_id)) /* undocumented logon domain id pointer */
1395                 return False;
1396         if(!prs_uint8s (False, "padding       ", ps, depth, usr->padding, 40)) /* unused padding bytes? */
1397                 return False;
1398
1399         if (validation_level == 3) {
1400                 if(!prs_uint32("num_other_sids", ps, depth, &usr->num_other_sids)) /* 0 - num_sids */
1401                         return False;
1402                 if(!prs_uint32("buffer_other_sids", ps, depth, &usr->buffer_other_sids)) /* NULL - undocumented pointer to SIDs. */
1403                         return False;
1404         } else {
1405                 if (UNMARSHALLING(ps)) {
1406                         usr->num_other_sids = 0;
1407                         usr->buffer_other_sids = 0;
1408                 }
1409         }
1410                 
1411         if(!smb_io_unistr2("unistr2", &usr->uni_user_name, usr->hdr_user_name.buffer, ps, depth)) /* username unicode string */
1412                 return False;
1413         if(!smb_io_unistr2("unistr2", &usr->uni_full_name, usr->hdr_full_name.buffer, ps, depth)) /* user's full name unicode string */
1414                 return False;
1415         if(!smb_io_unistr2("unistr2", &usr->uni_logon_script, usr->hdr_logon_script.buffer, ps, depth)) /* logon script unicode string */
1416                 return False;
1417         if(!smb_io_unistr2("unistr2", &usr->uni_profile_path, usr->hdr_profile_path.buffer, ps, depth)) /* profile path unicode string */
1418                 return False;
1419         if(!smb_io_unistr2("unistr2", &usr->uni_home_dir, usr->hdr_home_dir.buffer, ps, depth)) /* home directory unicode string */
1420                 return False;
1421         if(!smb_io_unistr2("unistr2", &usr->uni_dir_drive, usr->hdr_dir_drive.buffer, ps, depth)) /* home directory drive unicode string */
1422                 return False;
1423
1424         if(!prs_align(ps))
1425                 return False;
1426         if(!prs_uint32("num_groups2   ", ps, depth, &usr->num_groups2))        /* num groups */
1427                 return False;
1428
1429         if (UNMARSHALLING(ps) && usr->num_groups2 > 0) {
1430                 usr->gids = (DOM_GID *)prs_alloc_mem(ps, sizeof(DOM_GID)*usr->num_groups2);
1431                 if (usr->gids == NULL)
1432                         return False;
1433         }
1434
1435         for (i = 0; i < usr->num_groups2; i++) {
1436                 if(!smb_io_gid("", &usr->gids[i], ps, depth)) /* group info */
1437                         return False;
1438         }
1439
1440         if(!smb_io_unistr2("unistr2", &usr->uni_logon_srv, usr->hdr_logon_srv.buffer, ps, depth)) /* logon server unicode string */
1441                 return False;
1442         if(!smb_io_unistr2("unistr2", &usr->uni_logon_dom, usr->hdr_logon_srv.buffer, ps, depth)) /* logon domain unicode string */
1443                 return False;
1444
1445         if(!smb_io_dom_sid2("", &usr->dom_sid, ps, depth))           /* domain SID */
1446                 return False;
1447
1448         if (usr->num_other_sids) {
1449
1450                 if (UNMARSHALLING(ps)) {
1451                         usr->other_sids = (DOM_SID2 *)prs_alloc_mem(ps, sizeof(DOM_SID2)*usr->num_other_sids);
1452                         if (usr->other_sids == NULL)
1453                                 return False;
1454                 }
1455         
1456                 if(!prs_uint32("num_other_groups", ps, depth, &usr->num_other_groups))
1457                         return False;
1458
1459                 if (UNMARSHALLING(ps) && usr->num_other_groups > 0) {
1460                         usr->other_gids = (DOM_GID *)prs_alloc_mem(ps, sizeof(DOM_GID)*usr->num_other_groups);
1461                         if (usr->other_gids == NULL)
1462                                 return False;
1463                 }
1464         
1465                 for (i = 0; i < usr->num_other_groups; i++) {
1466                         if(!smb_io_gid("", &usr->other_gids[i], ps, depth)) /* other GIDs */
1467                                 return False;
1468                 }
1469                 for (i = 0; i < usr->num_other_sids; i++) {
1470                         if(!smb_io_dom_sid2("", &usr->other_sids[i], ps, depth)) /* other domain SIDs */
1471                                 return False;
1472                 }
1473         }
1474
1475         return True;
1476 }
1477
1478 /*******************************************************************
1479  Reads or writes a structure.
1480 ********************************************************************/
1481
1482 BOOL net_io_q_sam_logon(char *desc, NET_Q_SAM_LOGON *q_l, prs_struct *ps, int depth)
1483 {
1484         if (q_l == NULL)
1485                 return False;
1486
1487         prs_debug(ps, depth, desc, "net_io_q_sam_logon");
1488         depth++;
1489
1490         if(!prs_align(ps))
1491                 return False;
1492         
1493         if(!smb_io_sam_info("", &q_l->sam_id, ps, depth))           /* domain SID */
1494                 return False;
1495
1496         if(!prs_uint16("validation_level", ps, depth, &q_l->validation_level))
1497                 return False;
1498
1499         return True;
1500 }
1501
1502 /*******************************************************************
1503  Reads or writes a structure.
1504 ********************************************************************/
1505
1506 BOOL net_io_r_sam_logon(char *desc, NET_R_SAM_LOGON *r_l, prs_struct *ps, int depth)
1507 {
1508         if (r_l == NULL)
1509                 return False;
1510
1511         prs_debug(ps, depth, desc, "net_io_r_sam_logon");
1512         depth++;
1513
1514         if(!prs_uint32("buffer_creds", ps, depth, &r_l->buffer_creds)) /* undocumented buffer pointer */
1515                 return False;
1516         if(!smb_io_cred("", &r_l->srv_creds, ps, depth)) /* server credentials.  server time stamp appears to be ignored. */
1517                 return False;
1518
1519         if(!prs_uint16("switch_value", ps, depth, &r_l->switch_value))
1520                 return False;
1521         if(!prs_align(ps))
1522                 return False;
1523
1524 #if 1 /* W2k always needs this - even for bad passwd. JRA */
1525         if(!net_io_user_info3("", r_l->user, ps, depth, r_l->switch_value))
1526                 return False;
1527 #else
1528         if (r_l->switch_value != 0) {
1529                 if(!net_io_user_info3("", r_l->user, ps, depth, r_l->switch_value))
1530                         return False;
1531         }
1532 #endif
1533
1534         if(!prs_uint32("auth_resp   ", ps, depth, &r_l->auth_resp)) /* 1 - Authoritative response; 0 - Non-Auth? */
1535                 return False;
1536
1537         if(!prs_ntstatus("status      ", ps, depth, &r_l->status))
1538                 return False;
1539
1540         if(!prs_align(ps))
1541                 return False;
1542
1543         return True;
1544 }
1545
1546 /*******************************************************************
1547  Reads or writes a structure.
1548 ********************************************************************/
1549
1550 BOOL net_io_q_sam_logoff(char *desc,  NET_Q_SAM_LOGOFF *q_l, prs_struct *ps, int depth)
1551 {
1552         if (q_l == NULL)
1553                 return False;
1554
1555         prs_debug(ps, depth, desc, "net_io_q_sam_logoff");
1556         depth++;
1557
1558         if(!prs_align(ps))
1559                 return False;
1560         
1561         if(!smb_io_sam_info("", &q_l->sam_id, ps, depth))           /* domain SID */
1562                 return False;
1563
1564         return True;
1565 }
1566
1567 /*******************************************************************
1568  Reads or writes a structure.
1569 ********************************************************************/
1570
1571 BOOL net_io_r_sam_logoff(char *desc, NET_R_SAM_LOGOFF *r_l, prs_struct *ps, int depth)
1572 {
1573         if (r_l == NULL)
1574                 return False;
1575
1576         prs_debug(ps, depth, desc, "net_io_r_sam_logoff");
1577         depth++;
1578
1579         if(!prs_align(ps))
1580                 return False;
1581         
1582         if(!prs_uint32("buffer_creds", ps, depth, &r_l->buffer_creds)) /* undocumented buffer pointer */
1583                 return False;
1584         if(!smb_io_cred("", &r_l->srv_creds, ps, depth)) /* server credentials.  server time stamp appears to be ignored. */
1585                 return False;
1586
1587         if(!prs_ntstatus("status      ", ps, depth, &r_l->status))
1588                 return False;
1589
1590         return True;
1591 }
1592
1593 /*******************************************************************
1594 makes a NET_Q_SAM_SYNC structure.
1595 ********************************************************************/
1596 BOOL init_net_q_sam_sync(NET_Q_SAM_SYNC * q_s, const char *srv_name,
1597                          const char *cli_name, DOM_CRED * cli_creds, 
1598                          uint32 database_id)
1599 {
1600         DEBUG(5, ("init_q_sam_sync\n"));
1601
1602         init_unistr2(&q_s->uni_srv_name, srv_name, strlen(srv_name) + 1);
1603         init_unistr2(&q_s->uni_cli_name, cli_name, strlen(cli_name) + 1);
1604
1605         if (cli_creds) {
1606                 memcpy(&q_s->cli_creds, cli_creds, sizeof(q_s->cli_creds));
1607                 memset(&q_s->ret_creds, 0, sizeof(q_s->ret_creds));
1608         }
1609
1610         q_s->database_id = database_id;
1611         q_s->restart_state = 0;
1612         q_s->sync_context = 0;
1613         q_s->max_size = 0xffff;
1614
1615         return True;
1616 }
1617
1618 /*******************************************************************
1619 reads or writes a structure.
1620 ********************************************************************/
1621 BOOL net_io_q_sam_sync(char *desc, NET_Q_SAM_SYNC * q_s, prs_struct *ps,
1622                        int depth)
1623 {
1624         prs_debug(ps, depth, desc, "net_io_q_sam_sync");
1625         depth++;
1626
1627         if (!smb_io_unistr2("", &q_s->uni_srv_name, True, ps, depth))
1628                 return False;
1629         if (!smb_io_unistr2("", &q_s->uni_cli_name, True, ps, depth))
1630                 return False;
1631
1632         if (!smb_io_cred("", &q_s->cli_creds, ps, depth))
1633                 return False;
1634         if (!smb_io_cred("", &q_s->ret_creds, ps, depth))
1635                 return False;
1636
1637         if (!prs_uint32("database_id  ", ps, depth, &q_s->database_id))
1638                 return False;
1639         if (!prs_uint32("restart_state", ps, depth, &q_s->restart_state))
1640                 return False;
1641         if (!prs_uint32("sync_context ", ps, depth, &q_s->sync_context))
1642                 return False;
1643
1644         if (!prs_uint32("max_size", ps, depth, &q_s->max_size))
1645                 return False;
1646
1647         return True;
1648 }
1649
1650 /*******************************************************************
1651 reads or writes a structure.
1652 ********************************************************************/
1653 static BOOL net_io_sam_delta_hdr(char *desc, SAM_DELTA_HDR * delta,
1654                                  prs_struct *ps, int depth)
1655 {
1656         prs_debug(ps, depth, desc, "net_io_sam_delta_hdr");
1657         depth++;
1658
1659         if (!prs_uint16("type", ps, depth, &delta->type))
1660                 return False;
1661         if (!prs_uint16("type2", ps, depth, &delta->type2))
1662                 return False;
1663         if (!prs_uint32("target_rid", ps, depth, &delta->target_rid))
1664                 return False;
1665
1666         if (!prs_uint32("type3", ps, depth, &delta->type3))
1667                 return False;
1668
1669         /* Not sure why we need this but it seems to be necessary to get
1670            sam deltas working. */
1671
1672         if (delta->type != 0x16) {
1673                 if (!prs_uint32("ptr_delta", ps, depth, &delta->ptr_delta))
1674                         return False;
1675         }
1676
1677         return True;
1678 }
1679
1680 /*******************************************************************
1681 reads or writes a structure.
1682 ********************************************************************/
1683 static BOOL net_io_sam_delta_stamp(char *desc, SAM_DELTA_STAMP *info,
1684                                    prs_struct *ps, int depth)
1685 {
1686         prs_debug(ps, depth, desc, "net_io_sam_delta_stamp");
1687         depth++;
1688
1689         if (!prs_uint32("seqnum", ps, depth, &info->seqnum))
1690                 return False;
1691         if (!prs_uint32("dom_mod_count_ptr", ps, depth, 
1692                         &info->dom_mod_count_ptr))
1693                 return False;
1694
1695         if (info->dom_mod_count_ptr) {
1696                 if (!prs_uint64("dom_mod_count", ps, depth,
1697                                 &info->dom_mod_count))
1698                         return False;
1699         }
1700
1701         return True;
1702 }
1703
1704 /*******************************************************************
1705 reads or writes a structure.
1706 ********************************************************************/
1707 static BOOL net_io_sam_domain_info(char *desc, SAM_DOMAIN_INFO * info,
1708                                    prs_struct *ps, int depth)
1709 {
1710         prs_debug(ps, depth, desc, "net_io_sam_domain_info");
1711         depth++;
1712
1713         if (!smb_io_unihdr("hdr_dom_name", &info->hdr_dom_name, ps, depth))
1714                 return False;
1715         if (!smb_io_unihdr("hdr_oem_info", &info->hdr_oem_info, ps, depth))
1716                 return False;
1717
1718         if (!prs_uint64("force_logoff", ps, depth, &info->force_logoff))
1719                 return False;
1720         if (!prs_uint16("min_pwd_len", ps, depth, &info->min_pwd_len))
1721                 return False;
1722         if (!prs_uint16("pwd_history_len", ps, depth, &info->pwd_history_len))
1723                 return False;
1724         if (!prs_uint64("max_pwd_age", ps, depth, &info->max_pwd_age))
1725                 return False;
1726         if (!prs_uint64("min_pwd_age", ps, depth, &info->min_pwd_age))
1727                 return False;
1728         if (!prs_uint64("dom_mod_count", ps, depth, &info->dom_mod_count))
1729                 return False;
1730         if (!smb_io_time("creation_time", &info->creation_time, ps, depth))
1731                 return False;
1732
1733         if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
1734                 return False;
1735         if (!smb_io_unihdr("hdr_unknown", &info->hdr_unknown, ps, depth))
1736                 return False;
1737
1738         if (ps->data_offset + 40 > ps->buffer_size)
1739                 return False;
1740         ps->data_offset += 40;
1741
1742         if (!smb_io_unistr2("uni_dom_name", &info->uni_dom_name,
1743                             info->hdr_dom_name.buffer, ps, depth))
1744                 return False;
1745         if (!smb_io_unistr2("buf_oem_info", &info->buf_oem_info,
1746                             info->hdr_oem_info.buffer, ps, depth))
1747                 return False;
1748
1749         if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc,
1750                             info->hdr_sec_desc.buffer, ps, depth))
1751                 return False;
1752         if (!smb_io_unistr2("buf_unknown", &info->buf_unknown,
1753                             info->hdr_unknown.buffer, ps, depth))
1754                 return False;
1755
1756         return True;
1757 }
1758
1759 /*******************************************************************
1760 reads or writes a structure.
1761 ********************************************************************/
1762 static BOOL net_io_sam_group_info(char *desc, SAM_GROUP_INFO * info,
1763                                   prs_struct *ps, int depth)
1764 {
1765         prs_debug(ps, depth, desc, "net_io_sam_group_info");
1766         depth++;
1767
1768         if (!smb_io_unihdr("hdr_grp_name", &info->hdr_grp_name, ps, depth))
1769                 return False;
1770         if (!smb_io_gid("gid", &info->gid, ps, depth))
1771                 return False;
1772         if (!smb_io_unihdr("hdr_grp_desc", &info->hdr_grp_desc, ps, depth))
1773                 return False;
1774         if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
1775                 return False;
1776
1777         if (ps->data_offset + 48 > ps->buffer_size)
1778                 return False;
1779         ps->data_offset += 48;
1780
1781         if (!smb_io_unistr2("uni_grp_name", &info->uni_grp_name,
1782                             info->hdr_grp_name.buffer, ps, depth))
1783                 return False;
1784         if (!smb_io_unistr2("uni_grp_desc", &info->uni_grp_desc,
1785                             info->hdr_grp_desc.buffer, ps, depth))
1786                 return False;
1787         if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc,
1788                             info->hdr_sec_desc.buffer, ps, depth))
1789                 return False;
1790
1791         return True;
1792 }
1793
1794 /*******************************************************************
1795 reads or writes a structure.
1796 ********************************************************************/
1797 static BOOL net_io_sam_passwd_info(char *desc, SAM_PWD * pwd,
1798                                    prs_struct *ps, int depth)
1799 {
1800         prs_debug(ps, depth, desc, "net_io_sam_passwd_info");
1801         depth++;
1802
1803         if (!prs_uint32("unk_0 ", ps, depth, &pwd->unk_0))
1804                 return False;
1805
1806         if (!smb_io_unihdr("hdr_lm_pwd", &pwd->hdr_lm_pwd, ps, depth))
1807                 return False;
1808         if (!prs_uint8s(False, "buf_lm_pwd", ps, depth, pwd->buf_lm_pwd, 16))
1809                 return False;
1810
1811         if (!smb_io_unihdr("hdr_nt_pwd", &pwd->hdr_nt_pwd, ps, depth))
1812                 return False;
1813         if (!prs_uint8s(False, "buf_nt_pwd", ps, depth, pwd->buf_nt_pwd, 16))
1814                 return False;
1815
1816         if (!smb_io_unihdr("", &pwd->hdr_empty_lm, ps, depth))
1817                 return False;
1818         if (!smb_io_unihdr("", &pwd->hdr_empty_nt, ps, depth))
1819                 return False;
1820
1821         return True;
1822 }
1823
1824 /*******************************************************************
1825 makes a SAM_ACCOUNT_INFO structure.
1826 ********************************************************************/
1827 BOOL make_sam_account_info(SAM_ACCOUNT_INFO * info,
1828                            const UNISTR2 *user_name,
1829                            const UNISTR2 *full_name,
1830                            uint32 user_rid, uint32 group_rid,
1831                            const UNISTR2 *home_dir,
1832                            const UNISTR2 *dir_drive,
1833                            const UNISTR2 *log_scr,
1834                            const UNISTR2 *desc,
1835                            uint32 acb_info,
1836                            const UNISTR2 *prof_path,
1837                            const UNISTR2 *wkstas,
1838                            const UNISTR2 *unk_str, const UNISTR2 *mung_dial)
1839 {
1840         int len_user_name = user_name != NULL ? user_name->uni_str_len : 0;
1841         int len_full_name = full_name != NULL ? full_name->uni_str_len : 0;
1842         int len_home_dir = home_dir != NULL ? home_dir->uni_str_len : 0;
1843         int len_dir_drive = dir_drive != NULL ? dir_drive->uni_str_len : 0;
1844         int len_logon_script = log_scr != NULL ? log_scr->uni_str_len : 0;
1845         int len_profile_path = prof_path != NULL ? prof_path->uni_str_len : 0;
1846         int len_description = desc != NULL ? desc->uni_str_len : 0;
1847         int len_workstations = wkstas != NULL ? wkstas->uni_str_len : 0;
1848         int len_unknown_str = unk_str != NULL ? unk_str->uni_str_len : 0;
1849         int len_munged_dial = mung_dial != NULL ? mung_dial->uni_str_len : 0;
1850
1851         DEBUG(5, ("make_sam_account_info\n"));
1852
1853         make_uni_hdr(&info->hdr_acct_name, len_user_name);
1854         make_uni_hdr(&info->hdr_full_name, len_full_name);
1855         make_uni_hdr(&info->hdr_home_dir, len_home_dir);
1856         make_uni_hdr(&info->hdr_dir_drive, len_dir_drive);
1857         make_uni_hdr(&info->hdr_logon_script, len_logon_script);
1858         make_uni_hdr(&info->hdr_profile, len_profile_path);
1859         make_uni_hdr(&info->hdr_acct_desc, len_description);
1860         make_uni_hdr(&info->hdr_workstations, len_workstations);
1861         make_uni_hdr(&info->hdr_comment, len_unknown_str);
1862         make_uni_hdr(&info->hdr_parameters, len_munged_dial);
1863
1864         /* not present */
1865         make_bufhdr2(&info->hdr_sec_desc, 0, 0, 0);
1866
1867         info->user_rid = user_rid;
1868         info->group_rid = group_rid;
1869
1870         init_nt_time(&info->logon_time);
1871         init_nt_time(&info->logoff_time);
1872         init_nt_time(&info->pwd_last_set_time);
1873         init_nt_time(&info->acct_expiry_time);
1874
1875         info->logon_divs = 0xA8;
1876         info->ptr_logon_hrs = 0;        /* Don't care right now */
1877
1878         info->bad_pwd_count = 0;
1879         info->logon_count = 0;
1880         info->acb_info = acb_info;
1881         info->nt_pwd_present = 0;
1882         info->lm_pwd_present = 0;
1883         info->pwd_expired = 0;
1884         info->country = 0;
1885         info->codepage = 0;
1886
1887         info->unknown1 = 0x4EC;
1888         info->unknown2 = 0;
1889
1890         copy_unistr2(&info->uni_acct_name, user_name);
1891         copy_unistr2(&info->uni_full_name, full_name);
1892         copy_unistr2(&info->uni_home_dir, home_dir);
1893         copy_unistr2(&info->uni_dir_drive, dir_drive);
1894         copy_unistr2(&info->uni_logon_script, log_scr);
1895         copy_unistr2(&info->uni_profile, prof_path);
1896         copy_unistr2(&info->uni_acct_desc, desc);
1897         copy_unistr2(&info->uni_workstations, wkstas);
1898         copy_unistr2(&info->uni_comment, unk_str);
1899         copy_unistr2(&info->uni_parameters, mung_dial);
1900
1901         return True;
1902 }
1903
1904 /*******************************************************************
1905 reads or writes a structure.
1906 ********************************************************************/
1907 static BOOL net_io_sam_account_info(char *desc, uint8 sess_key[16],
1908                                     SAM_ACCOUNT_INFO * info, prs_struct *ps,
1909                                     int depth)
1910 {
1911         BUFHDR2 hdr_priv_data;
1912         uint32 i;
1913
1914         prs_debug(ps, depth, desc, "net_io_sam_account_info");
1915         depth++;
1916
1917         if (!smb_io_unihdr("hdr_acct_name", &info->hdr_acct_name, ps, depth))
1918                 return False;
1919         if (!smb_io_unihdr("hdr_full_name", &info->hdr_full_name, ps, depth))
1920                 return False;
1921
1922         if (!prs_uint32("user_rid ", ps, depth, &info->user_rid))
1923                 return False;
1924         if (!prs_uint32("group_rid", ps, depth, &info->group_rid))
1925                 return False;
1926
1927         if (!smb_io_unihdr("hdr_home_dir ", &info->hdr_home_dir, ps, depth))
1928                 return False;
1929         if (!smb_io_unihdr("hdr_dir_drive", &info->hdr_dir_drive, ps, depth))
1930                 return False;
1931         if (!smb_io_unihdr("hdr_logon_script", &info->hdr_logon_script, ps,
1932                            depth))
1933                 return False;
1934
1935         if (!smb_io_unihdr("hdr_acct_desc", &info->hdr_acct_desc, ps, depth))
1936                 return False;
1937         if (!smb_io_unihdr("hdr_workstations", &info->hdr_workstations, ps,
1938                            depth))
1939                 return False;
1940
1941         if (!smb_io_time("logon_time", &info->logon_time, ps, depth))
1942                 return False;
1943         if (!smb_io_time("logoff_time", &info->logoff_time, ps, depth))
1944                 return False;
1945
1946         if (!prs_uint32("logon_divs   ", ps, depth, &info->logon_divs))
1947                 return False;
1948         if (!prs_uint32("ptr_logon_hrs", ps, depth, &info->ptr_logon_hrs))
1949                 return False;
1950
1951         if (!prs_uint16("bad_pwd_count", ps, depth, &info->bad_pwd_count))
1952                 return False;
1953         if (!prs_uint16("logon_count", ps, depth, &info->logon_count))
1954                 return False;
1955         if (!smb_io_time("pwd_last_set_time", &info->pwd_last_set_time, ps,
1956                          depth))
1957                 return False;
1958         if (!smb_io_time("acct_expiry_time", &info->acct_expiry_time, ps, 
1959                          depth))
1960                 return False;
1961
1962         if (!prs_uint32("acb_info", ps, depth, &info->acb_info))
1963                 return False;
1964         if (!prs_uint8s(False, "nt_pwd", ps, depth, info->nt_pwd, 16))
1965                 return False;
1966         if (!prs_uint8s(False, "lm_pwd", ps, depth, info->lm_pwd, 16))
1967                 return False;
1968         if (!prs_uint8("lm_pwd_present", ps, depth, &info->lm_pwd_present))
1969                 return False;
1970         if (!prs_uint8("nt_pwd_present", ps, depth, &info->nt_pwd_present))
1971                 return False;
1972         if (!prs_uint8("pwd_expired", ps, depth, &info->pwd_expired))
1973                 return False;
1974
1975         if (!smb_io_unihdr("hdr_comment", &info->hdr_comment, ps, depth))
1976                 return False;
1977         if (!smb_io_unihdr("hdr_parameters", &info->hdr_parameters, ps, 
1978                            depth))
1979                 return False;
1980         if (!prs_uint16("country", ps, depth, &info->country))
1981                 return False;
1982         if (!prs_uint16("codepage", ps, depth, &info->codepage))
1983                 return False;
1984
1985         if (!smb_io_bufhdr2("hdr_priv_data", &hdr_priv_data, ps, depth))
1986                 return False;
1987         if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
1988                 return False;
1989         if (!smb_io_unihdr("hdr_profile", &info->hdr_profile, ps, depth))
1990                 return False;
1991
1992         for (i = 0; i < 3; i++)
1993         {
1994                 if (!smb_io_unihdr("hdr_reserved", &info->hdr_reserved[i], 
1995                                    ps, depth))
1996                         return False;                                          
1997         }
1998
1999         for (i = 0; i < 4; i++)
2000         {
2001                 if (!prs_uint32("dw_reserved", ps, depth, 
2002                                 &info->dw_reserved[i]))
2003                         return False;
2004         }
2005
2006         if (!smb_io_unistr2("uni_acct_name", &info->uni_acct_name,
2007                             info->hdr_acct_name.buffer, ps, depth))
2008                 return False;
2009         prs_align(ps);
2010         if (!smb_io_unistr2("uni_full_name", &info->uni_full_name,
2011                             info->hdr_full_name.buffer, ps, depth))
2012                 return False;
2013         prs_align(ps);
2014         if (!smb_io_unistr2("uni_home_dir ", &info->uni_home_dir,
2015                             info->hdr_home_dir.buffer, ps, depth))
2016                 return False;
2017         prs_align(ps);
2018         if (!smb_io_unistr2("uni_dir_drive", &info->uni_dir_drive,
2019                             info->hdr_dir_drive.buffer, ps, depth))
2020                 return False;
2021         prs_align(ps);
2022         if (!smb_io_unistr2("uni_logon_script", &info->uni_logon_script,
2023                             info->hdr_logon_script.buffer, ps, depth))
2024                 return False;
2025         prs_align(ps);
2026         if (!smb_io_unistr2("uni_acct_desc", &info->uni_acct_desc,
2027                             info->hdr_acct_desc.buffer, ps, depth))
2028                 return False;
2029         prs_align(ps);
2030         if (!smb_io_unistr2("uni_workstations", &info->uni_workstations,
2031                             info->hdr_workstations.buffer, ps, depth))
2032                 return False;
2033         prs_align(ps);
2034
2035         if (!prs_uint32("unknown1", ps, depth, &info->unknown1))
2036                 return False;
2037         if (!prs_uint32("unknown2", ps, depth, &info->unknown2))
2038                 return False;
2039
2040         if (!smb_io_buffer4("buf_logon_hrs", &info->buf_logon_hrs,
2041                             info->ptr_logon_hrs, ps, depth))
2042                 return False;
2043         prs_align(ps);
2044         if (!smb_io_unistr2("uni_comment", &info->uni_comment,
2045                             info->hdr_comment.buffer, ps, depth))
2046                 return False;
2047         prs_align(ps);
2048         if (!smb_io_unistr2("uni_parameters", &info->uni_parameters,
2049                             info->hdr_parameters.buffer, ps, depth))
2050                 return False;
2051         prs_align(ps);
2052         if (hdr_priv_data.buffer != 0)
2053         {
2054                 int old_offset = 0;
2055                 uint32 len = 0x44;
2056                 if (!prs_uint32("pwd_len", ps, depth, &len))
2057                         return False;
2058                 old_offset = ps->data_offset;
2059                 if (len == 0x44)
2060                 {
2061                         if (ps->io)
2062                         {
2063                                 /* reading */
2064 /* // FIXME                     prs_hash1(ps, ps->offset, sess_key); */
2065                         }
2066                         if (!net_io_sam_passwd_info("pass", &info->pass, 
2067                                                     ps, depth))
2068                                 return False;
2069
2070                         if (!ps->io)
2071                         {
2072                                 /* writing */
2073 /* // FIXME TOO                 prs_hash1(ps, old_offset, sess_key); */
2074                         }
2075                 }
2076                 if (old_offset + len > ps->buffer_size)
2077                         return False;
2078                 ps->data_offset = old_offset + len;
2079         }
2080         if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc,
2081                             info->hdr_sec_desc.buffer, ps, depth))
2082                 return False;
2083         prs_align(ps);
2084         if (!smb_io_unistr2("uni_profile", &info->uni_profile,
2085                             info->hdr_profile.buffer, ps, depth))
2086                 return False;
2087
2088         prs_align(ps);
2089
2090         return True;
2091 }
2092
2093 /*******************************************************************
2094 reads or writes a structure.
2095 ********************************************************************/
2096 static BOOL net_io_sam_group_mem_info(char *desc, SAM_GROUP_MEM_INFO * info,
2097                                       prs_struct *ps, int depth)
2098 {
2099         uint32 i;
2100         fstring tmp;
2101
2102         prs_debug(ps, depth, desc, "net_io_sam_group_mem_info");
2103         depth++;
2104
2105         prs_align(ps);
2106         if (!prs_uint32("ptr_rids   ", ps, depth, &info->ptr_rids))
2107                 return False;
2108         if (!prs_uint32("ptr_attribs", ps, depth, &info->ptr_attribs))
2109                 return False;
2110         if (!prs_uint32("num_members", ps, depth, &info->num_members))
2111                 return False;
2112
2113         if (ps->data_offset + 16 > ps->buffer_size)
2114                 return False;
2115         ps->data_offset += 16;
2116
2117         if (info->ptr_rids != 0)
2118         {
2119                 if (!prs_uint32("num_members2", ps, depth, 
2120                                 &info->num_members2))
2121                         return False;
2122
2123                 if (info->num_members2 != info->num_members)
2124                 {
2125                         /* RPC fault */
2126                         return False;
2127                 }
2128
2129                 info->rids = talloc(ps->mem_ctx, sizeof(uint32) *
2130                                     info->num_members2);
2131
2132                 if (info->rids == NULL) {
2133                         DEBUG(0, ("out of memory allocating %d rids\n",
2134                                   info->num_members2));
2135                         return False;
2136                 }
2137
2138                 for (i = 0; i < info->num_members2; i++)
2139                 {
2140                         slprintf(tmp, sizeof(tmp) - 1, "rids[%02d]", i);
2141                         if (!prs_uint32(tmp, ps, depth, &info->rids[i]))
2142                                 return False;
2143                 }
2144         }
2145
2146         if (info->ptr_attribs != 0)
2147         {
2148                 if (!prs_uint32("num_members3", ps, depth, 
2149                                 &info->num_members3))
2150                         return False;
2151                 if (info->num_members3 != info->num_members)
2152                 {
2153                         /* RPC fault */
2154                         return False;
2155                 }
2156
2157                 info->attribs = talloc(ps->mem_ctx, sizeof(uint32) *
2158                                        info->num_members3);
2159
2160                 if (info->attribs == NULL) {
2161                         DEBUG(0, ("out of memory allocating %d attribs\n",
2162                                   info->num_members3));
2163                         return False;
2164                 }
2165
2166                 for (i = 0; i < info->num_members3; i++)
2167                 {
2168                         slprintf(tmp, sizeof(tmp) - 1, "attribs[%02d]", i);
2169                         if (!prs_uint32(tmp, ps, depth, &info->attribs[i]))
2170                                 return False;
2171                 }
2172         }
2173
2174         return True;
2175 }
2176
2177 /*******************************************************************
2178 reads or writes a structure.
2179 ********************************************************************/
2180 static BOOL net_io_sam_alias_info(char *desc, SAM_ALIAS_INFO * info,
2181                                   prs_struct *ps, int depth)
2182 {
2183         prs_debug(ps, depth, desc, "net_io_sam_alias_info");
2184         depth++;
2185
2186         if (!smb_io_unihdr("hdr_als_name", &info->hdr_als_name, ps, depth))
2187                 return False;
2188         if (!prs_uint32("als_rid", ps, depth, &info->als_rid))
2189                 return False;
2190         if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
2191                 return False;
2192         if (!smb_io_unihdr("hdr_als_desc", &info->hdr_als_desc, ps, depth))
2193                 return False;
2194
2195         if (ps->data_offset + 40 > ps->buffer_size)
2196                 return False;
2197         ps->data_offset += 40;
2198
2199         if (!smb_io_unistr2("uni_als_name", &info->uni_als_name,
2200                             info->hdr_als_name.buffer, ps, depth))
2201                 return False;
2202         if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc,
2203                             info->hdr_sec_desc.buffer, ps, depth))
2204                 return False;
2205         if (!smb_io_unistr2("uni_als_desc", &info->uni_als_desc,
2206                             info->hdr_als_name.buffer, ps, depth))
2207                 return False;
2208
2209         return True;
2210 }
2211
2212 /*******************************************************************
2213 reads or writes a structure.
2214 ********************************************************************/
2215 static BOOL net_io_sam_alias_mem_info(char *desc, SAM_ALIAS_MEM_INFO * info,
2216                                       prs_struct *ps, int depth)
2217 {
2218         uint32 i;
2219         fstring tmp;
2220
2221         prs_debug(ps, depth, desc, "net_io_sam_alias_mem_info");
2222         depth++;
2223
2224         prs_align(ps);
2225         if (!prs_uint32("num_members", ps, depth, &info->num_members))
2226                 return False;
2227         if (!prs_uint32("ptr_members", ps, depth, &info->ptr_members))
2228                 return False;
2229
2230         if (info->ptr_members != 0)
2231         {
2232                 if (ps->data_offset + 16 > ps->buffer_size)
2233                         return False;
2234                 ps->data_offset += 16;
2235
2236                 if (!prs_uint32("num_sids", ps, depth, &info->num_sids))
2237                         return False;
2238                 if (info->num_sids != info->num_members)
2239                 {
2240                         /* RPC fault */
2241                         return False;
2242                 }
2243
2244                 info->ptr_sids = talloc(ps->mem_ctx, sizeof(uint32) *
2245                                         info->num_sids);
2246                 
2247                 if (info->ptr_sids == NULL) {
2248                         DEBUG(0, ("out of memory allocating %d ptr_sids\n",
2249                                   info->num_sids));
2250                         return False;
2251                 }
2252
2253                 for (i = 0; i < info->num_sids; i++)
2254                 {
2255                         slprintf(tmp, sizeof(tmp) - 1, "ptr_sids[%02d]", i);
2256                         if (!prs_uint32(tmp, ps, depth, &info->ptr_sids[i]))
2257                                 return False;
2258                 }
2259
2260                 info->sids = talloc(ps->mem_ctx, sizeof(DOM_SID2) *
2261                                     info->num_sids);
2262
2263                 if (info->sids == NULL) {
2264                         DEBUG(0, ("error allocating %d sids\n",
2265                                   info->num_sids));
2266                         return False;
2267                 }
2268
2269                 for (i = 0; i < info->num_sids; i++)
2270                 {
2271                         if (info->ptr_sids[i] != 0)
2272                         {
2273                                 slprintf(tmp, sizeof(tmp) - 1, "sids[%02d]",
2274                                          i);
2275                                 if (!smb_io_dom_sid2(tmp, &info->sids[i], 
2276                                                      ps, depth))
2277                                         return False;
2278                         }
2279                 }
2280         }
2281
2282         return True;
2283 }
2284
2285 /*******************************************************************
2286 reads or writes a structure.
2287 ********************************************************************/
2288 static BOOL net_io_sam_delta_ctr(char *desc, uint8 sess_key[16],
2289                                  SAM_DELTA_CTR * delta, uint16 type,
2290                                  prs_struct *ps, int depth)
2291 {
2292         prs_debug(ps, depth, desc, "net_io_sam_delta_ctr");
2293         depth++;
2294
2295         switch (type)
2296         {
2297                 /* Seen in sam deltas */
2298
2299                 case SAM_DELTA_SAM_STAMP:
2300                 {
2301                         if (!net_io_sam_delta_stamp("", &delta->stamp,
2302                                                     ps, depth))
2303                                 return False;
2304                         break;
2305                 }
2306
2307                 case SAM_DELTA_DOMAIN_INFO:
2308                 {
2309                         if (!net_io_sam_domain_info("", &delta->domain_info,
2310                                                     ps, depth))
2311                                 return False;
2312                         break;
2313                 }
2314                 case SAM_DELTA_GROUP_INFO:
2315                 {
2316                         if (!net_io_sam_group_info("", &delta->group_info,
2317                                                    ps, depth))
2318                                 return False;
2319                         break;
2320                 }
2321                 case SAM_DELTA_ACCOUNT_INFO:
2322                 {
2323                         if (!net_io_sam_account_info("", sess_key,
2324                                                      &delta->account_info,
2325                                                      ps, depth))
2326                                 return False;
2327                         break;
2328                 }
2329                 case SAM_DELTA_GROUP_MEM:
2330                 {
2331                         if (!net_io_sam_group_mem_info("", 
2332                                                        &delta->grp_mem_info,
2333                                                        ps, depth))
2334                                 return False;
2335                         break;
2336                 }
2337                 case SAM_DELTA_ALIAS_INFO:
2338                 {
2339                         if (!net_io_sam_alias_info("", &delta->alias_info,
2340                                                    ps, depth))
2341                                 return False;
2342                         break;
2343                 }
2344                 case SAM_DELTA_ALIAS_MEM:
2345                 {
2346                         if (!net_io_sam_alias_mem_info("", 
2347                                                        &delta->als_mem_info,
2348                                                        ps, depth))
2349                                 return False;
2350                         break;
2351                 }
2352                 default:
2353                 {
2354                         DEBUG(0,
2355                               ("Replication error: Unknown delta type 0x%x\n",
2356                                type));
2357                         break;
2358                 }
2359         }
2360
2361         return True;
2362 }
2363
2364 /*******************************************************************
2365 reads or writes a structure.
2366 ********************************************************************/
2367 BOOL net_io_r_sam_sync(char *desc, uint8 sess_key[16],
2368                        NET_R_SAM_SYNC * r_s, prs_struct *ps, int depth)
2369 {
2370         uint32 i;
2371
2372         prs_debug(ps, depth, desc, "net_io_r_sam_sync");
2373         depth++;
2374
2375         if (!smb_io_cred("srv_creds", &r_s->srv_creds, ps, depth))
2376                 return False;
2377         if (!prs_uint32("sync_context", ps, depth, &r_s->sync_context))
2378                 return False;
2379
2380         if (!prs_uint32("ptr_deltas", ps, depth, &r_s->ptr_deltas))
2381                 return False;
2382         if (r_s->ptr_deltas != 0)
2383         {
2384                 if (!prs_uint32("num_deltas ", ps, depth, &r_s->num_deltas))
2385                         return False;
2386                 if (!prs_uint32("ptr_deltas2", ps, depth, &r_s->ptr_deltas2))
2387                         return False;
2388                 if (r_s->ptr_deltas2 != 0)
2389                 {
2390                         if (!prs_uint32("num_deltas2", ps, depth,
2391                                         &r_s->num_deltas2))
2392                                 return False;
2393
2394                         if (r_s->num_deltas2 != r_s->num_deltas)
2395                         {
2396                                 /* RPC fault */
2397                                 return False;
2398                         }
2399
2400                         if (r_s->num_deltas2 > 0) {
2401                                 r_s->hdr_deltas = (SAM_DELTA_HDR *)
2402                                         talloc(ps->mem_ctx, r_s->num_deltas2 *
2403                                                sizeof(SAM_DELTA_HDR));
2404                           
2405                                 if (r_s->hdr_deltas == NULL) {
2406                                         DEBUG(0, ("error tallocating memory "
2407                                                   "for %d delta headers\n", 
2408                                                   r_s->num_deltas2));
2409                                         return False;
2410                                 }
2411                         }
2412
2413                         for (i = 0; i < r_s->num_deltas2; i++)
2414                         {
2415                                 if (!net_io_sam_delta_hdr("", 
2416                                                           &r_s->hdr_deltas[i],
2417                                                           ps, depth))
2418                                         return False;
2419                         }
2420
2421                         if (r_s->num_deltas2 > 0) {
2422                                 r_s->deltas = (SAM_DELTA_CTR *)
2423                                         talloc(ps->mem_ctx, r_s->num_deltas2 *
2424                                                sizeof(SAM_DELTA_CTR));
2425
2426                                 if (r_s->deltas == NULL) {
2427                                         DEBUG(0, ("error tallocating memory "
2428                                                   "for %d deltas\n", 
2429                                                   r_s->num_deltas2));
2430                                         return False;
2431                                 }
2432                         }
2433
2434                         for (i = 0; i < r_s->num_deltas2; i++)
2435                         {
2436                                 if (!net_io_sam_delta_ctr(
2437                                         "", sess_key, &r_s->deltas[i],
2438                                         r_s->hdr_deltas[i].type3,
2439                                         ps, depth)) {
2440                                         DEBUG(0, ("hmm, failed on i=%d\n", i));
2441                                         return False;
2442                                 }
2443                         }
2444                 }
2445         }
2446
2447         prs_align(ps);
2448         if (!prs_ntstatus("status", ps, depth, &(r_s->status)))
2449                 return False;
2450
2451         return True;
2452 }
2453
2454 /*******************************************************************
2455 makes a NET_Q_SAM_DELTAS structure.
2456 ********************************************************************/
2457 BOOL init_net_q_sam_deltas(NET_Q_SAM_DELTAS *q_s, const char *srv_name, 
2458                            const char *cli_name, DOM_CRED *cli_creds, 
2459                            uint32 database_id, UINT64_S dom_mod_count)
2460 {
2461         DEBUG(5, ("init_net_q_sam_deltas\n"));
2462
2463         init_unistr2(&q_s->uni_srv_name, srv_name, strlen(srv_name) + 1);
2464         init_unistr2(&q_s->uni_cli_name, cli_name, strlen(cli_name) + 1);
2465
2466         memcpy(&q_s->cli_creds, cli_creds, sizeof(q_s->cli_creds));
2467         memset(&q_s->ret_creds, 0, sizeof(q_s->ret_creds));
2468
2469         q_s->database_id = database_id;
2470         q_s->dom_mod_count.low = dom_mod_count.low;
2471         q_s->dom_mod_count.high = dom_mod_count.high;
2472         q_s->max_size = 0xffff;
2473
2474         return True;
2475 }
2476
2477 /*******************************************************************
2478 reads or writes a structure.
2479 ********************************************************************/
2480 BOOL net_io_q_sam_deltas(char *desc, NET_Q_SAM_DELTAS *q_s, prs_struct *ps,
2481                          int depth)
2482 {
2483         prs_debug(ps, depth, desc, "net_io_q_sam_deltas");
2484         depth++;
2485
2486         if (!smb_io_unistr2("", &q_s->uni_srv_name, True, ps, depth))
2487                 return False;
2488         if (!smb_io_unistr2("", &q_s->uni_cli_name, True, ps, depth))
2489                 return False;
2490
2491         if (!smb_io_cred("", &q_s->cli_creds, ps, depth))
2492                 return False;
2493         if (!smb_io_cred("", &q_s->ret_creds, ps, depth))
2494                 return False;
2495
2496         if (!prs_uint32("database_id  ", ps, depth, &q_s->database_id))
2497                 return False;
2498         if (!prs_uint64("dom_mod_count", ps, depth, &q_s->dom_mod_count))
2499                 return False;
2500         if (!prs_uint32("max_size", ps, depth, &q_s->max_size))
2501                 return False;
2502
2503         return True;
2504 }
2505
2506 /*******************************************************************
2507 reads or writes a structure.
2508 ********************************************************************/
2509 BOOL net_io_r_sam_deltas(char *desc, uint8 sess_key[16],
2510                          NET_R_SAM_DELTAS *r_s, prs_struct *ps, int depth)
2511 {
2512         int i;
2513
2514         prs_debug(ps, depth, desc, "net_io_r_sam_deltas");
2515         depth++;
2516
2517         if (!smb_io_cred("srv_creds", &r_s->srv_creds, ps, depth))
2518                 return False;
2519         if (!prs_uint64("dom_mod_count", ps, depth, &r_s->dom_mod_count))
2520                 return False;
2521
2522         if (!prs_uint32("ptr_deltas", ps, depth, &r_s->ptr_deltas))
2523                 return False;
2524         if (!prs_uint32("num_deltas", ps, depth, &r_s->num_deltas))
2525                 return False;
2526         if (!prs_uint32("ptr_deltas2", ps, depth, &r_s->num_deltas2))
2527                 return False;
2528
2529         if (r_s->num_deltas2 != 0)
2530         {
2531                 if (!prs_uint32("num_deltas2 ", ps, depth, &r_s->num_deltas2))
2532                         return False;
2533
2534                 if (r_s->ptr_deltas != 0)
2535                 {
2536                         if (r_s->num_deltas > 0) {
2537                                 r_s->hdr_deltas = (SAM_DELTA_HDR *)
2538                                         talloc(ps->mem_ctx, r_s->num_deltas *
2539                                                sizeof(SAM_DELTA_HDR));
2540                                 if (r_s->hdr_deltas == NULL) {
2541                                         DEBUG(0, ("error tallocating memory "
2542                                                   "for %d delta headers\n", 
2543                                                   r_s->num_deltas));
2544                                         return False;
2545                                 }
2546                         }
2547
2548                         for (i = 0; i < r_s->num_deltas; i++)
2549                         {
2550                                 net_io_sam_delta_hdr("", &r_s->hdr_deltas[i],
2551                                                       ps, depth);
2552                         }
2553                         
2554                         if (r_s->num_deltas > 0) {
2555                                 r_s->deltas = (SAM_DELTA_CTR *)
2556                                         talloc(ps->mem_ctx, r_s->num_deltas *
2557                                                sizeof(SAM_DELTA_CTR));
2558
2559                                 if (r_s->deltas == NULL) {
2560                                         DEBUG(0, ("error tallocating memory "
2561                                                   "for %d deltas\n", 
2562                                                   r_s->num_deltas));
2563                                         return False;
2564                                 }
2565                         }
2566
2567                         for (i = 0; i < r_s->num_deltas; i++)
2568                         {
2569                                 if (!net_io_sam_delta_ctr(
2570                                         "", sess_key,
2571                                         &r_s->deltas[i],
2572                                         r_s->hdr_deltas[i].type2,
2573                                         ps, depth))
2574                                         
2575                                         return False;
2576                         }
2577                 }
2578         }
2579
2580         prs_align(ps);
2581         if (!prs_ntstatus("status", ps, depth, &r_s->status))
2582                 return False;
2583
2584         return True;
2585 }