OK. Smbpasswd -j is DEAD.
[tprouty/samba.git] / source / rpc_parse / parse_net.c
1 /* 
2  *  Unix SMB/Netbios implementation.
3  *  Version 1.9.
4  *  RPC Pipe client / server routines
5  *  Copyright (C) Andrew Tridgell              1992-1997,
6  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
7  *  Copyright (C) Paul Ashton                       1997.
8  *  
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2 of the License, or
12  *  (at your option) any later version.
13  *  
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *  
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; if not, write to the Free Software
21  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22  */
23
24 #include "includes.h"
25
26 /*******************************************************************
27  Reads or writes a structure.
28 ********************************************************************/
29
30 static BOOL net_io_neg_flags(char *desc, NEG_FLAGS *neg, prs_struct *ps, int depth)
31 {
32         if (neg == NULL)
33                 return False;
34
35         prs_debug(ps, depth, desc, "net_io_neg_flags");
36         depth++;
37
38         if(!prs_align(ps))
39                 return False;
40         
41         if(!prs_uint32("neg_flags", ps, depth, &neg->neg_flags))
42                 return False;
43
44         return True;
45 }
46
47 /*******************************************************************
48  Inits a NETLOGON_INFO_3 structure.
49 ********************************************************************/
50
51 static void init_netinfo_3(NETLOGON_INFO_3 *info, uint32 flags, uint32 logon_attempts)
52 {
53         info->flags          = flags;
54         info->logon_attempts = logon_attempts;
55         info->reserved_1     = 0x0;
56         info->reserved_2     = 0x0;
57         info->reserved_3     = 0x0;
58         info->reserved_4     = 0x0;
59         info->reserved_5     = 0x0;
60 }
61
62 /*******************************************************************
63  Reads or writes a NETLOGON_INFO_3 structure.
64 ********************************************************************/
65
66 static BOOL net_io_netinfo_3(char *desc,  NETLOGON_INFO_3 *info, prs_struct *ps, int depth)
67 {
68         if (info == NULL)
69                 return False;
70
71         prs_debug(ps, depth, desc, "net_io_netinfo_3");
72         depth++;
73
74         if(!prs_align(ps))
75                 return False;
76
77         if(!prs_uint32("flags         ", ps, depth, &info->flags))
78                 return False;
79         if(!prs_uint32("logon_attempts", ps, depth, &info->logon_attempts))
80                 return False;
81         if(!prs_uint32("reserved_1    ", ps, depth, &info->reserved_1))
82                 return False;
83         if(!prs_uint32("reserved_2    ", ps, depth, &info->reserved_2))
84                 return False;
85         if(!prs_uint32("reserved_3    ", ps, depth, &info->reserved_3))
86                 return False;
87         if(!prs_uint32("reserved_4    ", ps, depth, &info->reserved_4))
88                 return False;
89         if(!prs_uint32("reserved_5    ", ps, depth, &info->reserved_5))
90                 return False;
91
92         return True;
93 }
94
95
96 /*******************************************************************
97  Inits a NETLOGON_INFO_1 structure.
98 ********************************************************************/
99
100 static void init_netinfo_1(NETLOGON_INFO_1 *info, uint32 flags, uint32 pdc_status)
101 {
102         info->flags      = flags;
103         info->pdc_status = pdc_status;
104 }
105
106 /*******************************************************************
107  Reads or writes a NETLOGON_INFO_1 structure.
108 ********************************************************************/
109
110 static BOOL net_io_netinfo_1(char *desc, NETLOGON_INFO_1 *info, prs_struct *ps, int depth)
111 {
112         if (info == NULL)
113                 return False;
114
115         prs_debug(ps, depth, desc, "net_io_netinfo_1");
116         depth++;
117
118         if(!prs_align(ps))
119                 return False;
120         
121         if(!prs_uint32("flags     ", ps, depth, &info->flags))
122                 return False;
123         if(!prs_uint32("pdc_status", ps, depth, &info->pdc_status))
124                 return False;
125
126         return True;
127 }
128
129 /*******************************************************************
130  Inits a NETLOGON_INFO_2 structure.
131 ********************************************************************/
132
133 static void init_netinfo_2(NETLOGON_INFO_2 *info, uint32 flags, uint32 pdc_status,
134                                 uint32 tc_status, char *trusted_dc_name)
135 {
136         int len_dc_name = strlen(trusted_dc_name);
137         info->flags      = flags;
138         info->pdc_status = pdc_status;
139         info->ptr_trusted_dc_name = 1;
140         info->tc_status  = tc_status;
141
142         if (trusted_dc_name != NULL)
143                 init_unistr2(&info->uni_trusted_dc_name, trusted_dc_name, len_dc_name+1);
144         else
145                 init_unistr2(&info->uni_trusted_dc_name, "", 1);
146 }
147
148 /*******************************************************************
149  Reads or writes a NETLOGON_INFO_2 structure.
150 ********************************************************************/
151
152 static BOOL net_io_netinfo_2(char *desc, NETLOGON_INFO_2 *info, prs_struct *ps, int depth)
153 {
154         if (info == NULL)
155                 return False;
156
157         prs_debug(ps, depth, desc, "net_io_netinfo_2");
158         depth++;
159
160         if(!prs_align(ps))
161                 return False;
162         
163         if(!prs_uint32("flags              ", ps, depth, &info->flags))
164                 return False;
165         if(!prs_uint32("pdc_status         ", ps, depth, &info->pdc_status))
166                 return False;
167         if(!prs_uint32("ptr_trusted_dc_name", ps, depth, &info->ptr_trusted_dc_name))
168                 return False;
169         if(!prs_uint32("tc_status          ", ps, depth, &info->tc_status))
170                 return False;
171
172         if (info->ptr_trusted_dc_name != 0) {
173                 if(!smb_io_unistr2("unistr2", &info->uni_trusted_dc_name, info->ptr_trusted_dc_name, ps, depth))
174                         return False;
175         }
176
177         if(!prs_align(ps))
178                 return False;
179
180         return True;
181 }
182
183 /*******************************************************************
184  Reads or writes an NET_Q_LOGON_CTRL2 structure.
185 ********************************************************************/
186
187 BOOL net_io_q_logon_ctrl2(char *desc, NET_Q_LOGON_CTRL2 *q_l, prs_struct *ps, int depth)
188 {
189         if (q_l == NULL)
190                 return False;
191
192         prs_debug(ps, depth, desc, "net_io_q_logon_ctrl2");
193         depth++;
194
195         if(!prs_align(ps))
196                 return False;
197
198         if(!prs_uint32("ptr          ", ps, depth, &q_l->ptr))
199                 return False;
200
201         if(!smb_io_unistr2 ("", &q_l->uni_server_name, q_l->ptr, ps, depth))
202                 return False;
203
204         if(!prs_align(ps))
205                 return False;
206
207         if(!prs_uint32("function_code", ps, depth, &q_l->function_code))
208                 return False;
209         if(!prs_uint32("query_level  ", ps, depth, &q_l->query_level))
210                 return False;
211         if(!prs_uint32("switch_value ", ps, depth, &q_l->switch_value))
212                 return False;
213
214         return True;
215 }
216
217 /*******************************************************************
218  Inits an NET_Q_LOGON_CTRL2 structure.
219 ********************************************************************/
220
221 void init_net_q_logon_ctrl2(NET_Q_LOGON_CTRL2 *q_l, char *srv_name,
222                             uint32 query_level)
223 {
224         DEBUG(5,("init_q_logon_ctrl2\n"));
225
226         q_l->function_code = 0x01;
227         q_l->query_level = query_level;
228         q_l->switch_value  = 0x01;
229
230         init_unistr2(&q_l->uni_server_name, srv_name, strlen(srv_name) + 1);
231 }
232
233 /*******************************************************************
234  Inits an NET_R_LOGON_CTRL2 structure.
235 ********************************************************************/
236
237 void init_net_r_logon_ctrl2(NET_R_LOGON_CTRL2 *r_l, uint32 query_level,
238                             uint32 flags, uint32 pdc_status, 
239                             uint32 logon_attempts, uint32 tc_status, 
240                             char *trusted_domain_name)
241 {
242         DEBUG(5,("init_r_logon_ctrl2\n"));
243
244         r_l->switch_value  = query_level; /* should only be 0x1 */
245
246         switch (query_level) {
247         case 1:
248                 r_l->ptr = 1; /* undocumented pointer */
249                 init_netinfo_1(&r_l->logon.info1, flags, pdc_status);   
250                 r_l->status = NT_STATUS_OK;
251                 break;
252         case 2:
253                 r_l->ptr = 1; /* undocumented pointer */
254                 init_netinfo_2(&r_l->logon.info2, flags, pdc_status,
255                                tc_status, trusted_domain_name); 
256                 r_l->status = NT_STATUS_OK;
257                 break;
258         case 3:
259                 r_l->ptr = 1; /* undocumented pointer */
260                 init_netinfo_3(&r_l->logon.info3, flags, logon_attempts);       
261                 r_l->status = NT_STATUS_OK;
262                 break;
263         default:
264                 DEBUG(2,("init_r_logon_ctrl2: unsupported switch value %d\n",
265                         r_l->switch_value));
266                 r_l->ptr = 0; /* undocumented pointer */
267
268                 /* take a guess at an error code... */
269                 r_l->status = NT_STATUS_INVALID_INFO_CLASS;
270                 break;
271         }
272 }
273
274 /*******************************************************************
275  Reads or writes an NET_R_LOGON_CTRL2 structure.
276 ********************************************************************/
277
278 BOOL net_io_r_logon_ctrl2(char *desc, NET_R_LOGON_CTRL2 *r_l, prs_struct *ps, int depth)
279 {
280         if (r_l == NULL)
281                 return False;
282
283         prs_debug(ps, depth, desc, "net_io_r_logon_ctrl2");
284         depth++;
285
286         if(!prs_uint32("switch_value ", ps, depth, &r_l->switch_value))
287                 return False;
288         if(!prs_uint32("ptr          ", ps, depth, &r_l->ptr))
289                 return False;
290
291         if (r_l->ptr != 0) {
292                 switch (r_l->switch_value) {
293                 case 1:
294                         if(!net_io_netinfo_1("", &r_l->logon.info1, ps, depth))
295                                 return False;
296                         break;
297                 case 2:
298                         if(!net_io_netinfo_2("", &r_l->logon.info2, ps, depth))
299                                 return False;
300                         break;
301                 case 3:
302                         if(!net_io_netinfo_3("", &r_l->logon.info3, ps, depth))
303                                 return False;
304                         break;
305                 default:
306                         DEBUG(2,("net_io_r_logon_ctrl2: unsupported switch value %d\n",
307                                 r_l->switch_value));
308                         break;
309                 }
310         }
311
312         if(!prs_ntstatus("status       ", ps, depth, &r_l->status))
313                 return False;
314
315         return True;
316 }
317
318 /*******************************************************************
319  Reads or writes an NET_Q_LOGON_CTRL structure.
320 ********************************************************************/
321
322 BOOL net_io_q_logon_ctrl(char *desc, NET_Q_LOGON_CTRL *q_l, prs_struct *ps, 
323                          int depth)
324 {
325         prs_debug(ps, depth, desc, "net_io_q_logon_ctrl");
326         depth++;
327
328         if(!prs_align(ps))
329                 return False;
330
331         if(!prs_uint32("ptr          ", ps, depth, &q_l->ptr))
332                 return False;
333
334         if(!smb_io_unistr2 ("", &q_l->uni_server_name, q_l->ptr, ps, depth))
335                 return False;
336
337         if(!prs_align(ps))
338                 return False;
339
340         if(!prs_uint32("function_code", ps, depth, &q_l->function_code))
341                 return False;
342         if(!prs_uint32("query_level  ", ps, depth, &q_l->query_level))
343                 return False;
344
345         return True;
346 }
347
348 /*******************************************************************
349  Inits an NET_Q_LOGON_CTRL structure.
350 ********************************************************************/
351
352 void init_net_q_logon_ctrl(NET_Q_LOGON_CTRL *q_l, char *srv_name,
353                            uint32 query_level)
354 {
355         DEBUG(5,("init_q_logon_ctrl\n"));
356
357         q_l->function_code = 0x01; /* ??? */
358         q_l->query_level = query_level;
359
360         init_unistr2(&q_l->uni_server_name, srv_name, strlen(srv_name) + 1);
361 }
362
363 /*******************************************************************
364  Inits an NET_R_LOGON_CTRL structure.
365 ********************************************************************/
366
367 void init_net_r_logon_ctrl(NET_R_LOGON_CTRL *r_l, uint32 query_level,
368                            uint32 flags, uint32 pdc_status)
369 {
370         DEBUG(5,("init_r_logon_ctrl\n"));
371
372         r_l->switch_value  = query_level; /* should only be 0x1 */
373
374         switch (query_level) {
375         case 1:
376                 r_l->ptr = 1; /* undocumented pointer */
377                 init_netinfo_1(&r_l->logon.info1, flags, pdc_status);   
378                 r_l->status = NT_STATUS_OK;
379                 break;
380         default:
381                 DEBUG(2,("init_r_logon_ctrl: unsupported switch value %d\n",
382                         r_l->switch_value));
383                 r_l->ptr = 0; /* undocumented pointer */
384
385                 /* take a guess at an error code... */
386                 r_l->status = NT_STATUS_INVALID_INFO_CLASS;
387                 break;
388         }
389 }
390
391 /*******************************************************************
392  Reads or writes an NET_R_LOGON_CTRL structure.
393 ********************************************************************/
394
395 BOOL net_io_r_logon_ctrl(char *desc, NET_R_LOGON_CTRL *r_l, prs_struct *ps, 
396                          int depth)
397 {
398         prs_debug(ps, depth, desc, "net_io_r_logon_ctrl");
399         depth++;
400
401         if(!prs_uint32("switch_value ", ps, depth, &r_l->switch_value))
402                 return False;
403         if(!prs_uint32("ptr          ", ps, depth, &r_l->ptr))
404                 return False;
405
406         if (r_l->ptr != 0) {
407                 switch (r_l->switch_value) {
408                 case 1:
409                         if(!net_io_netinfo_1("", &r_l->logon.info1, ps, depth))
410                                 return False;
411                         break;
412                 default:
413                         DEBUG(2,("net_io_r_logon_ctrl: unsupported switch value %d\n",
414                                 r_l->switch_value));
415                         break;
416                 }
417         }
418
419         if(!prs_ntstatus("status       ", ps, depth, &r_l->status))
420                 return False;
421
422         return True;
423 }
424
425 /*******************************************************************
426  Inits an NET_R_TRUST_DOM_LIST structure.
427 ********************************************************************/
428
429 void init_r_trust_dom(NET_R_TRUST_DOM_LIST *r_t,
430                         uint32 num_doms, char *dom_name)
431 {
432         int i = 0;
433
434         DEBUG(5,("init_r_trust_dom\n"));
435
436         for (i = 0; i < MAX_TRUST_DOMS; i++) {
437                 r_t->uni_trust_dom_name[i].uni_str_len = 0;
438                 r_t->uni_trust_dom_name[i].uni_max_len = 0;
439         }
440         if (num_doms > MAX_TRUST_DOMS)
441                 num_doms = MAX_TRUST_DOMS;
442
443         for (i = 0; i < num_doms; i++) {
444                 fstring domain_name;
445                 fstrcpy(domain_name, dom_name);
446                 strupper(domain_name);
447                 init_unistr2(&r_t->uni_trust_dom_name[i], domain_name, strlen(domain_name)+1);
448                 /* the use of UNISTR2 here is non-standard. */
449                 r_t->uni_trust_dom_name[i].undoc = 0x1;
450         }
451         
452         r_t->status = NT_STATUS_OK;
453 }
454
455 /*******************************************************************
456  Reads or writes an NET_R_TRUST_DOM_LIST structure.
457 ********************************************************************/
458
459 BOOL net_io_r_trust_dom(char *desc, NET_R_TRUST_DOM_LIST *r_t, prs_struct *ps, int depth)
460 {
461         uint32 value;
462
463         if (r_t == NULL)
464                  return False;
465
466         prs_debug(ps, depth, desc, "net_io_r_trust_dom");
467         depth++;
468
469         /* temporary code to give a valid response */
470         value=2;
471         if(!prs_uint32("status", ps, depth, &value))
472                  return False;
473
474         value=1;
475         if(!prs_uint32("status", ps, depth, &value))
476                  return False;
477         value=2;
478         if(!prs_uint32("status", ps, depth, &value))
479                  return False;
480
481         value=0;
482         if(!prs_uint32("status", ps, depth, &value))
483                  return False;
484
485         value=0;
486         if(!prs_uint32("status", ps, depth, &value))
487                  return False;
488
489 /* old non working code */
490 #if 0
491         int i;
492
493         for (i = 0; i < MAX_TRUST_DOMS; i++) {
494                 if (r_t->uni_trust_dom_name[i].uni_str_len == 0)
495                         break;
496                 if(!smb_io_unistr2("", &r_t->uni_trust_dom_name[i], True, ps, depth))
497                          return False;
498         }
499
500         if(!prs_ntstatus("status", ps, depth, &r_t->status))
501                  return False;
502 #endif
503         return True;
504 }
505
506
507 /*******************************************************************
508  Reads or writes an NET_Q_TRUST_DOM_LIST structure.
509 ********************************************************************/
510
511 BOOL net_io_q_trust_dom(char *desc, NET_Q_TRUST_DOM_LIST *q_l, prs_struct *ps, int depth)
512 {
513         if (q_l == NULL)
514                  return False;
515
516         prs_debug(ps, depth, desc, "net_io_q_trust_dom");
517         depth++;
518
519         if(!prs_uint32("ptr          ", ps, depth, &q_l->ptr))
520                  return False;
521         if(!smb_io_unistr2 ("", &q_l->uni_server_name, q_l->ptr, ps, depth))
522                  return False;
523
524         return True;
525 }
526
527 /*******************************************************************
528  Inits an NET_Q_REQ_CHAL structure.
529 ********************************************************************/
530
531 void init_q_req_chal(NET_Q_REQ_CHAL *q_c,
532                                 char *logon_srv, char *logon_clnt,
533                                 DOM_CHAL *clnt_chal)
534 {
535         DEBUG(5,("init_q_req_chal: %d\n", __LINE__));
536
537         q_c->undoc_buffer = 1; /* don't know what this buffer is */
538
539         init_unistr2(&q_c->uni_logon_srv, logon_srv , strlen(logon_srv )+1);
540         init_unistr2(&q_c->uni_logon_clnt, logon_clnt, strlen(logon_clnt)+1);
541
542         memcpy(q_c->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data));
543
544         DEBUG(5,("init_q_req_chal: %d\n", __LINE__));
545 }
546
547 /*******************************************************************
548  Reads or writes an NET_Q_REQ_CHAL structure.
549 ********************************************************************/
550
551 BOOL net_io_q_req_chal(char *desc,  NET_Q_REQ_CHAL *q_c, prs_struct *ps, int depth)
552 {
553         int old_align;
554
555         if (q_c == NULL)
556                 return False;
557
558         prs_debug(ps, depth, desc, "net_io_q_req_chal");
559         depth++;
560
561         if(!prs_align(ps))
562                 return False;
563     
564         if(!prs_uint32("undoc_buffer", ps, depth, &q_c->undoc_buffer))
565                 return False;
566
567         if(!smb_io_unistr2("", &q_c->uni_logon_srv, True, ps, depth)) /* logon server unicode string */
568                 return False;
569         if(!smb_io_unistr2("", &q_c->uni_logon_clnt, True, ps, depth)) /* logon client unicode string */
570                 return False;
571
572         old_align = ps->align;
573         ps->align = 0;
574         /* client challenge is _not_ aligned after the unicode strings */
575         if(!smb_io_chal("", &q_c->clnt_chal, ps, depth)) {
576                 /* client challenge */
577                 ps->align = old_align;
578                 return False;
579         }
580         ps->align = old_align;
581
582         return True;
583 }
584
585 /*******************************************************************
586  Reads or writes a structure.
587 ********************************************************************/
588
589 BOOL net_io_r_req_chal(char *desc, NET_R_REQ_CHAL *r_c, prs_struct *ps, int depth)
590 {
591         if (r_c == NULL)
592                 return False;
593
594         prs_debug(ps, depth, desc, "net_io_r_req_chal");
595         depth++;
596
597         if(!prs_align(ps))
598                 return False;
599     
600         if(!smb_io_chal("", &r_c->srv_chal, ps, depth)) /* server challenge */
601                 return False;
602
603         if(!prs_ntstatus("status", ps, depth, &r_c->status))
604                 return False;
605
606         return True;
607 }
608
609
610 /*******************************************************************
611  Reads or writes a structure.
612 ********************************************************************/
613
614 BOOL net_io_q_auth(char *desc, NET_Q_AUTH *q_a, prs_struct *ps, int depth)
615 {
616         int old_align;
617         if (q_a == NULL)
618                 return False;
619
620         prs_debug(ps, depth, desc, "net_io_q_auth");
621         depth++;
622
623         if(!prs_align(ps))
624                 return False;
625     
626         if(!smb_io_log_info ("", &q_a->clnt_id, ps, depth)) /* client identification info */
627                 return False;
628         /* client challenge is _not_ aligned */
629         old_align = ps->align;
630         ps->align = 0;
631         if(!smb_io_chal("", &q_a->clnt_chal, ps, depth)) {
632                 /* client-calculated credentials */
633                 ps->align = old_align;
634                 return False;
635         }
636         ps->align = old_align;
637
638         return True;
639 }
640
641 /*******************************************************************
642  Reads or writes a structure.
643 ********************************************************************/
644
645 BOOL net_io_r_auth(char *desc, NET_R_AUTH *r_a, prs_struct *ps, int depth)
646 {
647         if (r_a == NULL)
648                 return False;
649
650         prs_debug(ps, depth, desc, "net_io_r_auth");
651         depth++;
652
653         if(!prs_align(ps))
654                 return False;
655     
656         if(!smb_io_chal("", &r_a->srv_chal, ps, depth)) /* server challenge */
657                 return False;
658
659         if(!prs_ntstatus("status", ps, depth, &r_a->status))
660                 return False;
661
662         return True;
663 }
664
665 /*******************************************************************
666  Inits a NET_Q_AUTH_2 struct.
667 ********************************************************************/
668
669 void init_q_auth_2(NET_Q_AUTH_2 *q_a,
670                 char *logon_srv, char *acct_name, uint16 sec_chan, char *comp_name,
671                 DOM_CHAL *clnt_chal, uint32 clnt_flgs)
672 {
673         DEBUG(5,("init_q_auth_2: %d\n", __LINE__));
674
675         init_log_info(&q_a->clnt_id, logon_srv, acct_name, sec_chan, comp_name);
676         memcpy(q_a->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data));
677         q_a->clnt_flgs.neg_flags = clnt_flgs;
678
679         DEBUG(5,("init_q_auth_2: %d\n", __LINE__));
680 }
681
682 /*******************************************************************
683  Reads or writes a structure.
684 ********************************************************************/
685
686 BOOL net_io_q_auth_2(char *desc, NET_Q_AUTH_2 *q_a, prs_struct *ps, int depth)
687 {
688         int old_align;
689         if (q_a == NULL)
690                 return False;
691
692         prs_debug(ps, depth, desc, "net_io_q_auth_2");
693         depth++;
694
695         if(!prs_align(ps))
696                 return False;
697     
698         if(!smb_io_log_info ("", &q_a->clnt_id, ps, depth)) /* client identification info */
699                 return False;
700         /* client challenge is _not_ aligned */
701         old_align = ps->align;
702         ps->align = 0;
703         if(!smb_io_chal("", &q_a->clnt_chal, ps, depth)) {
704                 /* client-calculated credentials */
705                 ps->align = old_align;
706                 return False;
707         }
708         ps->align = old_align;
709         if(!net_io_neg_flags("", &q_a->clnt_flgs, ps, depth))
710                 return False;
711
712         return True;
713 }
714
715 /*******************************************************************
716  Reads or writes a structure.
717 ********************************************************************/
718
719 BOOL net_io_r_auth_2(char *desc, NET_R_AUTH_2 *r_a, prs_struct *ps, int depth)
720 {
721         if (r_a == NULL)
722                 return False;
723
724         prs_debug(ps, depth, desc, "net_io_r_auth_2");
725         depth++;
726
727         if(!prs_align(ps))
728                 return False;
729     
730         if(!smb_io_chal("", &r_a->srv_chal, ps, depth)) /* server challenge */
731                 return False;
732         if(!net_io_neg_flags("", &r_a->srv_flgs, ps, depth))
733                 return False;
734
735         if(!prs_ntstatus("status", ps, depth, &r_a->status))
736                 return False;
737
738         return True;
739 }
740
741
742 /*******************************************************************
743  Inits a NET_Q_SRV_PWSET.
744 ********************************************************************/
745
746 void init_q_srv_pwset(NET_Q_SRV_PWSET *q_s, char *logon_srv, char *sess_key, char *acct_name, 
747                 uint16 sec_chan, char *comp_name, DOM_CRED *cred, char hashed_mach_pwd[16])
748 {
749         unsigned char nt_cypher[16];
750         
751         DEBUG(5,("init_q_srv_pwset\n"));
752         
753         /* Process the new password. */
754         cred_hash3( nt_cypher, hashed_mach_pwd, sess_key, 1);
755
756         init_clnt_info(&q_s->clnt_id, logon_srv, acct_name, sec_chan, comp_name, cred);
757
758         memcpy(q_s->pwd, nt_cypher, sizeof(q_s->pwd)); 
759 }
760
761 /*******************************************************************
762  Reads or writes a structure.
763 ********************************************************************/
764
765 BOOL net_io_q_srv_pwset(char *desc, NET_Q_SRV_PWSET *q_s, prs_struct *ps, int depth)
766 {
767         if (q_s == NULL)
768                 return False;
769
770         prs_debug(ps, depth, desc, "net_io_q_srv_pwset");
771         depth++;
772
773         if(!prs_align(ps))
774                 return False;
775     
776         if(!smb_io_clnt_info("", &q_s->clnt_id, ps, depth)) /* client identification/authentication info */
777                 return False;
778         if(!prs_uint8s (False, "pwd", ps, depth, q_s->pwd, 16)) /* new password - undocumented */
779                 return False;
780
781         return True;
782 }
783
784 /*******************************************************************
785  Reads or writes a structure.
786 ********************************************************************/
787
788 BOOL net_io_r_srv_pwset(char *desc, NET_R_SRV_PWSET *r_s, prs_struct *ps, int depth)
789 {
790         if (r_s == NULL)
791                 return False;
792
793         prs_debug(ps, depth, desc, "net_io_r_srv_pwset");
794         depth++;
795
796         if(!prs_align(ps))
797                 return False;
798     
799         if(!smb_io_cred("", &r_s->srv_cred, ps, depth)) /* server challenge */
800                 return False;
801
802         if(!prs_ntstatus("status", ps, depth, &r_s->status))
803                 return False;
804
805         return True;
806 }
807
808 /*************************************************************************
809  Init DOM_SID2 array from a string containing multiple sids
810  *************************************************************************/
811
812 static int init_dom_sid2s(TALLOC_CTX *ctx, char *sids_str, DOM_SID2 **ppsids)
813 {
814         char *ptr;
815         pstring s2;
816         int count = 0;
817
818         DEBUG(4,("init_dom_sid2s: %s\n", sids_str ? sids_str:""));
819
820         *ppsids = NULL;
821
822         if(sids_str) {
823                 int number;
824                 DOM_SID2 *sids;
825
826                 /* Count the number of SIDs. */
827                 for (count = 0, ptr = sids_str; 
828                   next_token(&ptr, s2, NULL, sizeof(s2)); count++)
829                         ;
830
831                 /* Now allocate space for them. */
832                 *ppsids = (DOM_SID2 *)talloc_zero(ctx, count * sizeof(DOM_SID2));
833                 if (*ppsids == NULL)
834                         return 0;
835
836                 sids = *ppsids;
837
838                 for (number = 0, ptr = sids_str; 
839                   next_token(&ptr, s2, NULL, sizeof(s2)); number++) {
840                         DOM_SID tmpsid;
841                         string_to_sid(&tmpsid, s2);
842                         init_dom_sid2(&sids[number], &tmpsid);
843                 }
844         }
845
846         return count;
847 }
848
849 /*******************************************************************
850  Inits a NET_ID_INFO_1 structure.
851 ********************************************************************/
852
853 void init_id_info1(NET_ID_INFO_1 *id, char *domain_name,
854                                 uint32 param_ctrl, uint32 log_id_low, uint32 log_id_high,
855                                 char *user_name, char *wksta_name,
856                                 char *sess_key,
857                                 unsigned char lm_cypher[16], unsigned char nt_cypher[16])
858 {
859         int len_domain_name = strlen(domain_name);
860         int len_user_name   = strlen(user_name  );
861         int len_wksta_name  = strlen(wksta_name );
862
863         unsigned char lm_owf[16];
864         unsigned char nt_owf[16];
865
866         DEBUG(5,("init_id_info1: %d\n", __LINE__));
867
868         id->ptr_id_info1 = 1;
869
870         init_uni_hdr(&id->hdr_domain_name, len_domain_name);
871
872         id->param_ctrl = param_ctrl;
873         init_logon_id(&id->logon_id, log_id_low, log_id_high);
874
875         init_uni_hdr(&id->hdr_user_name, len_user_name);
876         init_uni_hdr(&id->hdr_wksta_name, len_wksta_name);
877
878         if (lm_cypher && nt_cypher) {
879                 unsigned char key[16];
880 #ifdef DEBUG_PASSWORD
881                 DEBUG(100,("lm cypher:"));
882                 dump_data(100, (char *)lm_cypher, 16);
883
884                 DEBUG(100,("nt cypher:"));
885                 dump_data(100, (char *)nt_cypher, 16);
886 #endif
887
888                 memset(key, 0, 16);
889                 memcpy(key, sess_key, 8);
890
891                 memcpy(lm_owf, lm_cypher, 16);
892                 SamOEMhash(lm_owf, key, 16);
893                 memcpy(nt_owf, nt_cypher, 16);
894                 SamOEMhash(nt_owf, key, 16);
895
896 #ifdef DEBUG_PASSWORD
897                 DEBUG(100,("encrypt of lm owf password:"));
898                 dump_data(100, (char *)lm_owf, 16);
899
900                 DEBUG(100,("encrypt of nt owf password:"));
901                 dump_data(100, (char *)nt_owf, 16);
902 #endif
903                 /* set up pointers to cypher blocks */
904                 lm_cypher = lm_owf;
905                 nt_cypher = nt_owf;
906         }
907
908         init_owf_info(&id->lm_owf, lm_cypher);
909         init_owf_info(&id->nt_owf, nt_cypher);
910
911         init_unistr2(&id->uni_domain_name, domain_name, len_domain_name);
912         init_unistr2(&id->uni_user_name, user_name, len_user_name);
913         init_unistr2(&id->uni_wksta_name, wksta_name, len_wksta_name);
914 }
915
916 /*******************************************************************
917  Reads or writes an NET_ID_INFO_1 structure.
918 ********************************************************************/
919
920 static BOOL net_io_id_info1(char *desc,  NET_ID_INFO_1 *id, prs_struct *ps, int depth)
921 {
922         if (id == NULL)
923                 return False;
924
925         prs_debug(ps, depth, desc, "net_io_id_info1");
926         depth++;
927
928         if(!prs_align(ps))
929                 return False;
930         
931         if(!prs_uint32("ptr_id_info1", ps, depth, &id->ptr_id_info1))
932                 return False;
933
934         if (id->ptr_id_info1 != 0) {
935                 if(!smb_io_unihdr("unihdr", &id->hdr_domain_name, ps, depth))
936                         return False;
937
938                 if(!prs_uint32("param_ctrl", ps, depth, &id->param_ctrl))
939                         return False;
940                 if(!smb_io_logon_id("", &id->logon_id, ps, depth))
941                         return False;
942
943                 if(!smb_io_unihdr("unihdr", &id->hdr_user_name, ps, depth))
944                         return False;
945                 if(!smb_io_unihdr("unihdr", &id->hdr_wksta_name, ps, depth))
946                         return False;
947
948                 if(!smb_io_owf_info("", &id->lm_owf, ps, depth))
949                         return False;
950                 if(!smb_io_owf_info("", &id->nt_owf, ps, depth))
951                         return False;
952
953                 if(!smb_io_unistr2("unistr2", &id->uni_domain_name,
954                                 id->hdr_domain_name.buffer, ps, depth))
955                         return False;
956                 if(!smb_io_unistr2("unistr2", &id->uni_user_name,
957                                 id->hdr_user_name.buffer, ps, depth))
958                         return False;
959                 if(!smb_io_unistr2("unistr2", &id->uni_wksta_name,
960                                 id->hdr_wksta_name.buffer, ps, depth))
961                         return False;
962         }
963
964         return True;
965 }
966
967 /*******************************************************************
968 Inits a NET_ID_INFO_2 structure.
969
970 This is a network logon packet. The log_id parameters
971 are what an NT server would generate for LUID once the
972 user is logged on. I don't think we care about them.
973
974 Note that this has no access to the NT and LM hashed passwords,
975 so it forwards the challenge, and the NT and LM responses (24
976 bytes each) over the secure channel to the Domain controller
977 for it to say yea or nay. This is the preferred method of 
978 checking for a logon as it doesn't export the password
979 hashes to anyone who has compromised the secure channel. JRA.
980 ********************************************************************/
981
982 void init_id_info2(NET_ID_INFO_2 * id, const char *domain_name,
983                    uint32 param_ctrl,
984                    uint32 log_id_low, uint32 log_id_high,
985                    const char *user_name, const char *wksta_name,
986                    const uchar lm_challenge[8],
987                    const uchar * lm_chal_resp, int lm_chal_resp_len,
988                    const uchar * nt_chal_resp, int nt_chal_resp_len)
989 {
990         int len_domain_name = strlen(domain_name);
991         int len_user_name   = strlen(user_name  );
992         int len_wksta_name  = strlen(wksta_name );
993         unsigned char lm_owf[24];
994         unsigned char nt_owf[128];
995
996         DEBUG(5,("init_id_info2: %d\n", __LINE__));
997
998         id->ptr_id_info2 = 1;
999
1000         init_uni_hdr(&id->hdr_domain_name, len_domain_name);
1001
1002         id->param_ctrl = param_ctrl;
1003         init_logon_id(&id->logon_id, log_id_low, log_id_high);
1004
1005         init_uni_hdr(&id->hdr_user_name, len_user_name);
1006         init_uni_hdr(&id->hdr_wksta_name, len_wksta_name);
1007
1008         if (nt_chal_resp) {
1009                 /* oops.  can only send what-ever-it-is direct */
1010                 memcpy(nt_owf, nt_chal_resp, MIN(sizeof(nt_owf), nt_chal_resp_len));
1011                 nt_chal_resp = nt_owf;
1012         }
1013         if (lm_chal_resp) {
1014                 /* oops.  can only send what-ever-it-is direct */
1015                 memcpy(lm_owf, lm_chal_resp, MIN(sizeof(lm_owf), lm_chal_resp_len));
1016                 lm_chal_resp = lm_owf;
1017         }
1018
1019         memcpy(id->lm_chal, lm_challenge, sizeof(id->lm_chal));
1020         init_str_hdr(&id->hdr_nt_chal_resp, nt_chal_resp_len, nt_chal_resp_len, (nt_chal_resp != NULL) ? 1 : 0);
1021         init_str_hdr(&id->hdr_lm_chal_resp, lm_chal_resp_len, lm_chal_resp_len, (lm_chal_resp != NULL) ? 1 : 0);
1022
1023         init_unistr2(&id->uni_domain_name, domain_name, len_domain_name);
1024         init_unistr2(&id->uni_user_name, user_name, len_user_name);
1025         init_unistr2(&id->uni_wksta_name, wksta_name, len_wksta_name);
1026
1027         init_string2(&id->nt_chal_resp, (const char *)nt_chal_resp, nt_chal_resp_len, nt_chal_resp_len);
1028         init_string2(&id->lm_chal_resp, (const char *)lm_chal_resp, lm_chal_resp_len, lm_chal_resp_len);
1029
1030 }
1031
1032 /*******************************************************************
1033  Reads or writes an NET_ID_INFO_2 structure.
1034 ********************************************************************/
1035
1036 static BOOL net_io_id_info2(char *desc,  NET_ID_INFO_2 *id, prs_struct *ps, int depth)
1037 {
1038         if (id == NULL)
1039                 return False;
1040
1041         prs_debug(ps, depth, desc, "net_io_id_info2");
1042         depth++;
1043
1044         if(!prs_align(ps))
1045                 return False;
1046         
1047         if(!prs_uint32("ptr_id_info2", ps, depth, &id->ptr_id_info2))
1048                 return False;
1049
1050         if (id->ptr_id_info2 != 0) {
1051                 if(!smb_io_unihdr("unihdr", &id->hdr_domain_name, ps, depth))
1052                         return False;
1053
1054                 if(!prs_uint32("param_ctrl", ps, depth, &id->param_ctrl))
1055                         return False;
1056                 if(!smb_io_logon_id("", &id->logon_id, ps, depth))
1057                         return False;
1058
1059                 if(!smb_io_unihdr("unihdr", &id->hdr_user_name, ps, depth))
1060                         return False;
1061                 if(!smb_io_unihdr("unihdr", &id->hdr_wksta_name, ps, depth))
1062                         return False;
1063
1064                 if(!prs_uint8s (False, "lm_chal", ps, depth, id->lm_chal, 8)) /* lm 8 byte challenge */
1065                         return False;
1066
1067                 if(!smb_io_strhdr("hdr_nt_chal_resp", &id->hdr_nt_chal_resp, ps, depth))
1068                         return False;
1069                 if(!smb_io_strhdr("hdr_lm_chal_resp", &id->hdr_lm_chal_resp, ps, depth))
1070                         return False;
1071
1072                 if(!smb_io_unistr2("uni_domain_name", &id->uni_domain_name,
1073                                 id->hdr_domain_name.buffer, ps, depth))
1074                         return False;
1075                 if(!smb_io_unistr2("uni_user_name  ", &id->uni_user_name,
1076                                 id->hdr_user_name.buffer, ps, depth))
1077                         return False;
1078                 if(!smb_io_unistr2("uni_wksta_name ", &id->uni_wksta_name,
1079                                 id->hdr_wksta_name.buffer, ps, depth))
1080                         return False;
1081                 if(!smb_io_string2("nt_chal_resp", &id->nt_chal_resp,
1082                                 id->hdr_nt_chal_resp.buffer, ps, depth))
1083                         return False;
1084                 if(!smb_io_string2("lm_chal_resp", &id->lm_chal_resp,
1085                                 id->hdr_lm_chal_resp.buffer, ps, depth))
1086                         return False;
1087         }
1088
1089         return True;
1090 }
1091
1092
1093 /*******************************************************************
1094  Inits a DOM_SAM_INFO structure.
1095 ********************************************************************/
1096
1097 void init_sam_info(DOM_SAM_INFO *sam,
1098                                 char *logon_srv, char *comp_name, DOM_CRED *clnt_cred,
1099                                 DOM_CRED *rtn_cred, uint16 logon_level,
1100                                 NET_ID_INFO_CTR *ctr)
1101 {
1102         DEBUG(5,("init_sam_info: %d\n", __LINE__));
1103
1104         init_clnt_info2(&sam->client, logon_srv, comp_name, clnt_cred);
1105
1106         if (rtn_cred != NULL) {
1107                 sam->ptr_rtn_cred = 1;
1108                 memcpy(&sam->rtn_cred, rtn_cred, sizeof(sam->rtn_cred));
1109         } else {
1110                 sam->ptr_rtn_cred = 0;
1111         }
1112
1113         sam->logon_level  = logon_level;
1114         sam->ctr          = ctr;
1115 }
1116
1117 /*******************************************************************
1118  Reads or writes a DOM_SAM_INFO structure.
1119 ********************************************************************/
1120
1121 static BOOL net_io_id_info_ctr(char *desc, NET_ID_INFO_CTR **pp_ctr, prs_struct *ps, int depth)
1122 {
1123         NET_ID_INFO_CTR *ctr = *pp_ctr;
1124
1125         prs_debug(ps, depth, desc, "smb_io_sam_info");
1126         depth++;
1127
1128         if (UNMARSHALLING(ps)) {
1129                 ctr = *pp_ctr = (NET_ID_INFO_CTR *)prs_alloc_mem(ps, sizeof(NET_ID_INFO_CTR));
1130                 if (ctr == NULL)
1131                         return False;
1132         }
1133         
1134         if (ctr == NULL)
1135                 return False;
1136
1137         /* don't 4-byte align here! */
1138
1139         if(!prs_uint16("switch_value ", ps, depth, &ctr->switch_value))
1140                 return False;
1141
1142         switch (ctr->switch_value) {
1143         case 1:
1144                 if(!net_io_id_info1("", &ctr->auth.id1, ps, depth))
1145                         return False;
1146                 break;
1147         case 2:
1148                 if(!net_io_id_info2("", &ctr->auth.id2, ps, depth))
1149                         return False;
1150                 break;
1151         default:
1152                 /* PANIC! */
1153                 DEBUG(4,("smb_io_sam_info: unknown switch_value!\n"));
1154                 break;
1155         }
1156
1157         return True;
1158 }
1159
1160 /*******************************************************************
1161  Reads or writes a DOM_SAM_INFO structure.
1162  ********************************************************************/
1163
1164 static BOOL smb_io_sam_info(char *desc, DOM_SAM_INFO *sam, prs_struct *ps, int depth)
1165 {
1166         if (sam == NULL)
1167                 return False;
1168
1169         prs_debug(ps, depth, desc, "smb_io_sam_info");
1170         depth++;
1171
1172         if(!prs_align(ps))
1173                 return False;
1174         
1175         if(!smb_io_clnt_info2("", &sam->client, ps, depth))
1176                 return False;
1177
1178         if(!prs_uint32("ptr_rtn_cred ", ps, depth, &sam->ptr_rtn_cred))
1179                 return False;
1180         if(!smb_io_cred("", &sam->rtn_cred, ps, depth))
1181                 return False;
1182
1183         if(!prs_uint16("logon_level  ", ps, depth, &sam->logon_level))
1184                 return False;
1185
1186         if (sam->logon_level != 0) {
1187                 if(!net_io_id_info_ctr("logon_info", &sam->ctr, ps, depth))
1188                         return False;
1189         }
1190
1191         return True;
1192 }
1193
1194 /*************************************************************************
1195  Init
1196  *************************************************************************/
1197
1198 void init_net_user_info3(TALLOC_CTX *ctx, NET_USER_INFO_3 *usr, SAM_ACCOUNT *sampw,
1199                          uint16 logon_count, uint16 bad_pw_count,
1200                          uint32 num_groups, DOM_GID *gids,
1201                          uint32 user_flgs, uchar *sess_key,
1202                          char *logon_srv, char *logon_dom,
1203                          DOM_SID *dom_sid, char *other_sids)
1204 {
1205         /* only cope with one "other" sid, right now. */
1206         /* need to count the number of space-delimited sids */
1207         int i;
1208         int num_other_sids = 0;
1209         
1210         NTTIME          logon_time, logoff_time, kickoff_time,
1211                         pass_last_set_time, pass_can_change_time,
1212                         pass_must_change_time;
1213
1214         int             len_user_name, len_full_name, len_home_dir,
1215                         len_dir_drive, len_logon_script, len_profile_path;
1216                         
1217         const char*             user_name = pdb_get_username(sampw);
1218         const char*             full_name = pdb_get_fullname(sampw);
1219         const char*             home_dir  = pdb_get_homedir(sampw);
1220         const char*             dir_drive = pdb_get_dirdrive(sampw);
1221         const char*             logon_script = pdb_get_logon_script(sampw);
1222         const char*             profile_path = pdb_get_profile_path(sampw);
1223
1224         int len_logon_srv    = strlen(logon_srv);
1225         int len_logon_dom    = strlen(logon_dom);
1226
1227         len_user_name    = strlen(user_name   );
1228         len_full_name    = strlen(full_name   );
1229         len_home_dir     = strlen(home_dir    );
1230         len_dir_drive    = strlen(dir_drive   );
1231         len_logon_script = strlen(logon_script);
1232         len_profile_path = strlen(profile_path);
1233
1234
1235         ZERO_STRUCTP(usr);
1236
1237         usr->ptr_user_info = 1; /* yes, we're bothering to put USER_INFO data here */
1238
1239
1240         /* Create NTTIME structs */
1241         unix_to_nt_time (&logon_time,           pdb_get_logon_time(sampw));
1242         unix_to_nt_time (&logoff_time,          pdb_get_logoff_time(sampw));
1243         unix_to_nt_time (&kickoff_time,         pdb_get_kickoff_time(sampw));
1244         unix_to_nt_time (&pass_last_set_time,   pdb_get_pass_last_set_time(sampw));
1245         unix_to_nt_time (&pass_can_change_time, pdb_get_pass_can_change_time(sampw));
1246         unix_to_nt_time (&pass_must_change_time,pdb_get_pass_must_change_time(sampw));
1247
1248         usr->logon_time            = logon_time;
1249         usr->logoff_time           = logoff_time;
1250         usr->kickoff_time          = kickoff_time;
1251         usr->pass_last_set_time    = pass_last_set_time;
1252         usr->pass_can_change_time  = pass_can_change_time;
1253         usr->pass_must_change_time = pass_must_change_time;
1254
1255         init_uni_hdr(&usr->hdr_user_name, len_user_name);
1256         init_uni_hdr(&usr->hdr_full_name, len_full_name);
1257         init_uni_hdr(&usr->hdr_logon_script, len_logon_script);
1258         init_uni_hdr(&usr->hdr_profile_path, len_profile_path);
1259         init_uni_hdr(&usr->hdr_home_dir, len_home_dir);
1260         init_uni_hdr(&usr->hdr_dir_drive, len_dir_drive);
1261
1262         usr->logon_count = logon_count;
1263         usr->bad_pw_count = bad_pw_count;
1264
1265         usr->user_rid = pdb_get_user_rid(sampw);
1266         usr->group_rid = pdb_get_group_rid(sampw);
1267         usr->num_groups = num_groups+1;
1268
1269         usr->buffer_groups = 1; /* indicates fill in groups, below, even if there are none */
1270         usr->user_flgs = user_flgs;
1271
1272         if (sess_key != NULL)
1273                 memcpy(usr->user_sess_key, sess_key, sizeof(usr->user_sess_key));
1274         else
1275                 memset((char *)usr->user_sess_key, '\0', sizeof(usr->user_sess_key));
1276
1277         init_uni_hdr(&usr->hdr_logon_srv, len_logon_srv);
1278         init_uni_hdr(&usr->hdr_logon_dom, len_logon_dom);
1279
1280         usr->buffer_dom_id = dom_sid ? 1 : 0; /* yes, we're bothering to put a domain SID in */
1281
1282         memset((char *)usr->padding, '\0', sizeof(usr->padding));
1283
1284         num_other_sids = init_dom_sid2s(ctx, other_sids, &usr->other_sids);
1285
1286         usr->num_other_sids = num_other_sids;
1287         usr->buffer_other_sids = (num_other_sids != 0) ? 1 : 0; 
1288         
1289         init_unistr2(&usr->uni_user_name, user_name, len_user_name);
1290         init_unistr2(&usr->uni_full_name, full_name, len_full_name);
1291         init_unistr2(&usr->uni_logon_script, logon_script, len_logon_script);
1292         init_unistr2(&usr->uni_profile_path, profile_path, len_profile_path);
1293         init_unistr2(&usr->uni_home_dir, home_dir, len_home_dir);
1294         init_unistr2(&usr->uni_dir_drive, dir_drive, len_dir_drive);
1295
1296         /* always have at least one group == the user's primary group */
1297         usr->num_groups2 = num_groups+1;
1298
1299         usr->gids = (DOM_GID *)talloc_zero(ctx,sizeof(DOM_GID) * (num_groups+1));
1300         if (usr->gids == NULL)
1301                 return;
1302
1303         /* primary group **MUST** go first.  NT4's winmsd.exe will give
1304            "The Network statistics are currently not available.  9-5"
1305            What the heck is this?     -- jerry  */
1306         usr->gids[0].g_rid = usr->group_rid;
1307         usr->gids[0].attr  = 0x07;
1308         for (i = 0; i < num_groups; i++) 
1309                 usr->gids[i+1] = gids[i];       
1310                 
1311         init_unistr2(&usr->uni_logon_srv, logon_srv, len_logon_srv);
1312         init_unistr2(&usr->uni_logon_dom, logon_dom, len_logon_dom);
1313
1314         init_dom_sid2(&usr->dom_sid, dom_sid);
1315         /* "other" sids are set up above */
1316 }
1317
1318 /*******************************************************************
1319  This code has been modified to cope with a NET_USER_INFO_2 - which is
1320  exactly the same as a NET_USER_INFO_3, minus the other sids parameters.
1321  We use validation level to determine if we're marshalling a info 2 or
1322  INFO_3 - be we always return an INFO_3. Based on code donated by Marc
1323  Jacobsen at HP. JRA.
1324 ********************************************************************/
1325
1326 static BOOL net_io_user_info3(char *desc, NET_USER_INFO_3 *usr, prs_struct *ps, int depth, uint16 validation_level)
1327 {
1328         int i;
1329
1330         if (usr == NULL)
1331                 return False;
1332
1333         prs_debug(ps, depth, desc, "lsa_io_lsa_user_info");
1334         depth++;
1335
1336         if (UNMARSHALLING(ps))
1337                 ZERO_STRUCTP(usr);
1338
1339         if(!prs_align(ps))
1340                 return False;
1341         
1342         if(!prs_uint32("ptr_user_info ", ps, depth, &usr->ptr_user_info))
1343                 return False;
1344
1345         if (usr->ptr_user_info == 0)
1346                 return True;
1347
1348         if(!smb_io_time("logon time", &usr->logon_time, ps, depth)) /* logon time */
1349                 return False;
1350         if(!smb_io_time("logoff time", &usr->logoff_time, ps, depth)) /* logoff time */
1351                 return False;
1352         if(!smb_io_time("kickoff time", &usr->kickoff_time, ps, depth)) /* kickoff time */
1353                 return False;
1354         if(!smb_io_time("last set time", &usr->pass_last_set_time, ps, depth)) /* password last set time */
1355                 return False;
1356         if(!smb_io_time("can change time", &usr->pass_can_change_time , ps, depth)) /* password can change time */
1357                 return False;
1358         if(!smb_io_time("must change time", &usr->pass_must_change_time, ps, depth)) /* password must change time */
1359                 return False;
1360
1361         if(!smb_io_unihdr("unihdr", &usr->hdr_user_name, ps, depth)) /* username unicode string header */
1362                 return False;
1363         if(!smb_io_unihdr("unihdr", &usr->hdr_full_name, ps, depth)) /* user's full name unicode string header */
1364                 return False;
1365         if(!smb_io_unihdr("unihdr", &usr->hdr_logon_script, ps, depth)) /* logon script unicode string header */
1366                 return False;
1367         if(!smb_io_unihdr("unihdr", &usr->hdr_profile_path, ps, depth)) /* profile path unicode string header */
1368                 return False;
1369         if(!smb_io_unihdr("unihdr", &usr->hdr_home_dir, ps, depth)) /* home directory unicode string header */
1370                 return False;
1371         if(!smb_io_unihdr("unihdr", &usr->hdr_dir_drive, ps, depth)) /* home directory drive unicode string header */
1372                 return False;
1373
1374         if(!prs_uint16("logon_count   ", ps, depth, &usr->logon_count))  /* logon count */
1375                 return False;
1376         if(!prs_uint16("bad_pw_count  ", ps, depth, &usr->bad_pw_count)) /* bad password count */
1377                 return False;
1378
1379         if(!prs_uint32("user_rid      ", ps, depth, &usr->user_rid))       /* User RID */
1380                 return False;
1381         if(!prs_uint32("group_rid     ", ps, depth, &usr->group_rid))      /* Group RID */
1382                 return False;
1383         if(!prs_uint32("num_groups    ", ps, depth, &usr->num_groups))    /* num groups */
1384                 return False;
1385         if(!prs_uint32("buffer_groups ", ps, depth, &usr->buffer_groups)) /* undocumented buffer pointer to groups. */
1386                 return False;
1387         if(!prs_uint32("user_flgs     ", ps, depth, &usr->user_flgs))     /* user flags */
1388                 return False;
1389
1390         if(!prs_uint8s(False, "user_sess_key", ps, depth, usr->user_sess_key, 16)) /* unused user session key */
1391                 return False;
1392
1393         if(!smb_io_unihdr("unihdr", &usr->hdr_logon_srv, ps, depth)) /* logon server unicode string header */
1394                 return False;
1395         if(!smb_io_unihdr("unihdr", &usr->hdr_logon_dom, ps, depth)) /* logon domain unicode string header */
1396                 return False;
1397
1398         if(!prs_uint32("buffer_dom_id ", ps, depth, &usr->buffer_dom_id)) /* undocumented logon domain id pointer */
1399                 return False;
1400         if(!prs_uint8s (False, "padding       ", ps, depth, usr->padding, 40)) /* unused padding bytes? */
1401                 return False;
1402
1403         if (validation_level == 3) {
1404                 if(!prs_uint32("num_other_sids", ps, depth, &usr->num_other_sids)) /* 0 - num_sids */
1405                         return False;
1406                 if(!prs_uint32("buffer_other_sids", ps, depth, &usr->buffer_other_sids)) /* NULL - undocumented pointer to SIDs. */
1407                         return False;
1408         } else {
1409                 if (UNMARSHALLING(ps)) {
1410                         usr->num_other_sids = 0;
1411                         usr->buffer_other_sids = 0;
1412                 }
1413         }
1414                 
1415         if(!smb_io_unistr2("unistr2", &usr->uni_user_name, usr->hdr_user_name.buffer, ps, depth)) /* username unicode string */
1416                 return False;
1417         if(!smb_io_unistr2("unistr2", &usr->uni_full_name, usr->hdr_full_name.buffer, ps, depth)) /* user's full name unicode string */
1418                 return False;
1419         if(!smb_io_unistr2("unistr2", &usr->uni_logon_script, usr->hdr_logon_script.buffer, ps, depth)) /* logon script unicode string */
1420                 return False;
1421         if(!smb_io_unistr2("unistr2", &usr->uni_profile_path, usr->hdr_profile_path.buffer, ps, depth)) /* profile path unicode string */
1422                 return False;
1423         if(!smb_io_unistr2("unistr2", &usr->uni_home_dir, usr->hdr_home_dir.buffer, ps, depth)) /* home directory unicode string */
1424                 return False;
1425         if(!smb_io_unistr2("unistr2", &usr->uni_dir_drive, usr->hdr_dir_drive.buffer, ps, depth)) /* home directory drive unicode string */
1426                 return False;
1427
1428         if(!prs_align(ps))
1429                 return False;
1430         if(!prs_uint32("num_groups2   ", ps, depth, &usr->num_groups2))        /* num groups */
1431                 return False;
1432
1433         if (UNMARSHALLING(ps) && usr->num_groups2 > 0) {
1434                 usr->gids = (DOM_GID *)prs_alloc_mem(ps, sizeof(DOM_GID)*usr->num_groups2);
1435                 if (usr->gids == NULL)
1436                         return False;
1437         }
1438
1439         for (i = 0; i < usr->num_groups2; i++) {
1440                 if(!smb_io_gid("", &usr->gids[i], ps, depth)) /* group info */
1441                         return False;
1442         }
1443
1444         if(!smb_io_unistr2("unistr2", &usr->uni_logon_srv, usr->hdr_logon_srv.buffer, ps, depth)) /* logon server unicode string */
1445                 return False;
1446         if(!smb_io_unistr2("unistr2", &usr->uni_logon_dom, usr->hdr_logon_srv.buffer, ps, depth)) /* logon domain unicode string */
1447                 return False;
1448
1449         if(!smb_io_dom_sid2("", &usr->dom_sid, ps, depth))           /* domain SID */
1450                 return False;
1451
1452         if (usr->num_other_sids) {
1453
1454                 if (UNMARSHALLING(ps)) {
1455                         usr->other_sids = (DOM_SID2 *)prs_alloc_mem(ps, sizeof(DOM_SID2)*usr->num_other_sids);
1456                         if (usr->other_sids == NULL)
1457                                 return False;
1458                 }
1459         
1460                 if(!prs_uint32("num_other_groups", ps, depth, &usr->num_other_groups))
1461                         return False;
1462
1463                 if (UNMARSHALLING(ps) && usr->num_other_groups > 0) {
1464                         usr->other_gids = (DOM_GID *)prs_alloc_mem(ps, sizeof(DOM_GID)*usr->num_other_groups);
1465                         if (usr->other_gids == NULL)
1466                                 return False;
1467                 }
1468         
1469                 for (i = 0; i < usr->num_other_groups; i++) {
1470                         if(!smb_io_gid("", &usr->other_gids[i], ps, depth)) /* other GIDs */
1471                                 return False;
1472                 }
1473                 for (i = 0; i < usr->num_other_sids; i++) {
1474                         if(!smb_io_dom_sid2("", &usr->other_sids[i], ps, depth)) /* other domain SIDs */
1475                                 return False;
1476                 }
1477         }
1478
1479         return True;
1480 }
1481
1482 /*******************************************************************
1483  Reads or writes a structure.
1484 ********************************************************************/
1485
1486 BOOL net_io_q_sam_logon(char *desc, NET_Q_SAM_LOGON *q_l, prs_struct *ps, int depth)
1487 {
1488         if (q_l == NULL)
1489                 return False;
1490
1491         prs_debug(ps, depth, desc, "net_io_q_sam_logon");
1492         depth++;
1493
1494         if(!prs_align(ps))
1495                 return False;
1496         
1497         if(!smb_io_sam_info("", &q_l->sam_id, ps, depth))
1498                 return False;
1499
1500         if(!prs_uint16("validation_level", ps, depth, &q_l->validation_level))
1501                 return False;
1502
1503         return True;
1504 }
1505
1506 /*******************************************************************
1507  Reads or writes a structure.
1508 ********************************************************************/
1509
1510 BOOL net_io_r_sam_logon(char *desc, NET_R_SAM_LOGON *r_l, prs_struct *ps, int depth)
1511 {
1512         if (r_l == NULL)
1513                 return False;
1514
1515         prs_debug(ps, depth, desc, "net_io_r_sam_logon");
1516         depth++;
1517
1518         if(!prs_uint32("buffer_creds", ps, depth, &r_l->buffer_creds)) /* undocumented buffer pointer */
1519                 return False;
1520         if(!smb_io_cred("", &r_l->srv_creds, ps, depth)) /* server credentials.  server time stamp appears to be ignored. */
1521                 return False;
1522
1523         if(!prs_uint16("switch_value", ps, depth, &r_l->switch_value))
1524                 return False;
1525         if(!prs_align(ps))
1526                 return False;
1527
1528 #if 1 /* W2k always needs this - even for bad passwd. JRA */
1529         if(!net_io_user_info3("", r_l->user, ps, depth, r_l->switch_value))
1530                 return False;
1531 #else
1532         if (r_l->switch_value != 0) {
1533                 if(!net_io_user_info3("", r_l->user, ps, depth, r_l->switch_value))
1534                         return False;
1535         }
1536 #endif
1537
1538         if(!prs_uint32("auth_resp   ", ps, depth, &r_l->auth_resp)) /* 1 - Authoritative response; 0 - Non-Auth? */
1539                 return False;
1540
1541         if(!prs_ntstatus("status      ", ps, depth, &r_l->status))
1542                 return False;
1543
1544         if(!prs_align(ps))
1545                 return False;
1546
1547         return True;
1548 }
1549
1550 /*******************************************************************
1551  Reads or writes a structure.
1552 ********************************************************************/
1553
1554 BOOL net_io_q_sam_logoff(char *desc,  NET_Q_SAM_LOGOFF *q_l, prs_struct *ps, int depth)
1555 {
1556         if (q_l == NULL)
1557                 return False;
1558
1559         prs_debug(ps, depth, desc, "net_io_q_sam_logoff");
1560         depth++;
1561
1562         if(!prs_align(ps))
1563                 return False;
1564         
1565         if(!smb_io_sam_info("", &q_l->sam_id, ps, depth))           /* domain SID */
1566                 return False;
1567
1568         return True;
1569 }
1570
1571 /*******************************************************************
1572  Reads or writes a structure.
1573 ********************************************************************/
1574
1575 BOOL net_io_r_sam_logoff(char *desc, NET_R_SAM_LOGOFF *r_l, prs_struct *ps, int depth)
1576 {
1577         if (r_l == NULL)
1578                 return False;
1579
1580         prs_debug(ps, depth, desc, "net_io_r_sam_logoff");
1581         depth++;
1582
1583         if(!prs_align(ps))
1584                 return False;
1585         
1586         if(!prs_uint32("buffer_creds", ps, depth, &r_l->buffer_creds)) /* undocumented buffer pointer */
1587                 return False;
1588         if(!smb_io_cred("", &r_l->srv_creds, ps, depth)) /* server credentials.  server time stamp appears to be ignored. */
1589                 return False;
1590
1591         if(!prs_ntstatus("status      ", ps, depth, &r_l->status))
1592                 return False;
1593
1594         return True;
1595 }
1596
1597 /*******************************************************************
1598 makes a NET_Q_SAM_SYNC structure.
1599 ********************************************************************/
1600 BOOL init_net_q_sam_sync(NET_Q_SAM_SYNC * q_s, const char *srv_name,
1601                          const char *cli_name, DOM_CRED * cli_creds, 
1602                          uint32 database_id)
1603 {
1604         DEBUG(5, ("init_q_sam_sync\n"));
1605
1606         init_unistr2(&q_s->uni_srv_name, srv_name, strlen(srv_name) + 1);
1607         init_unistr2(&q_s->uni_cli_name, cli_name, strlen(cli_name) + 1);
1608
1609         if (cli_creds) {
1610                 memcpy(&q_s->cli_creds, cli_creds, sizeof(q_s->cli_creds));
1611                 memset(&q_s->ret_creds, 0, sizeof(q_s->ret_creds));
1612         }
1613
1614         q_s->database_id = database_id;
1615         q_s->restart_state = 0;
1616         q_s->sync_context = 0;
1617         q_s->max_size = 0xffff;
1618
1619         return True;
1620 }
1621
1622 /*******************************************************************
1623 reads or writes a structure.
1624 ********************************************************************/
1625 BOOL net_io_q_sam_sync(char *desc, NET_Q_SAM_SYNC * q_s, prs_struct *ps,
1626                        int depth)
1627 {
1628         prs_debug(ps, depth, desc, "net_io_q_sam_sync");
1629         depth++;
1630
1631         if (!smb_io_unistr2("", &q_s->uni_srv_name, True, ps, depth))
1632                 return False;
1633         if (!smb_io_unistr2("", &q_s->uni_cli_name, True, ps, depth))
1634                 return False;
1635
1636         if (!smb_io_cred("", &q_s->cli_creds, ps, depth))
1637                 return False;
1638         if (!smb_io_cred("", &q_s->ret_creds, ps, depth))
1639                 return False;
1640
1641         if (!prs_uint32("database_id  ", ps, depth, &q_s->database_id))
1642                 return False;
1643         if (!prs_uint32("restart_state", ps, depth, &q_s->restart_state))
1644                 return False;
1645         if (!prs_uint32("sync_context ", ps, depth, &q_s->sync_context))
1646                 return False;
1647
1648         if (!prs_uint32("max_size", ps, depth, &q_s->max_size))
1649                 return False;
1650
1651         return True;
1652 }
1653
1654 /*******************************************************************
1655 reads or writes a structure.
1656 ********************************************************************/
1657 static BOOL net_io_sam_delta_hdr(char *desc, SAM_DELTA_HDR * delta,
1658                                  prs_struct *ps, int depth)
1659 {
1660         prs_debug(ps, depth, desc, "net_io_sam_delta_hdr");
1661         depth++;
1662
1663         if (!prs_uint16("type", ps, depth, &delta->type))
1664                 return False;
1665         if (!prs_uint16("type2", ps, depth, &delta->type2))
1666                 return False;
1667         if (!prs_uint32("target_rid", ps, depth, &delta->target_rid))
1668                 return False;
1669
1670         if (!prs_uint32("type3", ps, depth, &delta->type3))
1671                 return False;
1672
1673         /* Not sure why we need this but it seems to be necessary to get
1674            sam deltas working. */
1675
1676         if (delta->type != 0x16) {
1677                 if (!prs_uint32("ptr_delta", ps, depth, &delta->ptr_delta))
1678                         return False;
1679         }
1680
1681         return True;
1682 }
1683
1684 /*******************************************************************
1685 reads or writes a structure.
1686 ********************************************************************/
1687 static BOOL net_io_sam_delta_stamp(char *desc, SAM_DELTA_STAMP *info,
1688                                    prs_struct *ps, int depth)
1689 {
1690         prs_debug(ps, depth, desc, "net_io_sam_delta_stamp");
1691         depth++;
1692
1693         if (!prs_uint32("seqnum", ps, depth, &info->seqnum))
1694                 return False;
1695         if (!prs_uint32("dom_mod_count_ptr", ps, depth, 
1696                         &info->dom_mod_count_ptr))
1697                 return False;
1698
1699         if (info->dom_mod_count_ptr) {
1700                 if (!prs_uint64("dom_mod_count", ps, depth,
1701                                 &info->dom_mod_count))
1702                         return False;
1703         }
1704
1705         return True;
1706 }
1707
1708 /*******************************************************************
1709 reads or writes a structure.
1710 ********************************************************************/
1711 static BOOL net_io_sam_domain_info(char *desc, SAM_DOMAIN_INFO * info,
1712                                    prs_struct *ps, int depth)
1713 {
1714         prs_debug(ps, depth, desc, "net_io_sam_domain_info");
1715         depth++;
1716
1717         if (!smb_io_unihdr("hdr_dom_name", &info->hdr_dom_name, ps, depth))
1718                 return False;
1719         if (!smb_io_unihdr("hdr_oem_info", &info->hdr_oem_info, ps, depth))
1720                 return False;
1721
1722         if (!prs_uint64("force_logoff", ps, depth, &info->force_logoff))
1723                 return False;
1724         if (!prs_uint16("min_pwd_len", ps, depth, &info->min_pwd_len))
1725                 return False;
1726         if (!prs_uint16("pwd_history_len", ps, depth, &info->pwd_history_len))
1727                 return False;
1728         if (!prs_uint64("max_pwd_age", ps, depth, &info->max_pwd_age))
1729                 return False;
1730         if (!prs_uint64("min_pwd_age", ps, depth, &info->min_pwd_age))
1731                 return False;
1732         if (!prs_uint64("dom_mod_count", ps, depth, &info->dom_mod_count))
1733                 return False;
1734         if (!smb_io_time("creation_time", &info->creation_time, ps, depth))
1735                 return False;
1736
1737         if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
1738                 return False;
1739         if (!smb_io_unihdr("hdr_unknown", &info->hdr_unknown, ps, depth))
1740                 return False;
1741
1742         if (ps->data_offset + 40 > ps->buffer_size)
1743                 return False;
1744         ps->data_offset += 40;
1745
1746         if (!smb_io_unistr2("uni_dom_name", &info->uni_dom_name,
1747                             info->hdr_dom_name.buffer, ps, depth))
1748                 return False;
1749         if (!smb_io_unistr2("buf_oem_info", &info->buf_oem_info,
1750                             info->hdr_oem_info.buffer, ps, depth))
1751                 return False;
1752
1753         if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc,
1754                             info->hdr_sec_desc.buffer, ps, depth))
1755                 return False;
1756         if (!smb_io_unistr2("buf_unknown", &info->buf_unknown,
1757                             info->hdr_unknown.buffer, ps, depth))
1758                 return False;
1759
1760         return True;
1761 }
1762
1763 /*******************************************************************
1764 reads or writes a structure.
1765 ********************************************************************/
1766 static BOOL net_io_sam_group_info(char *desc, SAM_GROUP_INFO * info,
1767                                   prs_struct *ps, int depth)
1768 {
1769         prs_debug(ps, depth, desc, "net_io_sam_group_info");
1770         depth++;
1771
1772         if (!smb_io_unihdr("hdr_grp_name", &info->hdr_grp_name, ps, depth))
1773                 return False;
1774         if (!smb_io_gid("gid", &info->gid, ps, depth))
1775                 return False;
1776         if (!smb_io_unihdr("hdr_grp_desc", &info->hdr_grp_desc, ps, depth))
1777                 return False;
1778         if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
1779                 return False;
1780
1781         if (ps->data_offset + 48 > ps->buffer_size)
1782                 return False;
1783         ps->data_offset += 48;
1784
1785         if (!smb_io_unistr2("uni_grp_name", &info->uni_grp_name,
1786                             info->hdr_grp_name.buffer, ps, depth))
1787                 return False;
1788         if (!smb_io_unistr2("uni_grp_desc", &info->uni_grp_desc,
1789                             info->hdr_grp_desc.buffer, ps, depth))
1790                 return False;
1791         if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc,
1792                             info->hdr_sec_desc.buffer, ps, depth))
1793                 return False;
1794
1795         return True;
1796 }
1797
1798 /*******************************************************************
1799 reads or writes a structure.
1800 ********************************************************************/
1801 static BOOL net_io_sam_passwd_info(char *desc, SAM_PWD * pwd,
1802                                    prs_struct *ps, int depth)
1803 {
1804         prs_debug(ps, depth, desc, "net_io_sam_passwd_info");
1805         depth++;
1806
1807         if (!prs_uint32("unk_0 ", ps, depth, &pwd->unk_0))
1808                 return False;
1809
1810         if (!smb_io_unihdr("hdr_lm_pwd", &pwd->hdr_lm_pwd, ps, depth))
1811                 return False;
1812         if (!prs_uint8s(False, "buf_lm_pwd", ps, depth, pwd->buf_lm_pwd, 16))
1813                 return False;
1814
1815         if (!smb_io_unihdr("hdr_nt_pwd", &pwd->hdr_nt_pwd, ps, depth))
1816                 return False;
1817         if (!prs_uint8s(False, "buf_nt_pwd", ps, depth, pwd->buf_nt_pwd, 16))
1818                 return False;
1819
1820         if (!smb_io_unihdr("", &pwd->hdr_empty_lm, ps, depth))
1821                 return False;
1822         if (!smb_io_unihdr("", &pwd->hdr_empty_nt, ps, depth))
1823                 return False;
1824
1825         return True;
1826 }
1827
1828 /*******************************************************************
1829 makes a SAM_ACCOUNT_INFO structure.
1830 ********************************************************************/
1831 BOOL make_sam_account_info(SAM_ACCOUNT_INFO * info,
1832                            const UNISTR2 *user_name,
1833                            const UNISTR2 *full_name,
1834                            uint32 user_rid, uint32 group_rid,
1835                            const UNISTR2 *home_dir,
1836                            const UNISTR2 *dir_drive,
1837                            const UNISTR2 *log_scr,
1838                            const UNISTR2 *desc,
1839                            uint32 acb_info,
1840                            const UNISTR2 *prof_path,
1841                            const UNISTR2 *wkstas,
1842                            const UNISTR2 *unk_str, const UNISTR2 *mung_dial)
1843 {
1844         int len_user_name = user_name != NULL ? user_name->uni_str_len : 0;
1845         int len_full_name = full_name != NULL ? full_name->uni_str_len : 0;
1846         int len_home_dir = home_dir != NULL ? home_dir->uni_str_len : 0;
1847         int len_dir_drive = dir_drive != NULL ? dir_drive->uni_str_len : 0;
1848         int len_logon_script = log_scr != NULL ? log_scr->uni_str_len : 0;
1849         int len_profile_path = prof_path != NULL ? prof_path->uni_str_len : 0;
1850         int len_description = desc != NULL ? desc->uni_str_len : 0;
1851         int len_workstations = wkstas != NULL ? wkstas->uni_str_len : 0;
1852         int len_unknown_str = unk_str != NULL ? unk_str->uni_str_len : 0;
1853         int len_munged_dial = mung_dial != NULL ? mung_dial->uni_str_len : 0;
1854
1855         DEBUG(5, ("make_sam_account_info\n"));
1856
1857         make_uni_hdr(&info->hdr_acct_name, len_user_name);
1858         make_uni_hdr(&info->hdr_full_name, len_full_name);
1859         make_uni_hdr(&info->hdr_home_dir, len_home_dir);
1860         make_uni_hdr(&info->hdr_dir_drive, len_dir_drive);
1861         make_uni_hdr(&info->hdr_logon_script, len_logon_script);
1862         make_uni_hdr(&info->hdr_profile, len_profile_path);
1863         make_uni_hdr(&info->hdr_acct_desc, len_description);
1864         make_uni_hdr(&info->hdr_workstations, len_workstations);
1865         make_uni_hdr(&info->hdr_comment, len_unknown_str);
1866         make_uni_hdr(&info->hdr_parameters, len_munged_dial);
1867
1868         /* not present */
1869         make_bufhdr2(&info->hdr_sec_desc, 0, 0, 0);
1870
1871         info->user_rid = user_rid;
1872         info->group_rid = group_rid;
1873
1874         init_nt_time(&info->logon_time);
1875         init_nt_time(&info->logoff_time);
1876         init_nt_time(&info->pwd_last_set_time);
1877         init_nt_time(&info->acct_expiry_time);
1878
1879         info->logon_divs = 0xA8;
1880         info->ptr_logon_hrs = 0;        /* Don't care right now */
1881
1882         info->bad_pwd_count = 0;
1883         info->logon_count = 0;
1884         info->acb_info = acb_info;
1885         info->nt_pwd_present = 0;
1886         info->lm_pwd_present = 0;
1887         info->pwd_expired = 0;
1888         info->country = 0;
1889         info->codepage = 0;
1890
1891         info->unknown1 = 0x4EC;
1892         info->unknown2 = 0;
1893
1894         copy_unistr2(&info->uni_acct_name, user_name);
1895         copy_unistr2(&info->uni_full_name, full_name);
1896         copy_unistr2(&info->uni_home_dir, home_dir);
1897         copy_unistr2(&info->uni_dir_drive, dir_drive);
1898         copy_unistr2(&info->uni_logon_script, log_scr);
1899         copy_unistr2(&info->uni_profile, prof_path);
1900         copy_unistr2(&info->uni_acct_desc, desc);
1901         copy_unistr2(&info->uni_workstations, wkstas);
1902         copy_unistr2(&info->uni_comment, unk_str);
1903         copy_unistr2(&info->uni_parameters, mung_dial);
1904
1905         return True;
1906 }
1907
1908 /*******************************************************************
1909 reads or writes a structure.
1910 ********************************************************************/
1911 static BOOL net_io_sam_account_info(char *desc, uint8 sess_key[16],
1912                                     SAM_ACCOUNT_INFO * info, prs_struct *ps,
1913                                     int depth)
1914 {
1915         BUFHDR2 hdr_priv_data;
1916         uint32 i;
1917
1918         prs_debug(ps, depth, desc, "net_io_sam_account_info");
1919         depth++;
1920
1921         if (!smb_io_unihdr("hdr_acct_name", &info->hdr_acct_name, ps, depth))
1922                 return False;
1923         if (!smb_io_unihdr("hdr_full_name", &info->hdr_full_name, ps, depth))
1924                 return False;
1925
1926         if (!prs_uint32("user_rid ", ps, depth, &info->user_rid))
1927                 return False;
1928         if (!prs_uint32("group_rid", ps, depth, &info->group_rid))
1929                 return False;
1930
1931         if (!smb_io_unihdr("hdr_home_dir ", &info->hdr_home_dir, ps, depth))
1932                 return False;
1933         if (!smb_io_unihdr("hdr_dir_drive", &info->hdr_dir_drive, ps, depth))
1934                 return False;
1935         if (!smb_io_unihdr("hdr_logon_script", &info->hdr_logon_script, ps,
1936                            depth))
1937                 return False;
1938
1939         if (!smb_io_unihdr("hdr_acct_desc", &info->hdr_acct_desc, ps, depth))
1940                 return False;
1941         if (!smb_io_unihdr("hdr_workstations", &info->hdr_workstations, ps,
1942                            depth))
1943                 return False;
1944
1945         if (!smb_io_time("logon_time", &info->logon_time, ps, depth))
1946                 return False;
1947         if (!smb_io_time("logoff_time", &info->logoff_time, ps, depth))
1948                 return False;
1949
1950         if (!prs_uint32("logon_divs   ", ps, depth, &info->logon_divs))
1951                 return False;
1952         if (!prs_uint32("ptr_logon_hrs", ps, depth, &info->ptr_logon_hrs))
1953                 return False;
1954
1955         if (!prs_uint16("bad_pwd_count", ps, depth, &info->bad_pwd_count))
1956                 return False;
1957         if (!prs_uint16("logon_count", ps, depth, &info->logon_count))
1958                 return False;
1959         if (!smb_io_time("pwd_last_set_time", &info->pwd_last_set_time, ps,
1960                          depth))
1961                 return False;
1962         if (!smb_io_time("acct_expiry_time", &info->acct_expiry_time, ps, 
1963                          depth))
1964                 return False;
1965
1966         if (!prs_uint32("acb_info", ps, depth, &info->acb_info))
1967                 return False;
1968         if (!prs_uint8s(False, "nt_pwd", ps, depth, info->nt_pwd, 16))
1969                 return False;
1970         if (!prs_uint8s(False, "lm_pwd", ps, depth, info->lm_pwd, 16))
1971                 return False;
1972         if (!prs_uint8("lm_pwd_present", ps, depth, &info->lm_pwd_present))
1973                 return False;
1974         if (!prs_uint8("nt_pwd_present", ps, depth, &info->nt_pwd_present))
1975                 return False;
1976         if (!prs_uint8("pwd_expired", ps, depth, &info->pwd_expired))
1977                 return False;
1978
1979         if (!smb_io_unihdr("hdr_comment", &info->hdr_comment, ps, depth))
1980                 return False;
1981         if (!smb_io_unihdr("hdr_parameters", &info->hdr_parameters, ps, 
1982                            depth))
1983                 return False;
1984         if (!prs_uint16("country", ps, depth, &info->country))
1985                 return False;
1986         if (!prs_uint16("codepage", ps, depth, &info->codepage))
1987                 return False;
1988
1989         if (!smb_io_bufhdr2("hdr_priv_data", &hdr_priv_data, ps, depth))
1990                 return False;
1991         if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
1992                 return False;
1993         if (!smb_io_unihdr("hdr_profile", &info->hdr_profile, ps, depth))
1994                 return False;
1995
1996         for (i = 0; i < 3; i++)
1997         {
1998                 if (!smb_io_unihdr("hdr_reserved", &info->hdr_reserved[i], 
1999                                    ps, depth))
2000                         return False;                                          
2001         }
2002
2003         for (i = 0; i < 4; i++)
2004         {
2005                 if (!prs_uint32("dw_reserved", ps, depth, 
2006                                 &info->dw_reserved[i]))
2007                         return False;
2008         }
2009
2010         if (!smb_io_unistr2("uni_acct_name", &info->uni_acct_name,
2011                             info->hdr_acct_name.buffer, ps, depth))
2012                 return False;
2013         prs_align(ps);
2014         if (!smb_io_unistr2("uni_full_name", &info->uni_full_name,
2015                             info->hdr_full_name.buffer, ps, depth))
2016                 return False;
2017         prs_align(ps);
2018         if (!smb_io_unistr2("uni_home_dir ", &info->uni_home_dir,
2019                             info->hdr_home_dir.buffer, ps, depth))
2020                 return False;
2021         prs_align(ps);
2022         if (!smb_io_unistr2("uni_dir_drive", &info->uni_dir_drive,
2023                             info->hdr_dir_drive.buffer, ps, depth))
2024                 return False;
2025         prs_align(ps);
2026         if (!smb_io_unistr2("uni_logon_script", &info->uni_logon_script,
2027                             info->hdr_logon_script.buffer, ps, depth))
2028                 return False;
2029         prs_align(ps);
2030         if (!smb_io_unistr2("uni_acct_desc", &info->uni_acct_desc,
2031                             info->hdr_acct_desc.buffer, ps, depth))
2032                 return False;
2033         prs_align(ps);
2034         if (!smb_io_unistr2("uni_workstations", &info->uni_workstations,
2035                             info->hdr_workstations.buffer, ps, depth))
2036                 return False;
2037         prs_align(ps);
2038
2039         if (!prs_uint32("unknown1", ps, depth, &info->unknown1))
2040                 return False;
2041         if (!prs_uint32("unknown2", ps, depth, &info->unknown2))
2042                 return False;
2043
2044         if (!smb_io_buffer4("buf_logon_hrs", &info->buf_logon_hrs,
2045                             info->ptr_logon_hrs, ps, depth))
2046                 return False;
2047         prs_align(ps);
2048         if (!smb_io_unistr2("uni_comment", &info->uni_comment,
2049                             info->hdr_comment.buffer, ps, depth))
2050                 return False;
2051         prs_align(ps);
2052         if (!smb_io_unistr2("uni_parameters", &info->uni_parameters,
2053                             info->hdr_parameters.buffer, ps, depth))
2054                 return False;
2055         prs_align(ps);
2056         if (hdr_priv_data.buffer != 0)
2057         {
2058                 int old_offset = 0;
2059                 uint32 len = 0x44;
2060                 if (!prs_uint32("pwd_len", ps, depth, &len))
2061                         return False;
2062                 old_offset = ps->data_offset;
2063                 if (len == 0x44)
2064                 {
2065                         if (ps->io)
2066                         {
2067                                 /* reading */
2068                                 if (!prs_hash1(ps, ps->data_offset, sess_key))
2069                                         return False;
2070                         }
2071                         if (!net_io_sam_passwd_info("pass", &info->pass, 
2072                                                     ps, depth))
2073                                 return False;
2074
2075                         if (!ps->io)
2076                         {
2077                                 /* writing */
2078                                 if (!prs_hash1(ps, old_offset, sess_key))
2079                                         return False;
2080                         }
2081                 }
2082                 if (old_offset + len > ps->buffer_size)
2083                         return False;
2084                 ps->data_offset = old_offset + len;
2085         }
2086         if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc,
2087                             info->hdr_sec_desc.buffer, ps, depth))
2088                 return False;
2089         prs_align(ps);
2090         if (!smb_io_unistr2("uni_profile", &info->uni_profile,
2091                             info->hdr_profile.buffer, ps, depth))
2092                 return False;
2093
2094         prs_align(ps);
2095
2096         return True;
2097 }
2098
2099 /*******************************************************************
2100 reads or writes a structure.
2101 ********************************************************************/
2102 static BOOL net_io_sam_group_mem_info(char *desc, SAM_GROUP_MEM_INFO * info,
2103                                       prs_struct *ps, int depth)
2104 {
2105         uint32 i;
2106         fstring tmp;
2107
2108         prs_debug(ps, depth, desc, "net_io_sam_group_mem_info");
2109         depth++;
2110
2111         prs_align(ps);
2112         if (!prs_uint32("ptr_rids   ", ps, depth, &info->ptr_rids))
2113                 return False;
2114         if (!prs_uint32("ptr_attribs", ps, depth, &info->ptr_attribs))
2115                 return False;
2116         if (!prs_uint32("num_members", ps, depth, &info->num_members))
2117                 return False;
2118
2119         if (ps->data_offset + 16 > ps->buffer_size)
2120                 return False;
2121         ps->data_offset += 16;
2122
2123         if (info->ptr_rids != 0)
2124         {
2125                 if (!prs_uint32("num_members2", ps, depth, 
2126                                 &info->num_members2))
2127                         return False;
2128
2129                 if (info->num_members2 != info->num_members)
2130                 {
2131                         /* RPC fault */
2132                         return False;
2133                 }
2134
2135                 info->rids = talloc(ps->mem_ctx, sizeof(uint32) *
2136                                     info->num_members2);
2137
2138                 if (info->rids == NULL) {
2139                         DEBUG(0, ("out of memory allocating %d rids\n",
2140                                   info->num_members2));
2141                         return False;
2142                 }
2143
2144                 for (i = 0; i < info->num_members2; i++)
2145                 {
2146                         slprintf(tmp, sizeof(tmp) - 1, "rids[%02d]", i);
2147                         if (!prs_uint32(tmp, ps, depth, &info->rids[i]))
2148                                 return False;
2149                 }
2150         }
2151
2152         if (info->ptr_attribs != 0)
2153         {
2154                 if (!prs_uint32("num_members3", ps, depth, 
2155                                 &info->num_members3))
2156                         return False;
2157                 if (info->num_members3 != info->num_members)
2158                 {
2159                         /* RPC fault */
2160                         return False;
2161                 }
2162
2163                 info->attribs = talloc(ps->mem_ctx, sizeof(uint32) *
2164                                        info->num_members3);
2165
2166                 if (info->attribs == NULL) {
2167                         DEBUG(0, ("out of memory allocating %d attribs\n",
2168                                   info->num_members3));
2169                         return False;
2170                 }
2171
2172                 for (i = 0; i < info->num_members3; i++)
2173                 {
2174                         slprintf(tmp, sizeof(tmp) - 1, "attribs[%02d]", i);
2175                         if (!prs_uint32(tmp, ps, depth, &info->attribs[i]))
2176                                 return False;
2177                 }
2178         }
2179
2180         return True;
2181 }
2182
2183 /*******************************************************************
2184 reads or writes a structure.
2185 ********************************************************************/
2186 static BOOL net_io_sam_alias_info(char *desc, SAM_ALIAS_INFO * info,
2187                                   prs_struct *ps, int depth)
2188 {
2189         prs_debug(ps, depth, desc, "net_io_sam_alias_info");
2190         depth++;
2191
2192         if (!smb_io_unihdr("hdr_als_name", &info->hdr_als_name, ps, depth))
2193                 return False;
2194         if (!prs_uint32("als_rid", ps, depth, &info->als_rid))
2195                 return False;
2196         if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
2197                 return False;
2198         if (!smb_io_unihdr("hdr_als_desc", &info->hdr_als_desc, ps, depth))
2199                 return False;
2200
2201         if (ps->data_offset + 40 > ps->buffer_size)
2202                 return False;
2203         ps->data_offset += 40;
2204
2205         if (!smb_io_unistr2("uni_als_name", &info->uni_als_name,
2206                             info->hdr_als_name.buffer, ps, depth))
2207                 return False;
2208         if (!smb_io_buffer4("buf_sec_desc", &info->buf_sec_desc,
2209                             info->hdr_sec_desc.buffer, ps, depth))
2210                 return False;
2211         if (!smb_io_unistr2("uni_als_desc", &info->uni_als_desc,
2212                             info->hdr_als_name.buffer, ps, depth))
2213                 return False;
2214
2215         return True;
2216 }
2217
2218 /*******************************************************************
2219 reads or writes a structure.
2220 ********************************************************************/
2221 static BOOL net_io_sam_alias_mem_info(char *desc, SAM_ALIAS_MEM_INFO * info,
2222                                       prs_struct *ps, int depth)
2223 {
2224         uint32 i;
2225         fstring tmp;
2226
2227         prs_debug(ps, depth, desc, "net_io_sam_alias_mem_info");
2228         depth++;
2229
2230         prs_align(ps);
2231         if (!prs_uint32("num_members", ps, depth, &info->num_members))
2232                 return False;
2233         if (!prs_uint32("ptr_members", ps, depth, &info->ptr_members))
2234                 return False;
2235
2236         if (info->ptr_members != 0)
2237         {
2238                 if (ps->data_offset + 16 > ps->buffer_size)
2239                         return False;
2240                 ps->data_offset += 16;
2241
2242                 if (!prs_uint32("num_sids", ps, depth, &info->num_sids))
2243                         return False;
2244                 if (info->num_sids != info->num_members)
2245                 {
2246                         /* RPC fault */
2247                         return False;
2248                 }
2249
2250                 info->ptr_sids = talloc(ps->mem_ctx, sizeof(uint32) *
2251                                         info->num_sids);
2252                 
2253                 if (info->ptr_sids == NULL) {
2254                         DEBUG(0, ("out of memory allocating %d ptr_sids\n",
2255                                   info->num_sids));
2256                         return False;
2257                 }
2258
2259                 for (i = 0; i < info->num_sids; i++)
2260                 {
2261                         slprintf(tmp, sizeof(tmp) - 1, "ptr_sids[%02d]", i);
2262                         if (!prs_uint32(tmp, ps, depth, &info->ptr_sids[i]))
2263                                 return False;
2264                 }
2265
2266                 info->sids = talloc(ps->mem_ctx, sizeof(DOM_SID2) *
2267                                     info->num_sids);
2268
2269                 if (info->sids == NULL) {
2270                         DEBUG(0, ("error allocating %d sids\n",
2271                                   info->num_sids));
2272                         return False;
2273                 }
2274
2275                 for (i = 0; i < info->num_sids; i++)
2276                 {
2277                         if (info->ptr_sids[i] != 0)
2278                         {
2279                                 slprintf(tmp, sizeof(tmp) - 1, "sids[%02d]",
2280                                          i);
2281                                 if (!smb_io_dom_sid2(tmp, &info->sids[i], 
2282                                                      ps, depth))
2283                                         return False;
2284                         }
2285                 }
2286         }
2287
2288         return True;
2289 }
2290
2291 /*******************************************************************
2292 reads or writes a structure.
2293 ********************************************************************/
2294 static BOOL net_io_sam_delta_ctr(char *desc, uint8 sess_key[16],
2295                                  SAM_DELTA_CTR * delta, uint16 type,
2296                                  prs_struct *ps, int depth)
2297 {
2298         prs_debug(ps, depth, desc, "net_io_sam_delta_ctr");
2299         depth++;
2300
2301         switch (type)
2302         {
2303                 /* Seen in sam deltas */
2304
2305                 case SAM_DELTA_SAM_STAMP:
2306                 {
2307                         if (!net_io_sam_delta_stamp("", &delta->stamp,
2308                                                     ps, depth))
2309                                 return False;
2310                         break;
2311                 }
2312
2313                 case SAM_DELTA_DOMAIN_INFO:
2314                 {
2315                         if (!net_io_sam_domain_info("", &delta->domain_info,
2316                                                     ps, depth))
2317                                 return False;
2318                         break;
2319                 }
2320                 case SAM_DELTA_GROUP_INFO:
2321                 {
2322                         if (!net_io_sam_group_info("", &delta->group_info,
2323                                                    ps, depth))
2324                                 return False;
2325                         break;
2326                 }
2327                 case SAM_DELTA_ACCOUNT_INFO:
2328                 {
2329                         if (!net_io_sam_account_info("", sess_key,
2330                                                      &delta->account_info,
2331                                                      ps, depth))
2332                                 return False;
2333                         break;
2334                 }
2335                 case SAM_DELTA_GROUP_MEM:
2336                 {
2337                         if (!net_io_sam_group_mem_info("", 
2338                                                        &delta->grp_mem_info,
2339                                                        ps, depth))
2340                                 return False;
2341                         break;
2342                 }
2343                 case SAM_DELTA_ALIAS_INFO:
2344                 {
2345                         if (!net_io_sam_alias_info("", &delta->alias_info,
2346                                                    ps, depth))
2347                                 return False;
2348                         break;
2349                 }
2350                 case SAM_DELTA_ALIAS_MEM:
2351                 {
2352                         if (!net_io_sam_alias_mem_info("", 
2353                                                        &delta->als_mem_info,
2354                                                        ps, depth))
2355                                 return False;
2356                         break;
2357                 }
2358                 default:
2359                 {
2360                         DEBUG(0,
2361                               ("Replication error: Unknown delta type 0x%x\n",
2362                                type));
2363                         break;
2364                 }
2365         }
2366
2367         return True;
2368 }
2369
2370 /*******************************************************************
2371 reads or writes a structure.
2372 ********************************************************************/
2373 BOOL net_io_r_sam_sync(char *desc, uint8 sess_key[16],
2374                        NET_R_SAM_SYNC * r_s, prs_struct *ps, int depth)
2375 {
2376         uint32 i;
2377
2378         prs_debug(ps, depth, desc, "net_io_r_sam_sync");
2379         depth++;
2380
2381         if (!smb_io_cred("srv_creds", &r_s->srv_creds, ps, depth))
2382                 return False;
2383         if (!prs_uint32("sync_context", ps, depth, &r_s->sync_context))
2384                 return False;
2385
2386         if (!prs_uint32("ptr_deltas", ps, depth, &r_s->ptr_deltas))
2387                 return False;
2388         if (r_s->ptr_deltas != 0)
2389         {
2390                 if (!prs_uint32("num_deltas ", ps, depth, &r_s->num_deltas))
2391                         return False;
2392                 if (!prs_uint32("ptr_deltas2", ps, depth, &r_s->ptr_deltas2))
2393                         return False;
2394                 if (r_s->ptr_deltas2 != 0)
2395                 {
2396                         if (!prs_uint32("num_deltas2", ps, depth,
2397                                         &r_s->num_deltas2))
2398                                 return False;
2399
2400                         if (r_s->num_deltas2 != r_s->num_deltas)
2401                         {
2402                                 /* RPC fault */
2403                                 return False;
2404                         }
2405
2406                         if (r_s->num_deltas2 > 0) {
2407                                 r_s->hdr_deltas = (SAM_DELTA_HDR *)
2408                                         talloc(ps->mem_ctx, r_s->num_deltas2 *
2409                                                sizeof(SAM_DELTA_HDR));
2410                           
2411                                 if (r_s->hdr_deltas == NULL) {
2412                                         DEBUG(0, ("error tallocating memory "
2413                                                   "for %d delta headers\n", 
2414                                                   r_s->num_deltas2));
2415                                         return False;
2416                                 }
2417                         }
2418
2419                         for (i = 0; i < r_s->num_deltas2; i++)
2420                         {
2421                                 if (!net_io_sam_delta_hdr("", 
2422                                                           &r_s->hdr_deltas[i],
2423                                                           ps, depth))
2424                                         return False;
2425                         }
2426
2427                         if (r_s->num_deltas2 > 0) {
2428                                 r_s->deltas = (SAM_DELTA_CTR *)
2429                                         talloc(ps->mem_ctx, r_s->num_deltas2 *
2430                                                sizeof(SAM_DELTA_CTR));
2431
2432                                 if (r_s->deltas == NULL) {
2433                                         DEBUG(0, ("error tallocating memory "
2434                                                   "for %d deltas\n", 
2435                                                   r_s->num_deltas2));
2436                                         return False;
2437                                 }
2438                         }
2439
2440                         for (i = 0; i < r_s->num_deltas2; i++)
2441                         {
2442                                 if (!net_io_sam_delta_ctr(
2443                                         "", sess_key, &r_s->deltas[i],
2444                                         r_s->hdr_deltas[i].type3,
2445                                         ps, depth)) {
2446                                         DEBUG(0, ("hmm, failed on i=%d\n", i));
2447                                         return False;
2448                                 }
2449                         }
2450                 }
2451         }
2452
2453         prs_align(ps);
2454         if (!prs_ntstatus("status", ps, depth, &(r_s->status)))
2455                 return False;
2456
2457         return True;
2458 }
2459
2460 /*******************************************************************
2461 makes a NET_Q_SAM_DELTAS structure.
2462 ********************************************************************/
2463 BOOL init_net_q_sam_deltas(NET_Q_SAM_DELTAS *q_s, const char *srv_name, 
2464                            const char *cli_name, DOM_CRED *cli_creds, 
2465                            uint32 database_id, UINT64_S dom_mod_count)
2466 {
2467         DEBUG(5, ("init_net_q_sam_deltas\n"));
2468
2469         init_unistr2(&q_s->uni_srv_name, srv_name, strlen(srv_name) + 1);
2470         init_unistr2(&q_s->uni_cli_name, cli_name, strlen(cli_name) + 1);
2471
2472         memcpy(&q_s->cli_creds, cli_creds, sizeof(q_s->cli_creds));
2473         memset(&q_s->ret_creds, 0, sizeof(q_s->ret_creds));
2474
2475         q_s->database_id = database_id;
2476         q_s->dom_mod_count.low = dom_mod_count.low;
2477         q_s->dom_mod_count.high = dom_mod_count.high;
2478         q_s->max_size = 0xffff;
2479
2480         return True;
2481 }
2482
2483 /*******************************************************************
2484 reads or writes a structure.
2485 ********************************************************************/
2486 BOOL net_io_q_sam_deltas(char *desc, NET_Q_SAM_DELTAS *q_s, prs_struct *ps,
2487                          int depth)
2488 {
2489         prs_debug(ps, depth, desc, "net_io_q_sam_deltas");
2490         depth++;
2491
2492         if (!smb_io_unistr2("", &q_s->uni_srv_name, True, ps, depth))
2493                 return False;
2494         if (!smb_io_unistr2("", &q_s->uni_cli_name, True, ps, depth))
2495                 return False;
2496
2497         if (!smb_io_cred("", &q_s->cli_creds, ps, depth))
2498                 return False;
2499         if (!smb_io_cred("", &q_s->ret_creds, ps, depth))
2500                 return False;
2501
2502         if (!prs_uint32("database_id  ", ps, depth, &q_s->database_id))
2503                 return False;
2504         if (!prs_uint64("dom_mod_count", ps, depth, &q_s->dom_mod_count))
2505                 return False;
2506         if (!prs_uint32("max_size", ps, depth, &q_s->max_size))
2507                 return False;
2508
2509         return True;
2510 }
2511
2512 /*******************************************************************
2513 reads or writes a structure.
2514 ********************************************************************/
2515 BOOL net_io_r_sam_deltas(char *desc, uint8 sess_key[16],
2516                          NET_R_SAM_DELTAS *r_s, prs_struct *ps, int depth)
2517 {
2518         int i;
2519
2520         prs_debug(ps, depth, desc, "net_io_r_sam_deltas");
2521         depth++;
2522
2523         if (!smb_io_cred("srv_creds", &r_s->srv_creds, ps, depth))
2524                 return False;
2525         if (!prs_uint64("dom_mod_count", ps, depth, &r_s->dom_mod_count))
2526                 return False;
2527
2528         if (!prs_uint32("ptr_deltas", ps, depth, &r_s->ptr_deltas))
2529                 return False;
2530         if (!prs_uint32("num_deltas", ps, depth, &r_s->num_deltas))
2531                 return False;
2532         if (!prs_uint32("ptr_deltas2", ps, depth, &r_s->num_deltas2))
2533                 return False;
2534
2535         if (r_s->num_deltas2 != 0)
2536         {
2537                 if (!prs_uint32("num_deltas2 ", ps, depth, &r_s->num_deltas2))
2538                         return False;
2539
2540                 if (r_s->ptr_deltas != 0)
2541                 {
2542                         if (r_s->num_deltas > 0) {
2543                                 r_s->hdr_deltas = (SAM_DELTA_HDR *)
2544                                         talloc(ps->mem_ctx, r_s->num_deltas *
2545                                                sizeof(SAM_DELTA_HDR));
2546                                 if (r_s->hdr_deltas == NULL) {
2547                                         DEBUG(0, ("error tallocating memory "
2548                                                   "for %d delta headers\n", 
2549                                                   r_s->num_deltas));
2550                                         return False;
2551                                 }
2552                         }
2553
2554                         for (i = 0; i < r_s->num_deltas; i++)
2555                         {
2556                                 net_io_sam_delta_hdr("", &r_s->hdr_deltas[i],
2557                                                       ps, depth);
2558                         }
2559                         
2560                         if (r_s->num_deltas > 0) {
2561                                 r_s->deltas = (SAM_DELTA_CTR *)
2562                                         talloc(ps->mem_ctx, r_s->num_deltas *
2563                                                sizeof(SAM_DELTA_CTR));
2564
2565                                 if (r_s->deltas == NULL) {
2566                                         DEBUG(0, ("error tallocating memory "
2567                                                   "for %d deltas\n", 
2568                                                   r_s->num_deltas));
2569                                         return False;
2570                                 }
2571                         }
2572
2573                         for (i = 0; i < r_s->num_deltas; i++)
2574                         {
2575                                 if (!net_io_sam_delta_ctr(
2576                                         "", sess_key,
2577                                         &r_s->deltas[i],
2578                                         r_s->hdr_deltas[i].type2,
2579                                         ps, depth))
2580                                         
2581                                         return False;
2582                         }
2583                 }
2584         }
2585
2586         prs_align(ps);
2587         if (!prs_ntstatus("status", ps, depth, &r_s->status))
2588                 return False;
2589
2590         return True;
2591 }