r11706: Implement dsr_getdcname client code. It's handy: It not only gives you the IP
[sfrench/samba-autobuild/.git] / source / rpc_parse / parse_net.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-1997,
5  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6  *  Copyright (C) Paul Ashton                       1997.
7  *  Copyright (C) Jean François Micouleau           2002.
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 #undef DBGC_CLASS
27 #define DBGC_CLASS DBGC_RPC_PARSE
28
29 /*******************************************************************
30  Reads or writes a structure.
31 ********************************************************************/
32
33 static BOOL net_io_neg_flags(const char *desc, NEG_FLAGS *neg, prs_struct *ps, int depth)
34 {
35         if (neg == NULL)
36                 return False;
37
38         prs_debug(ps, depth, desc, "net_io_neg_flags");
39         depth++;
40
41         if(!prs_align(ps))
42                 return False;
43         
44         if(!prs_uint32("neg_flags", ps, depth, &neg->neg_flags))
45                 return False;
46
47         return True;
48 }
49
50 /*******************************************************************
51  Inits a NETLOGON_INFO_3 structure.
52 ********************************************************************/
53
54 static void init_netinfo_3(NETLOGON_INFO_3 *info, uint32 flags, uint32 logon_attempts)
55 {
56         info->flags          = flags;
57         info->logon_attempts = logon_attempts;
58         info->reserved_1     = 0x0;
59         info->reserved_2     = 0x0;
60         info->reserved_3     = 0x0;
61         info->reserved_4     = 0x0;
62         info->reserved_5     = 0x0;
63 }
64
65 /*******************************************************************
66  Reads or writes a NETLOGON_INFO_3 structure.
67 ********************************************************************/
68
69 static BOOL net_io_netinfo_3(const char *desc,  NETLOGON_INFO_3 *info, prs_struct *ps, int depth)
70 {
71         if (info == NULL)
72                 return False;
73
74         prs_debug(ps, depth, desc, "net_io_netinfo_3");
75         depth++;
76
77         if(!prs_align(ps))
78                 return False;
79
80         if(!prs_uint32("flags         ", ps, depth, &info->flags))
81                 return False;
82         if(!prs_uint32("logon_attempts", ps, depth, &info->logon_attempts))
83                 return False;
84         if(!prs_uint32("reserved_1    ", ps, depth, &info->reserved_1))
85                 return False;
86         if(!prs_uint32("reserved_2    ", ps, depth, &info->reserved_2))
87                 return False;
88         if(!prs_uint32("reserved_3    ", ps, depth, &info->reserved_3))
89                 return False;
90         if(!prs_uint32("reserved_4    ", ps, depth, &info->reserved_4))
91                 return False;
92         if(!prs_uint32("reserved_5    ", ps, depth, &info->reserved_5))
93                 return False;
94
95         return True;
96 }
97
98
99 /*******************************************************************
100  Inits a NETLOGON_INFO_1 structure.
101 ********************************************************************/
102
103 static void init_netinfo_1(NETLOGON_INFO_1 *info, uint32 flags, uint32 pdc_status)
104 {
105         info->flags      = flags;
106         info->pdc_status = pdc_status;
107 }
108
109 /*******************************************************************
110  Reads or writes a NETLOGON_INFO_1 structure.
111 ********************************************************************/
112
113 static BOOL net_io_netinfo_1(const char *desc, NETLOGON_INFO_1 *info, prs_struct *ps, int depth)
114 {
115         if (info == NULL)
116                 return False;
117
118         prs_debug(ps, depth, desc, "net_io_netinfo_1");
119         depth++;
120
121         if(!prs_align(ps))
122                 return False;
123         
124         if(!prs_uint32("flags     ", ps, depth, &info->flags))
125                 return False;
126         if(!prs_uint32("pdc_status", ps, depth, &info->pdc_status))
127                 return False;
128
129         return True;
130 }
131
132 /*******************************************************************
133  Inits a NETLOGON_INFO_2 structure.
134 ********************************************************************/
135
136 static void init_netinfo_2(NETLOGON_INFO_2 *info, uint32 flags, uint32 pdc_status,
137                                 uint32 tc_status, const char *trusted_dc_name)
138 {
139         info->flags      = flags;
140         info->pdc_status = pdc_status;
141         info->ptr_trusted_dc_name = 1;
142         info->tc_status  = tc_status;
143
144         if (trusted_dc_name != NULL)
145                 init_unistr2(&info->uni_trusted_dc_name, trusted_dc_name, UNI_STR_TERMINATE);
146         else
147                 init_unistr2(&info->uni_trusted_dc_name, "", UNI_STR_TERMINATE);
148 }
149
150 /*******************************************************************
151  Reads or writes a NETLOGON_INFO_2 structure.
152 ********************************************************************/
153
154 static BOOL net_io_netinfo_2(const char *desc, NETLOGON_INFO_2 *info, prs_struct *ps, int depth)
155 {
156         if (info == NULL)
157                 return False;
158
159         prs_debug(ps, depth, desc, "net_io_netinfo_2");
160         depth++;
161
162         if(!prs_align(ps))
163                 return False;
164         
165         if(!prs_uint32("flags              ", ps, depth, &info->flags))
166                 return False;
167         if(!prs_uint32("pdc_status         ", ps, depth, &info->pdc_status))
168                 return False;
169         if(!prs_uint32("ptr_trusted_dc_name", ps, depth, &info->ptr_trusted_dc_name))
170                 return False;
171         if(!prs_uint32("tc_status          ", ps, depth, &info->tc_status))
172                 return False;
173
174         if (info->ptr_trusted_dc_name != 0) {
175                 if(!smb_io_unistr2("unistr2", &info->uni_trusted_dc_name, info->ptr_trusted_dc_name, ps, depth))
176                         return False;
177         }
178
179         if(!prs_align(ps))
180                 return False;
181
182         return True;
183 }
184
185 static BOOL net_io_ctrl_data_info_5(const char *desc, CTRL_DATA_INFO_5 *info, prs_struct *ps, int depth)
186 {
187         if (info == NULL)
188                 return False;
189                 
190         prs_debug(ps, depth, desc, "net_io_ctrl_data_info_5");
191         depth++;
192         
193         if ( !prs_uint32( "function_code", ps, depth, &info->function_code ) )
194                 return False;
195         
196         if(!prs_uint32("ptr_domain", ps, depth, &info->ptr_domain))
197                 return False;
198                 
199         if ( info->ptr_domain ) {
200                 if(!smb_io_unistr2("domain", &info->domain, info->ptr_domain, ps, depth))
201                         return False;
202         }
203                 
204         return True;
205 }
206
207 static BOOL net_io_ctrl_data_info_6(const char *desc, CTRL_DATA_INFO_6 *info, prs_struct *ps, int depth)
208 {
209         if (info == NULL)
210                 return False;
211                 
212         prs_debug(ps, depth, desc, "net_io_ctrl_data_info_6");
213         depth++;
214         
215         if ( !prs_uint32( "function_code", ps, depth, &info->function_code ) )
216                 return False;
217         
218         if(!prs_uint32("ptr_domain", ps, depth, &info->ptr_domain))
219                 return False;
220                 
221         if ( info->ptr_domain ) {
222                 if(!smb_io_unistr2("domain", &info->domain, info->ptr_domain, ps, depth))
223                         return False;
224         }
225                 
226         return True;
227 }
228
229 /*******************************************************************
230  Reads or writes an NET_Q_LOGON_CTRL2 structure.
231 ********************************************************************/
232
233 BOOL net_io_q_logon_ctrl2(const char *desc, NET_Q_LOGON_CTRL2 *q_l, prs_struct *ps, int depth)
234 {
235         if (q_l == NULL)
236                 return False;
237
238         prs_debug(ps, depth, desc, "net_io_q_logon_ctrl2");
239         depth++;
240
241         if(!prs_align(ps))
242                 return False;
243
244         if(!prs_uint32("ptr          ", ps, depth, &q_l->ptr))
245                 return False;
246
247         if(!smb_io_unistr2 ("", &q_l->uni_server_name, q_l->ptr, ps, depth))
248                 return False;
249
250         if(!prs_align(ps))
251                 return False;
252
253         if(!prs_uint32("function_code", ps, depth, &q_l->function_code))
254                 return False;
255         if(!prs_uint32("query_level  ", ps, depth, &q_l->query_level))
256                 return False;
257         switch ( q_l->function_code ) {
258                 case NETLOGON_CONTROL_REDISCOVER:
259                         if ( !net_io_ctrl_data_info_5( "ctrl_data_info5", &q_l->info.info5, ps, depth) ) 
260                                 return False;
261                         break;
262                         
263                 case NETLOGON_CONTROL_TC_QUERY:
264                         if ( !net_io_ctrl_data_info_6( "ctrl_data_info6", &q_l->info.info6, ps, depth) ) 
265                                 return False;
266                         break;
267
268                 default:
269                         DEBUG(0,("net_io_q_logon_ctrl2: unknown function_code [%d]\n",
270                                 q_l->function_code));
271                         return False;
272         }
273         
274         return True;
275 }
276
277 /*******************************************************************
278  Inits an NET_Q_LOGON_CTRL2 structure.
279 ********************************************************************/
280
281 void init_net_q_logon_ctrl2(NET_Q_LOGON_CTRL2 *q_l, const char *srv_name,
282                             uint32 query_level)
283 {
284         DEBUG(5,("init_q_logon_ctrl2\n"));
285
286         q_l->function_code = 0x01;
287         q_l->query_level = query_level;
288
289         init_unistr2(&q_l->uni_server_name, srv_name, UNI_STR_TERMINATE);
290 }
291
292 /*******************************************************************
293  Inits an NET_R_LOGON_CTRL2 structure.
294 ********************************************************************/
295
296 void init_net_r_logon_ctrl2(NET_R_LOGON_CTRL2 *r_l, uint32 query_level,
297                             uint32 flags, uint32 pdc_status, 
298                             uint32 logon_attempts, uint32 tc_status, 
299                             const char *trusted_domain_name)
300 {
301         r_l->switch_value  = query_level; 
302
303         switch (query_level) {
304         case 1:
305                 r_l->ptr = 1; /* undocumented pointer */
306                 init_netinfo_1(&r_l->logon.info1, flags, pdc_status);   
307                 r_l->status = NT_STATUS_OK;
308                 break;
309         case 2:
310                 r_l->ptr = 1; /* undocumented pointer */
311                 init_netinfo_2(&r_l->logon.info2, flags, pdc_status,
312                                tc_status, trusted_domain_name); 
313                 r_l->status = NT_STATUS_OK;
314                 break;
315         case 3:
316                 r_l->ptr = 1; /* undocumented pointer */
317                 init_netinfo_3(&r_l->logon.info3, flags, logon_attempts);       
318                 r_l->status = NT_STATUS_OK;
319                 break;
320         default:
321                 DEBUG(2,("init_r_logon_ctrl2: unsupported switch value %d\n",
322                         r_l->switch_value));
323                 r_l->ptr = 0; /* undocumented pointer */
324
325                 /* take a guess at an error code... */
326                 r_l->status = NT_STATUS_INVALID_INFO_CLASS;
327                 break;
328         }
329 }
330
331 /*******************************************************************
332  Reads or writes an NET_R_LOGON_CTRL2 structure.
333 ********************************************************************/
334
335 BOOL net_io_r_logon_ctrl2(const char *desc, NET_R_LOGON_CTRL2 *r_l, prs_struct *ps, int depth)
336 {
337         if (r_l == NULL)
338                 return False;
339
340         prs_debug(ps, depth, desc, "net_io_r_logon_ctrl2");
341         depth++;
342
343         if(!prs_uint32("switch_value ", ps, depth, &r_l->switch_value))
344                 return False;
345         if(!prs_uint32("ptr          ", ps, depth, &r_l->ptr))
346                 return False;
347
348         if (r_l->ptr != 0) {
349                 switch (r_l->switch_value) {
350                 case 1:
351                         if(!net_io_netinfo_1("", &r_l->logon.info1, ps, depth))
352                                 return False;
353                         break;
354                 case 2:
355                         if(!net_io_netinfo_2("", &r_l->logon.info2, ps, depth))
356                                 return False;
357                         break;
358                 case 3:
359                         if(!net_io_netinfo_3("", &r_l->logon.info3, ps, depth))
360                                 return False;
361                         break;
362                 default:
363                         DEBUG(2,("net_io_r_logon_ctrl2: unsupported switch value %d\n",
364                                 r_l->switch_value));
365                         break;
366                 }
367         }
368
369         if(!prs_ntstatus("status       ", ps, depth, &r_l->status))
370                 return False;
371
372         return True;
373 }
374
375 /*******************************************************************
376  Reads or writes an NET_Q_LOGON_CTRL structure.
377 ********************************************************************/
378
379 BOOL net_io_q_logon_ctrl(const char *desc, NET_Q_LOGON_CTRL *q_l, prs_struct *ps, 
380                          int depth)
381 {
382         prs_debug(ps, depth, desc, "net_io_q_logon_ctrl");
383         depth++;
384
385         if(!prs_align(ps))
386                 return False;
387
388         if(!prs_uint32("ptr          ", ps, depth, &q_l->ptr))
389                 return False;
390
391         if(!smb_io_unistr2 ("", &q_l->uni_server_name, q_l->ptr, ps, depth))
392                 return False;
393
394         if(!prs_align(ps))
395                 return False;
396
397         if(!prs_uint32("function_code", ps, depth, &q_l->function_code))
398                 return False;
399         if(!prs_uint32("query_level  ", ps, depth, &q_l->query_level))
400                 return False;
401
402         return True;
403 }
404
405 /*******************************************************************
406  Inits an NET_Q_LOGON_CTRL structure.
407 ********************************************************************/
408
409 void init_net_q_logon_ctrl(NET_Q_LOGON_CTRL *q_l, const char *srv_name,
410                            uint32 query_level)
411 {
412         DEBUG(5,("init_q_logon_ctrl\n"));
413
414         q_l->function_code = 0x01; /* ??? */
415         q_l->query_level = query_level;
416
417         init_unistr2(&q_l->uni_server_name, srv_name, UNI_STR_TERMINATE);
418 }
419
420 /*******************************************************************
421  Inits an NET_R_LOGON_CTRL structure.
422 ********************************************************************/
423
424 void init_net_r_logon_ctrl(NET_R_LOGON_CTRL *r_l, uint32 query_level,
425                            uint32 flags, uint32 pdc_status)
426 {
427         DEBUG(5,("init_r_logon_ctrl\n"));
428
429         r_l->switch_value  = query_level; /* should only be 0x1 */
430
431         switch (query_level) {
432         case 1:
433                 r_l->ptr = 1; /* undocumented pointer */
434                 init_netinfo_1(&r_l->logon.info1, flags, pdc_status);   
435                 r_l->status = NT_STATUS_OK;
436                 break;
437         default:
438                 DEBUG(2,("init_r_logon_ctrl: unsupported switch value %d\n",
439                         r_l->switch_value));
440                 r_l->ptr = 0; /* undocumented pointer */
441
442                 /* take a guess at an error code... */
443                 r_l->status = NT_STATUS_INVALID_INFO_CLASS;
444                 break;
445         }
446 }
447
448 /*******************************************************************
449  Reads or writes an NET_R_LOGON_CTRL structure.
450 ********************************************************************/
451
452 BOOL net_io_r_logon_ctrl(const char *desc, NET_R_LOGON_CTRL *r_l, prs_struct *ps, 
453                          int depth)
454 {
455         prs_debug(ps, depth, desc, "net_io_r_logon_ctrl");
456         depth++;
457
458         if(!prs_uint32("switch_value ", ps, depth, &r_l->switch_value))
459                 return False;
460         if(!prs_uint32("ptr          ", ps, depth, &r_l->ptr))
461                 return False;
462
463         if (r_l->ptr != 0) {
464                 switch (r_l->switch_value) {
465                 case 1:
466                         if(!net_io_netinfo_1("", &r_l->logon.info1, ps, depth))
467                                 return False;
468                         break;
469                 default:
470                         DEBUG(2,("net_io_r_logon_ctrl: unsupported switch value %d\n",
471                                 r_l->switch_value));
472                         break;
473                 }
474         }
475
476         if(!prs_ntstatus("status       ", ps, depth, &r_l->status))
477                 return False;
478
479         return True;
480 }
481
482 /*******************************************************************
483  Inits an NET_R_GETDCNAME structure.
484 ********************************************************************/
485 void init_net_q_getdcname(NET_Q_GETDCNAME *r_t, const char *logon_server,
486                           const char *domainname)
487 {
488         DEBUG(5,("init_r_getdcname\n"));
489
490         r_t->ptr_logon_server = (logon_server != NULL);
491         init_unistr2(&r_t->uni_logon_server, logon_server, UNI_STR_TERMINATE);
492         r_t->ptr_domainname = (domainname != NULL);
493         init_unistr2(&r_t->uni_domainname, domainname, UNI_STR_TERMINATE);
494 }
495
496 /*******************************************************************
497  Reads or writes an NET_Q_GETDCNAME structure.
498 ********************************************************************/
499
500 BOOL net_io_q_getdcname(const char *desc, NET_Q_GETDCNAME *r_t, prs_struct *ps,
501                         int depth)
502 {
503         if (r_t == NULL)
504                 return False;
505
506         prs_debug(ps, depth, desc, "net_io_q_getdcname");
507         depth++;
508
509         if (!prs_uint32("ptr_logon_server", ps, depth, &r_t->ptr_logon_server))
510                 return False;
511
512         if (!smb_io_unistr2("logon_server", &r_t->uni_logon_server,
513                             r_t->ptr_logon_server, ps, depth))
514                 return False;
515
516         if (!prs_align(ps))
517                 return False;
518
519         if (!prs_uint32("ptr_domainname", ps, depth, &r_t->ptr_domainname))
520                 return False;
521
522         if (!smb_io_unistr2("domainname", &r_t->uni_domainname,
523                             r_t->ptr_domainname, ps, depth))
524                 return False;
525
526         return True;
527 }
528
529
530 /*******************************************************************
531  Inits an NET_R_GETDCNAME structure.
532 ********************************************************************/
533 void init_net_r_getdcname(NET_R_GETDCNAME *r_t, const char *dcname)
534 {
535         DEBUG(5,("init_r_getdcname\n"));
536
537         init_unistr2(&r_t->uni_dcname, dcname, UNI_STR_TERMINATE);
538 }
539
540 /*******************************************************************
541  Reads or writes an NET_R_GETDCNAME structure.
542 ********************************************************************/
543
544 BOOL net_io_r_getdcname(const char *desc, NET_R_GETDCNAME *r_t, prs_struct *ps,
545                         int depth)
546 {
547         if (r_t == NULL)
548                 return False;
549
550         prs_debug(ps, depth, desc, "net_io_r_getdcname");
551         depth++;
552
553         if (!prs_uint32("ptr_dcname", ps, depth, &r_t->ptr_dcname))
554                 return False;
555
556         if (!smb_io_unistr2("dcname", &r_t->uni_dcname,
557                             r_t->ptr_dcname, ps, depth))
558                 return False;
559
560         if (!prs_align(ps))
561                 return False;
562
563         if (!prs_ntstatus("status", ps, depth, &r_t->status))
564                 return False;
565
566         return True;
567 }
568
569 /*******************************************************************
570  Inits an NET_R_TRUST_DOM_LIST structure.
571 ********************************************************************/
572
573 void init_r_trust_dom(NET_R_TRUST_DOM_LIST *r_t,
574                         uint32 num_doms, const char *dom_name)
575 {
576         unsigned int i = 0;
577
578         DEBUG(5,("init_r_trust_dom\n"));
579
580         for (i = 0; i < MAX_TRUST_DOMS; i++) {
581                 r_t->uni_trust_dom_name[i].uni_str_len = 0;
582                 r_t->uni_trust_dom_name[i].uni_max_len = 0;
583         }
584         if (num_doms > MAX_TRUST_DOMS)
585                 num_doms = MAX_TRUST_DOMS;
586
587         for (i = 0; i < num_doms; i++) {
588                 fstring domain_name;
589                 fstrcpy(domain_name, dom_name);
590                 strupper_m(domain_name);
591                 init_unistr2(&r_t->uni_trust_dom_name[i], domain_name, UNI_STR_TERMINATE);
592                 /* the use of UNISTR2 here is non-standard. */
593                 r_t->uni_trust_dom_name[i].offset = 0x1;
594         }
595         
596         r_t->status = NT_STATUS_OK;
597 }
598
599 /*******************************************************************
600  Reads or writes an NET_R_TRUST_DOM_LIST structure.
601 ********************************************************************/
602
603 BOOL net_io_r_trust_dom(const char *desc, NET_R_TRUST_DOM_LIST *r_t, prs_struct *ps, int depth)
604 {
605         uint32 value;
606
607         if (r_t == NULL)
608                  return False;
609
610         prs_debug(ps, depth, desc, "net_io_r_trust_dom");
611         depth++;
612
613         /* temporary code to give a valid response */
614         value=2;
615         if(!prs_uint32("status", ps, depth, &value))
616                  return False;
617
618         value=1;
619         if(!prs_uint32("status", ps, depth, &value))
620                  return False;
621         value=2;
622         if(!prs_uint32("status", ps, depth, &value))
623                  return False;
624
625         value=0;
626         if(!prs_uint32("status", ps, depth, &value))
627                  return False;
628
629         value=0;
630         if(!prs_uint32("status", ps, depth, &value))
631                  return False;
632
633 /* old non working code */
634 #if 0
635         int i;
636
637         for (i = 0; i < MAX_TRUST_DOMS; i++) {
638                 if (r_t->uni_trust_dom_name[i].uni_str_len == 0)
639                         break;
640                 if(!smb_io_unistr2("", &r_t->uni_trust_dom_name[i], True, ps, depth))
641                          return False;
642         }
643
644         if(!prs_ntstatus("status", ps, depth, &r_t->status))
645                  return False;
646 #endif
647         return True;
648 }
649
650
651 /*******************************************************************
652  Reads or writes an NET_Q_TRUST_DOM_LIST structure.
653 ********************************************************************/
654
655 BOOL net_io_q_trust_dom(const char *desc, NET_Q_TRUST_DOM_LIST *q_l, prs_struct *ps, int depth)
656 {
657         if (q_l == NULL)
658                  return False;
659
660         prs_debug(ps, depth, desc, "net_io_q_trust_dom");
661         depth++;
662
663         if(!prs_uint32("ptr          ", ps, depth, &q_l->ptr))
664                  return False;
665         if(!smb_io_unistr2 ("", &q_l->uni_server_name, q_l->ptr, ps, depth))
666                  return False;
667
668         return True;
669 }
670
671 /*******************************************************************
672  Inits an NET_Q_REQ_CHAL structure.
673 ********************************************************************/
674
675 void init_q_req_chal(NET_Q_REQ_CHAL *q_c,
676                      const char *logon_srv, const char *logon_clnt,
677                      const DOM_CHAL *clnt_chal)
678 {
679         DEBUG(5,("init_q_req_chal: %d\n", __LINE__));
680
681         q_c->undoc_buffer = 1; /* don't know what this buffer is */
682
683         init_unistr2(&q_c->uni_logon_srv, logon_srv , UNI_STR_TERMINATE);
684         init_unistr2(&q_c->uni_logon_clnt, logon_clnt, UNI_STR_TERMINATE);
685
686         memcpy(q_c->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data));
687
688         DEBUG(5,("init_q_req_chal: %d\n", __LINE__));
689 }
690
691 /*******************************************************************
692  Reads or writes an NET_Q_REQ_CHAL structure.
693 ********************************************************************/
694
695 BOOL net_io_q_req_chal(const char *desc,  NET_Q_REQ_CHAL *q_c, prs_struct *ps, int depth)
696 {
697         if (q_c == NULL)
698                 return False;
699
700         prs_debug(ps, depth, desc, "net_io_q_req_chal");
701         depth++;
702
703         if(!prs_align(ps))
704                 return False;
705     
706         if(!prs_uint32("undoc_buffer", ps, depth, &q_c->undoc_buffer))
707                 return False;
708
709         if(!smb_io_unistr2("", &q_c->uni_logon_srv, True, ps, depth)) /* logon server unicode string */
710                 return False;
711         if(!smb_io_unistr2("", &q_c->uni_logon_clnt, True, ps, depth)) /* logon client unicode string */
712                 return False;
713
714         if(!smb_io_chal("", &q_c->clnt_chal, ps, depth))
715                 return False;
716
717         return True;
718 }
719
720 /*******************************************************************
721  Reads or writes a structure.
722 ********************************************************************/
723
724 BOOL net_io_r_req_chal(const char *desc, NET_R_REQ_CHAL *r_c, prs_struct *ps, int depth)
725 {
726         if (r_c == NULL)
727                 return False;
728
729         prs_debug(ps, depth, desc, "net_io_r_req_chal");
730         depth++;
731
732         if(!prs_align(ps))
733                 return False;
734     
735         if(!smb_io_chal("", &r_c->srv_chal, ps, depth)) /* server challenge */
736                 return False;
737
738         if(!prs_ntstatus("status", ps, depth, &r_c->status))
739                 return False;
740
741         return True;
742 }
743
744
745 /*******************************************************************
746  Reads or writes a structure.
747 ********************************************************************/
748
749 BOOL net_io_q_auth(const char *desc, NET_Q_AUTH *q_a, prs_struct *ps, int depth)
750 {
751         if (q_a == NULL)
752                 return False;
753
754         prs_debug(ps, depth, desc, "net_io_q_auth");
755         depth++;
756
757         if(!prs_align(ps))
758                 return False;
759     
760         if(!smb_io_log_info ("", &q_a->clnt_id, ps, depth)) /* client identification info */
761                 return False;
762         if(!smb_io_chal("", &q_a->clnt_chal, ps, depth))
763                 return False;
764
765         return True;
766 }
767
768 /*******************************************************************
769  Reads or writes a structure.
770 ********************************************************************/
771
772 BOOL net_io_r_auth(const char *desc, NET_R_AUTH *r_a, prs_struct *ps, int depth)
773 {
774         if (r_a == NULL)
775                 return False;
776
777         prs_debug(ps, depth, desc, "net_io_r_auth");
778         depth++;
779
780         if(!prs_align(ps))
781                 return False;
782     
783         if(!smb_io_chal("", &r_a->srv_chal, ps, depth)) /* server challenge */
784                 return False;
785
786         if(!prs_ntstatus("status", ps, depth, &r_a->status))
787                 return False;
788
789         return True;
790 }
791
792 /*******************************************************************
793  Inits a NET_Q_AUTH_2 struct.
794 ********************************************************************/
795
796 void init_q_auth_2(NET_Q_AUTH_2 *q_a,
797                 const char *logon_srv, const char *acct_name, uint16 sec_chan, const char *comp_name,
798                 const DOM_CHAL *clnt_chal, uint32 clnt_flgs)
799 {
800         DEBUG(5,("init_q_auth_2: %d\n", __LINE__));
801
802         init_log_info(&q_a->clnt_id, logon_srv, acct_name, sec_chan, comp_name);
803         memcpy(q_a->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data));
804         q_a->clnt_flgs.neg_flags = clnt_flgs;
805
806         DEBUG(5,("init_q_auth_2: %d\n", __LINE__));
807 }
808
809 /*******************************************************************
810  Reads or writes a structure.
811 ********************************************************************/
812
813 BOOL net_io_q_auth_2(const char *desc, NET_Q_AUTH_2 *q_a, prs_struct *ps, int depth)
814 {
815         if (q_a == NULL)
816                 return False;
817
818         prs_debug(ps, depth, desc, "net_io_q_auth_2");
819         depth++;
820
821         if(!prs_align(ps))
822                 return False;
823     
824         if(!smb_io_log_info ("", &q_a->clnt_id, ps, depth)) /* client identification info */
825                 return False;
826         if(!smb_io_chal("", &q_a->clnt_chal, ps, depth))
827                 return False;
828         if(!net_io_neg_flags("", &q_a->clnt_flgs, ps, depth))
829                 return False;
830
831         return True;
832 }
833
834 /*******************************************************************
835  Reads or writes a structure.
836 ********************************************************************/
837
838 BOOL net_io_r_auth_2(const char *desc, NET_R_AUTH_2 *r_a, prs_struct *ps, int depth)
839 {
840         if (r_a == NULL)
841                 return False;
842
843         prs_debug(ps, depth, desc, "net_io_r_auth_2");
844         depth++;
845
846         if(!prs_align(ps))
847                 return False;
848     
849         if(!smb_io_chal("", &r_a->srv_chal, ps, depth)) /* server challenge */
850                 return False;
851         if(!net_io_neg_flags("", &r_a->srv_flgs, ps, depth))
852                 return False;
853
854         if(!prs_ntstatus("status", ps, depth, &r_a->status))
855                 return False;
856
857         return True;
858 }
859
860 /*******************************************************************
861  Inits a NET_Q_AUTH_3 struct.
862 ********************************************************************/
863
864 void init_q_auth_3(NET_Q_AUTH_3 *q_a,
865                 const char *logon_srv, const char *acct_name, uint16 sec_chan, const char *comp_name,
866                 const DOM_CHAL *clnt_chal, uint32 clnt_flgs)
867 {
868         DEBUG(5,("init_q_auth_3: %d\n", __LINE__));
869
870         init_log_info(&q_a->clnt_id, logon_srv, acct_name, sec_chan, comp_name);
871         memcpy(q_a->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data));
872         q_a->clnt_flgs.neg_flags = clnt_flgs;
873
874         DEBUG(5,("init_q_auth_3: %d\n", __LINE__));
875 }
876
877 /*******************************************************************
878  Reads or writes a structure.
879 ********************************************************************/
880
881 BOOL net_io_q_auth_3(const char *desc, NET_Q_AUTH_3 *q_a, prs_struct *ps, int depth)
882 {
883         if (q_a == NULL)
884                 return False;
885
886         prs_debug(ps, depth, desc, "net_io_q_auth_3");
887         depth++;
888
889         if(!prs_align(ps))
890                 return False;
891     
892         if(!smb_io_log_info ("", &q_a->clnt_id, ps, depth)) /* client identification info */
893                 return False;
894         if(!smb_io_chal("", &q_a->clnt_chal, ps, depth))
895                 return False;
896         if(!net_io_neg_flags("", &q_a->clnt_flgs, ps, depth))
897                 return False;
898
899         return True;
900 }
901
902 /*******************************************************************
903  Reads or writes a structure.
904 ********************************************************************/
905
906 BOOL net_io_r_auth_3(const char *desc, NET_R_AUTH_3 *r_a, prs_struct *ps, int depth)
907 {
908         if (r_a == NULL)
909                 return False;
910
911         prs_debug(ps, depth, desc, "net_io_r_auth_3");
912         depth++;
913
914         if(!prs_align(ps))
915                 return False;
916     
917         if(!smb_io_chal("srv_chal", &r_a->srv_chal, ps, depth)) /* server challenge */
918                 return False;
919         if(!net_io_neg_flags("srv_flgs", &r_a->srv_flgs, ps, depth))
920                 return False;
921         if (!prs_uint32("unknown", ps, depth, &r_a->unknown))
922                 return False;
923
924         if(!prs_ntstatus("status", ps, depth, &r_a->status))
925                 return False;
926
927         return True;
928 }
929
930
931 /*******************************************************************
932  Inits a NET_Q_SRV_PWSET.
933 ********************************************************************/
934
935 void init_q_srv_pwset(NET_Q_SRV_PWSET *q_s,
936                 const char *logon_srv, const char *sess_key, const char *acct_name, 
937                 uint16 sec_chan, const char *comp_name,
938                 DOM_CRED *cred, const uchar hashed_mach_pwd[16])
939 {
940         unsigned char nt_cypher[16];
941         
942         DEBUG(5,("init_q_srv_pwset\n"));
943         
944         /* Process the new password. */
945         cred_hash3( nt_cypher, hashed_mach_pwd, (const unsigned char *)sess_key, 1);
946
947         init_clnt_info(&q_s->clnt_id, logon_srv, acct_name, sec_chan, comp_name, cred);
948
949         memcpy(q_s->pwd, nt_cypher, sizeof(q_s->pwd)); 
950 }
951
952 /*******************************************************************
953  Reads or writes a structure.
954 ********************************************************************/
955
956 BOOL net_io_q_srv_pwset(const char *desc, NET_Q_SRV_PWSET *q_s, prs_struct *ps, int depth)
957 {
958         if (q_s == NULL)
959                 return False;
960
961         prs_debug(ps, depth, desc, "net_io_q_srv_pwset");
962         depth++;
963
964         if(!prs_align(ps))
965                 return False;
966     
967         if(!smb_io_clnt_info("", &q_s->clnt_id, ps, depth)) /* client identification/authentication info */
968                 return False;
969         if(!prs_uint8s (False, "pwd", ps, depth, q_s->pwd, 16)) /* new password - undocumented */
970                 return False;
971
972         return True;
973 }
974
975 /*******************************************************************
976  Reads or writes a structure.
977 ********************************************************************/
978
979 BOOL net_io_r_srv_pwset(const char *desc, NET_R_SRV_PWSET *r_s, prs_struct *ps, int depth)
980 {
981         if (r_s == NULL)
982                 return False;
983
984         prs_debug(ps, depth, desc, "net_io_r_srv_pwset");
985         depth++;
986
987         if(!prs_align(ps))
988                 return False;
989     
990         if(!smb_io_cred("", &r_s->srv_cred, ps, depth)) /* server challenge */
991                 return False;
992
993         if(!prs_ntstatus("status", ps, depth, &r_s->status))
994                 return False;
995
996         return True;
997 }
998
999 /*************************************************************************
1000  Init DOM_SID2 array from a string containing multiple sids
1001  *************************************************************************/
1002
1003 static int init_dom_sid2s(TALLOC_CTX *ctx, const char *sids_str, DOM_SID2 **ppsids)
1004 {
1005         const char *ptr;
1006         pstring s2;
1007         int count = 0;
1008
1009         DEBUG(4,("init_dom_sid2s: %s\n", sids_str ? sids_str:""));
1010
1011         *ppsids = NULL;
1012
1013         if(sids_str) {
1014                 int number;
1015                 DOM_SID2 *sids;
1016
1017                 /* Count the number of valid SIDs. */
1018                 for (count = 0, ptr = sids_str; next_token(&ptr, s2, NULL, sizeof(s2)); ) {
1019                         DOM_SID tmpsid;
1020                         if (string_to_sid(&tmpsid, s2))
1021                                 count++;
1022                 }
1023
1024                 /* Now allocate space for them. */
1025                 *ppsids = TALLOC_ZERO_ARRAY(ctx, DOM_SID2, count);
1026                 if (*ppsids == NULL)
1027                         return 0;
1028
1029                 sids = *ppsids;
1030
1031                 for (number = 0, ptr = sids_str; next_token(&ptr, s2, NULL, sizeof(s2)); ) {
1032                         DOM_SID tmpsid;
1033                         if (string_to_sid(&tmpsid, s2)) {
1034                                 /* count only valid sids */
1035                                 init_dom_sid2(&sids[number], &tmpsid);
1036                                 number++;
1037                         }
1038                 }
1039         }
1040
1041         return count;
1042 }
1043
1044 /*******************************************************************
1045  Inits a NET_ID_INFO_1 structure.
1046 ********************************************************************/
1047
1048 void init_id_info1(NET_ID_INFO_1 *id, const char *domain_name,
1049                                 uint32 param_ctrl, uint32 log_id_low, uint32 log_id_high,
1050                                 const char *user_name, const char *wksta_name,
1051                                 const char *sess_key,
1052                                 unsigned char lm_cypher[16], unsigned char nt_cypher[16])
1053 {
1054         unsigned char lm_owf[16];
1055         unsigned char nt_owf[16];
1056
1057         DEBUG(5,("init_id_info1: %d\n", __LINE__));
1058
1059         id->ptr_id_info1 = 1;
1060
1061         id->param_ctrl = param_ctrl;
1062         init_logon_id(&id->logon_id, log_id_low, log_id_high);
1063
1064
1065         if (lm_cypher && nt_cypher) {
1066                 unsigned char key[16];
1067 #ifdef DEBUG_PASSWORD
1068                 DEBUG(100,("lm cypher:"));
1069                 dump_data(100, (char *)lm_cypher, 16);
1070
1071                 DEBUG(100,("nt cypher:"));
1072                 dump_data(100, (char *)nt_cypher, 16);
1073 #endif
1074
1075                 memset(key, 0, 16);
1076                 memcpy(key, sess_key, 8);
1077
1078                 memcpy(lm_owf, lm_cypher, 16);
1079                 SamOEMhash(lm_owf, key, 16);
1080                 memcpy(nt_owf, nt_cypher, 16);
1081                 SamOEMhash(nt_owf, key, 16);
1082
1083 #ifdef DEBUG_PASSWORD
1084                 DEBUG(100,("encrypt of lm owf password:"));
1085                 dump_data(100, (char *)lm_owf, 16);
1086
1087                 DEBUG(100,("encrypt of nt owf password:"));
1088                 dump_data(100, (char *)nt_owf, 16);
1089 #endif
1090                 /* set up pointers to cypher blocks */
1091                 lm_cypher = lm_owf;
1092                 nt_cypher = nt_owf;
1093         }
1094
1095         init_owf_info(&id->lm_owf, lm_cypher);
1096         init_owf_info(&id->nt_owf, nt_cypher);
1097
1098         init_unistr2(&id->uni_domain_name, domain_name, UNI_FLAGS_NONE);
1099         init_uni_hdr(&id->hdr_domain_name, &id->uni_domain_name);
1100         init_unistr2(&id->uni_user_name, user_name, UNI_FLAGS_NONE);
1101         init_uni_hdr(&id->hdr_user_name, &id->uni_user_name);
1102         init_unistr2(&id->uni_wksta_name, wksta_name, UNI_FLAGS_NONE);
1103         init_uni_hdr(&id->hdr_wksta_name, &id->uni_wksta_name);
1104 }
1105
1106 /*******************************************************************
1107  Reads or writes an NET_ID_INFO_1 structure.
1108 ********************************************************************/
1109
1110 static BOOL net_io_id_info1(const char *desc,  NET_ID_INFO_1 *id, prs_struct *ps, int depth)
1111 {
1112         if (id == NULL)
1113                 return False;
1114
1115         prs_debug(ps, depth, desc, "net_io_id_info1");
1116         depth++;
1117
1118         if(!prs_align(ps))
1119                 return False;
1120         
1121         if(!prs_uint32("ptr_id_info1", ps, depth, &id->ptr_id_info1))
1122                 return False;
1123
1124         if (id->ptr_id_info1 != 0) {
1125                 if(!smb_io_unihdr("unihdr", &id->hdr_domain_name, ps, depth))
1126                         return False;
1127
1128                 if(!prs_uint32("param_ctrl", ps, depth, &id->param_ctrl))
1129                         return False;
1130                 if(!smb_io_logon_id("", &id->logon_id, ps, depth))
1131                         return False;
1132
1133                 if(!smb_io_unihdr("unihdr", &id->hdr_user_name, ps, depth))
1134                         return False;
1135                 if(!smb_io_unihdr("unihdr", &id->hdr_wksta_name, ps, depth))
1136                         return False;
1137
1138                 if(!smb_io_owf_info("", &id->lm_owf, ps, depth))
1139                         return False;
1140                 if(!smb_io_owf_info("", &id->nt_owf, ps, depth))
1141                         return False;
1142
1143                 if(!smb_io_unistr2("unistr2", &id->uni_domain_name,
1144                                 id->hdr_domain_name.buffer, ps, depth))
1145                         return False;
1146                 if(!smb_io_unistr2("unistr2", &id->uni_user_name,
1147                                 id->hdr_user_name.buffer, ps, depth))
1148                         return False;
1149                 if(!smb_io_unistr2("unistr2", &id->uni_wksta_name,
1150                                 id->hdr_wksta_name.buffer, ps, depth))
1151                         return False;
1152         }
1153
1154         return True;
1155 }
1156
1157 /*******************************************************************
1158 Inits a NET_ID_INFO_2 structure.
1159
1160 This is a network logon packet. The log_id parameters
1161 are what an NT server would generate for LUID once the
1162 user is logged on. I don't think we care about them.
1163
1164 Note that this has no access to the NT and LM hashed passwords,
1165 so it forwards the challenge, and the NT and LM responses (24
1166 bytes each) over the secure channel to the Domain controller
1167 for it to say yea or nay. This is the preferred method of 
1168 checking for a logon as it doesn't export the password
1169 hashes to anyone who has compromised the secure channel. JRA.
1170 ********************************************************************/
1171
1172 void init_id_info2(NET_ID_INFO_2 * id, const char *domain_name,
1173                    uint32 param_ctrl,
1174                    uint32 log_id_low, uint32 log_id_high,
1175                    const char *user_name, const char *wksta_name,
1176                    const uchar lm_challenge[8],
1177                    const uchar * lm_chal_resp, size_t lm_chal_resp_len,
1178                    const uchar * nt_chal_resp, size_t nt_chal_resp_len)
1179 {
1180
1181         DEBUG(5,("init_id_info2: %d\n", __LINE__));
1182
1183         id->ptr_id_info2 = 1;
1184
1185         id->param_ctrl = param_ctrl;
1186         init_logon_id(&id->logon_id, log_id_low, log_id_high);
1187
1188         memcpy(id->lm_chal, lm_challenge, sizeof(id->lm_chal));
1189         init_str_hdr(&id->hdr_nt_chal_resp, nt_chal_resp_len, nt_chal_resp_len, (nt_chal_resp != NULL) ? 1 : 0);
1190         init_str_hdr(&id->hdr_lm_chal_resp, lm_chal_resp_len, lm_chal_resp_len, (lm_chal_resp != NULL) ? 1 : 0);
1191
1192         init_unistr2(&id->uni_domain_name, domain_name, UNI_FLAGS_NONE);
1193         init_uni_hdr(&id->hdr_domain_name, &id->uni_domain_name);
1194         init_unistr2(&id->uni_user_name, user_name, UNI_FLAGS_NONE);
1195         init_uni_hdr(&id->hdr_user_name, &id->uni_user_name);
1196         init_unistr2(&id->uni_wksta_name, wksta_name, UNI_FLAGS_NONE);
1197         init_uni_hdr(&id->hdr_wksta_name, &id->uni_wksta_name);
1198
1199         init_string2(&id->nt_chal_resp, (const char *)nt_chal_resp, nt_chal_resp_len, nt_chal_resp_len);
1200         init_string2(&id->lm_chal_resp, (const char *)lm_chal_resp, lm_chal_resp_len, lm_chal_resp_len);
1201
1202 }
1203
1204 /*******************************************************************
1205  Reads or writes an NET_ID_INFO_2 structure.
1206 ********************************************************************/
1207
1208 static BOOL net_io_id_info2(const char *desc,  NET_ID_INFO_2 *id, prs_struct *ps, int depth)
1209 {
1210         if (id == NULL)
1211                 return False;
1212
1213         prs_debug(ps, depth, desc, "net_io_id_info2");
1214         depth++;
1215
1216         if(!prs_align(ps))
1217                 return False;
1218         
1219         if(!prs_uint32("ptr_id_info2", ps, depth, &id->ptr_id_info2))
1220                 return False;
1221
1222         if (id->ptr_id_info2 != 0) {
1223                 if(!smb_io_unihdr("unihdr", &id->hdr_domain_name, ps, depth))
1224                         return False;
1225
1226                 if(!prs_uint32("param_ctrl", ps, depth, &id->param_ctrl))
1227                         return False;
1228                 if(!smb_io_logon_id("", &id->logon_id, ps, depth))
1229                         return False;
1230
1231                 if(!smb_io_unihdr("unihdr", &id->hdr_user_name, ps, depth))
1232                         return False;
1233                 if(!smb_io_unihdr("unihdr", &id->hdr_wksta_name, ps, depth))
1234                         return False;
1235
1236                 if(!prs_uint8s (False, "lm_chal", ps, depth, id->lm_chal, 8)) /* lm 8 byte challenge */
1237                         return False;
1238
1239                 if(!smb_io_strhdr("hdr_nt_chal_resp", &id->hdr_nt_chal_resp, ps, depth))
1240                         return False;
1241                 if(!smb_io_strhdr("hdr_lm_chal_resp", &id->hdr_lm_chal_resp, ps, depth))
1242                         return False;
1243
1244                 if(!smb_io_unistr2("uni_domain_name", &id->uni_domain_name,
1245                                 id->hdr_domain_name.buffer, ps, depth))
1246                         return False;
1247                 if(!smb_io_unistr2("uni_user_name  ", &id->uni_user_name,
1248                                 id->hdr_user_name.buffer, ps, depth))
1249                         return False;
1250                 if(!smb_io_unistr2("uni_wksta_name ", &id->uni_wksta_name,
1251                                 id->hdr_wksta_name.buffer, ps, depth))
1252                         return False;
1253                 if(!smb_io_string2("nt_chal_resp", &id->nt_chal_resp,
1254                                 id->hdr_nt_chal_resp.buffer, ps, depth))
1255                         return False;
1256                 if(!smb_io_string2("lm_chal_resp", &id->lm_chal_resp,
1257                                 id->hdr_lm_chal_resp.buffer, ps, depth))
1258                         return False;
1259         }
1260
1261         return True;
1262 }
1263
1264
1265 /*******************************************************************
1266  Inits a DOM_SAM_INFO structure.
1267 ********************************************************************/
1268
1269 void init_sam_info(DOM_SAM_INFO *sam,
1270                                 const char *logon_srv, const char *comp_name,
1271                                 DOM_CRED *clnt_cred,
1272                                 DOM_CRED *rtn_cred, uint16 logon_level,
1273                                 NET_ID_INFO_CTR *ctr)
1274 {
1275         DEBUG(5,("init_sam_info: %d\n", __LINE__));
1276
1277         init_clnt_info2(&sam->client, logon_srv, comp_name, clnt_cred);
1278
1279         if (rtn_cred != NULL) {
1280                 sam->ptr_rtn_cred = 1;
1281                 memcpy(&sam->rtn_cred, rtn_cred, sizeof(sam->rtn_cred));
1282         } else {
1283                 sam->ptr_rtn_cred = 0;
1284         }
1285
1286         sam->logon_level  = logon_level;
1287         sam->ctr          = ctr;
1288 }
1289
1290 /*******************************************************************
1291  Reads or writes a DOM_SAM_INFO structure.
1292 ********************************************************************/
1293
1294 static BOOL net_io_id_info_ctr(const char *desc, NET_ID_INFO_CTR **pp_ctr, prs_struct *ps, int depth)
1295 {
1296         NET_ID_INFO_CTR *ctr = *pp_ctr;
1297
1298         prs_debug(ps, depth, desc, "smb_io_sam_info");
1299         depth++;
1300
1301         if (UNMARSHALLING(ps)) {
1302                 ctr = *pp_ctr = PRS_ALLOC_MEM(ps, NET_ID_INFO_CTR, 1);
1303                 if (ctr == NULL)
1304                         return False;
1305         }
1306         
1307         if (ctr == NULL)
1308                 return False;
1309
1310         /* don't 4-byte align here! */
1311
1312         if(!prs_uint16("switch_value ", ps, depth, &ctr->switch_value))
1313                 return False;
1314
1315         switch (ctr->switch_value) {
1316         case 1:
1317                 if(!net_io_id_info1("", &ctr->auth.id1, ps, depth))
1318                         return False;
1319                 break;
1320         case 2:
1321                 if(!net_io_id_info2("", &ctr->auth.id2, ps, depth))
1322                         return False;
1323                 break;
1324         default:
1325                 /* PANIC! */
1326                 DEBUG(4,("smb_io_sam_info: unknown switch_value!\n"));
1327                 break;
1328         }
1329
1330         return True;
1331 }
1332
1333 /*******************************************************************
1334  Reads or writes a DOM_SAM_INFO structure.
1335  ********************************************************************/
1336
1337 static BOOL smb_io_sam_info(const char *desc, DOM_SAM_INFO *sam, prs_struct *ps, int depth)
1338 {
1339         if (sam == NULL)
1340                 return False;
1341
1342         prs_debug(ps, depth, desc, "smb_io_sam_info");
1343         depth++;
1344
1345         if(!prs_align(ps))
1346                 return False;
1347         
1348         if(!smb_io_clnt_info2("", &sam->client, ps, depth))
1349                 return False;
1350
1351         if(!prs_uint32("ptr_rtn_cred ", ps, depth, &sam->ptr_rtn_cred))
1352                 return False;
1353         if(!smb_io_cred("", &sam->rtn_cred, ps, depth))
1354                 return False;
1355
1356         if(!prs_uint16("logon_level  ", ps, depth, &sam->logon_level))
1357                 return False;
1358
1359         if (sam->logon_level != 0) {
1360                 if(!net_io_id_info_ctr("logon_info", &sam->ctr, ps, depth))
1361                         return False;
1362         }
1363
1364         return True;
1365 }
1366
1367 /*************************************************************************
1368  Inits a NET_USER_INFO_3 structure.
1369
1370  This is a network logon reply packet, and contains much information about
1371  the user.  This information is passed as a (very long) paramater list
1372  to avoid having to link in the PASSDB code to every program that deals 
1373  with this file.
1374  *************************************************************************/
1375
1376 void init_net_user_info3(TALLOC_CTX *ctx, NET_USER_INFO_3 *usr, 
1377                          uint32                user_rid,
1378                          uint32                group_rid,
1379
1380                          const char*            user_name,
1381                          const char*            full_name,
1382                          const char*            home_dir,
1383                          const char*            dir_drive,
1384                          const char*            logon_script,
1385                          const char*            profile_path,
1386
1387                          time_t unix_logon_time,
1388                          time_t unix_logoff_time,
1389                          time_t unix_kickoff_time,
1390                          time_t unix_pass_last_set_time,
1391                          time_t unix_pass_can_change_time,
1392                          time_t unix_pass_must_change_time,
1393                          
1394                          uint16 logon_count, uint16 bad_pw_count,
1395                          uint32 num_groups, const DOM_GID *gids,
1396                          uint32 user_flgs, uchar user_session_key[16],
1397                          uchar lm_session_key[16],
1398                          const char *logon_srv, const char *logon_dom,
1399                          const DOM_SID *dom_sid, const char *other_sids)
1400 {
1401         /* only cope with one "other" sid, right now. */
1402         /* need to count the number of space-delimited sids */
1403         unsigned int i;
1404         int num_other_sids = 0;
1405         
1406         NTTIME          logon_time, logoff_time, kickoff_time,
1407                         pass_last_set_time, pass_can_change_time,
1408                         pass_must_change_time;
1409
1410         ZERO_STRUCTP(usr);
1411
1412         usr->ptr_user_info = 1; /* yes, we're bothering to put USER_INFO data here */
1413
1414         /* Create NTTIME structs */
1415         unix_to_nt_time (&logon_time,            unix_logon_time);
1416         unix_to_nt_time (&logoff_time,           unix_logoff_time);
1417         unix_to_nt_time (&kickoff_time,          unix_kickoff_time);
1418         unix_to_nt_time (&pass_last_set_time,    unix_pass_last_set_time);
1419         unix_to_nt_time (&pass_can_change_time,  unix_pass_can_change_time);
1420         unix_to_nt_time (&pass_must_change_time, unix_pass_must_change_time);
1421
1422         usr->logon_time            = logon_time;
1423         usr->logoff_time           = logoff_time;
1424         usr->kickoff_time          = kickoff_time;
1425         usr->pass_last_set_time    = pass_last_set_time;
1426         usr->pass_can_change_time  = pass_can_change_time;
1427         usr->pass_must_change_time = pass_must_change_time;
1428
1429         usr->logon_count = logon_count;
1430         usr->bad_pw_count = bad_pw_count;
1431
1432         usr->user_rid = user_rid;
1433         usr->group_rid = group_rid;
1434         usr->num_groups = num_groups;
1435
1436         usr->buffer_groups = 1; /* indicates fill in groups, below, even if there are none */
1437         usr->user_flgs = user_flgs;
1438
1439         if (user_session_key != NULL)
1440                 memcpy(usr->user_sess_key, user_session_key, sizeof(usr->user_sess_key));
1441         else
1442                 memset((char *)usr->user_sess_key, '\0', sizeof(usr->user_sess_key));
1443
1444         usr->buffer_dom_id = dom_sid ? 1 : 0; /* yes, we're bothering to put a domain SID in */
1445
1446         memset((char *)usr->lm_sess_key, '\0', sizeof(usr->lm_sess_key));
1447         memset(&usr->acct_flags, '\0', sizeof(usr->acct_flags));
1448
1449         for (i=0; i<7; i++) {
1450                 memset(&usr->unknown[i], '\0', sizeof(usr->unknown));
1451         }
1452
1453         if (lm_session_key != NULL) {
1454                 memcpy(usr->lm_sess_key, lm_session_key, sizeof(usr->lm_sess_key));
1455         }
1456
1457         num_other_sids = init_dom_sid2s(ctx, other_sids, &usr->other_sids);
1458
1459         usr->num_other_sids = num_other_sids;
1460         usr->buffer_other_sids = (num_other_sids != 0) ? 1 : 0; 
1461         
1462         init_unistr2(&usr->uni_user_name, user_name, UNI_FLAGS_NONE);
1463         init_uni_hdr(&usr->hdr_user_name, &usr->uni_user_name);
1464         init_unistr2(&usr->uni_full_name, full_name, UNI_FLAGS_NONE);
1465         init_uni_hdr(&usr->hdr_full_name, &usr->uni_full_name);
1466         init_unistr2(&usr->uni_logon_script, logon_script, UNI_FLAGS_NONE);
1467         init_uni_hdr(&usr->hdr_logon_script, &usr->uni_logon_script);
1468         init_unistr2(&usr->uni_profile_path, profile_path, UNI_FLAGS_NONE);
1469         init_uni_hdr(&usr->hdr_profile_path, &usr->uni_profile_path);
1470         init_unistr2(&usr->uni_home_dir, home_dir, UNI_FLAGS_NONE);
1471         init_uni_hdr(&usr->hdr_home_dir, &usr->uni_home_dir);
1472         init_unistr2(&usr->uni_dir_drive, dir_drive, UNI_FLAGS_NONE);
1473         init_uni_hdr(&usr->hdr_dir_drive, &usr->uni_dir_drive);
1474
1475         usr->num_groups2 = num_groups;
1476
1477         usr->gids = TALLOC_ZERO_ARRAY(ctx,DOM_GID,num_groups);
1478         if (usr->gids == NULL && num_groups>0)
1479                 return;
1480
1481         for (i = 0; i < num_groups; i++) 
1482                 usr->gids[i] = gids[i]; 
1483                 
1484         init_unistr2(&usr->uni_logon_srv, logon_srv, UNI_FLAGS_NONE);
1485         init_uni_hdr(&usr->hdr_logon_srv, &usr->uni_logon_srv);
1486         init_unistr2(&usr->uni_logon_dom, logon_dom, UNI_FLAGS_NONE);
1487         init_uni_hdr(&usr->hdr_logon_dom, &usr->uni_logon_dom);
1488
1489         init_dom_sid2(&usr->dom_sid, dom_sid);
1490         /* "other" sids are set up above */
1491 }
1492
1493 /*******************************************************************
1494  This code has been modified to cope with a NET_USER_INFO_2 - which is
1495  exactly the same as a NET_USER_INFO_3, minus the other sids parameters.
1496  We use validation level to determine if we're marshalling a info 2 or
1497  INFO_3 - be we always return an INFO_3. Based on code donated by Marc
1498  Jacobsen at HP. JRA.
1499 ********************************************************************/
1500
1501 BOOL net_io_user_info3(const char *desc, NET_USER_INFO_3 *usr, prs_struct *ps, 
1502                        int depth, uint16 validation_level, BOOL kerb_validation_level)
1503 {
1504         unsigned int i;
1505
1506         if (usr == NULL)
1507                 return False;
1508
1509         prs_debug(ps, depth, desc, "net_io_user_info3");
1510         depth++;
1511
1512         if (UNMARSHALLING(ps))
1513                 ZERO_STRUCTP(usr);
1514
1515         if(!prs_align(ps))
1516                 return False;
1517         
1518         if(!prs_uint32("ptr_user_info ", ps, depth, &usr->ptr_user_info))
1519                 return False;
1520
1521         if (usr->ptr_user_info == 0)
1522                 return True;
1523
1524         if(!smb_io_time("logon time", &usr->logon_time, ps, depth)) /* logon time */
1525                 return False;
1526         if(!smb_io_time("logoff time", &usr->logoff_time, ps, depth)) /* logoff time */
1527                 return False;
1528         if(!smb_io_time("kickoff time", &usr->kickoff_time, ps, depth)) /* kickoff time */
1529                 return False;
1530         if(!smb_io_time("last set time", &usr->pass_last_set_time, ps, depth)) /* password last set time */
1531                 return False;
1532         if(!smb_io_time("can change time", &usr->pass_can_change_time , ps, depth)) /* password can change time */
1533                 return False;
1534         if(!smb_io_time("must change time", &usr->pass_must_change_time, ps, depth)) /* password must change time */
1535                 return False;
1536
1537         if(!smb_io_unihdr("hdr_user_name", &usr->hdr_user_name, ps, depth)) /* username unicode string header */
1538                 return False;
1539         if(!smb_io_unihdr("hdr_full_name", &usr->hdr_full_name, ps, depth)) /* user's full name unicode string header */
1540                 return False;
1541         if(!smb_io_unihdr("hdr_logon_script", &usr->hdr_logon_script, ps, depth)) /* logon script unicode string header */
1542                 return False;
1543         if(!smb_io_unihdr("hdr_profile_path", &usr->hdr_profile_path, ps, depth)) /* profile path unicode string header */
1544                 return False;
1545         if(!smb_io_unihdr("hdr_home_dir", &usr->hdr_home_dir, ps, depth)) /* home directory unicode string header */
1546                 return False;
1547         if(!smb_io_unihdr("hdr_dir_drive", &usr->hdr_dir_drive, ps, depth)) /* home directory drive unicode string header */
1548                 return False;
1549
1550         if(!prs_uint16("logon_count   ", ps, depth, &usr->logon_count))  /* logon count */
1551                 return False;
1552         if(!prs_uint16("bad_pw_count  ", ps, depth, &usr->bad_pw_count)) /* bad password count */
1553                 return False;
1554
1555         if(!prs_uint32("user_rid      ", ps, depth, &usr->user_rid))       /* User RID */
1556                 return False;
1557         if(!prs_uint32("group_rid     ", ps, depth, &usr->group_rid))      /* Group RID */
1558                 return False;
1559         if(!prs_uint32("num_groups    ", ps, depth, &usr->num_groups))    /* num groups */
1560                 return False;
1561         if(!prs_uint32("buffer_groups ", ps, depth, &usr->buffer_groups)) /* undocumented buffer pointer to groups. */
1562                 return False;
1563         if(!prs_uint32("user_flgs     ", ps, depth, &usr->user_flgs))     /* user flags */
1564                 return False;
1565
1566         if(!prs_uint8s(False, "user_sess_key", ps, depth, usr->user_sess_key, 16)) /* user session key */
1567                 return False;
1568
1569         if(!smb_io_unihdr("hdr_logon_srv", &usr->hdr_logon_srv, ps, depth)) /* logon server unicode string header */
1570                 return False;
1571         if(!smb_io_unihdr("hdr_logon_dom", &usr->hdr_logon_dom, ps, depth)) /* logon domain unicode string header */
1572                 return False;
1573
1574         if(!prs_uint32("buffer_dom_id ", ps, depth, &usr->buffer_dom_id)) /* undocumented logon domain id pointer */
1575                 return False;
1576
1577         if(!prs_uint8s(False, "lm_sess_key", ps, depth, usr->lm_sess_key, 8)) /* lm session key */
1578                 return False;
1579
1580         if(!prs_uint32("acct_flags ", ps, depth, &usr->acct_flags)) /* Account flags  */
1581                 return False;
1582
1583         for (i = 0; i < 7; i++)
1584         {
1585                 if (!prs_uint32("unkown", ps, depth, &usr->unknown[i])) /* unknown */
1586                         return False;
1587         }
1588
1589         if (validation_level == 3) {
1590                 if(!prs_uint32("num_other_sids", ps, depth, &usr->num_other_sids)) /* 0 - num_sids */
1591                         return False;
1592                 if(!prs_uint32("buffer_other_sids", ps, depth, &usr->buffer_other_sids)) /* NULL - undocumented pointer to SIDs. */
1593                         return False;
1594         } else {
1595                 if (UNMARSHALLING(ps)) {
1596                         usr->num_other_sids = 0;
1597                         usr->buffer_other_sids = 0;
1598                 }
1599         }
1600                 
1601         /* get kerb validation info (not really part of user_info_3) - Guenther */
1602
1603         if (kerb_validation_level) {
1604
1605                 if(!prs_uint32("ptr_res_group_dom_sid", ps, depth, &usr->ptr_res_group_dom_sid))
1606                         return False;
1607                 if(!prs_uint32("res_group_count", ps, depth, &usr->res_group_count))
1608                         return False;
1609                 if(!prs_uint32("ptr_res_groups", ps, depth, &usr->ptr_res_groups))
1610                         return False;
1611         }
1612
1613         if(!smb_io_unistr2("uni_user_name", &usr->uni_user_name, usr->hdr_user_name.buffer, ps, depth)) /* username unicode string */
1614                 return False;
1615         if(!smb_io_unistr2("uni_full_name", &usr->uni_full_name, usr->hdr_full_name.buffer, ps, depth)) /* user's full name unicode string */
1616                 return False;
1617         if(!smb_io_unistr2("uni_logon_script", &usr->uni_logon_script, usr->hdr_logon_script.buffer, ps, depth)) /* logon script unicode string */
1618                 return False;
1619         if(!smb_io_unistr2("uni_profile_path", &usr->uni_profile_path, usr->hdr_profile_path.buffer, ps, depth)) /* profile path unicode string */
1620                 return False;
1621         if(!smb_io_unistr2("uni_home_dir", &usr->uni_home_dir, usr->hdr_home_dir.buffer, ps, depth)) /* home directory unicode string */
1622                 return False;
1623         if(!smb_io_unistr2("uni_dir_drive", &usr->uni_dir_drive, usr->hdr_dir_drive.buffer, ps, depth)) /* home directory drive unicode string */
1624                 return False;
1625
1626         if(!prs_align(ps))
1627                 return False;
1628
1629         if (usr->num_groups > 0) {
1630
1631                 if(!prs_uint32("num_groups2   ", ps, depth, &usr->num_groups2))        /* num groups2 */
1632                         return False;
1633
1634                 if (usr->num_groups != usr->num_groups2) {
1635                         DEBUG(3,("net_io_user_info3: num_groups mismatch! (%d != %d)\n", 
1636                         usr->num_groups, usr->num_groups2));
1637                         return False;
1638                 }
1639
1640
1641                 if (UNMARSHALLING(ps)) {
1642                         usr->gids = PRS_ALLOC_MEM(ps, DOM_GID, usr->num_groups);
1643                         if (usr->gids == NULL)
1644                                 return False;
1645                 }
1646
1647                 for (i = 0; i < usr->num_groups; i++) {
1648                         if(!smb_io_gid("", &usr->gids[i], ps, depth)) /* group info */
1649                                 return False;
1650                 }
1651                 
1652         }
1653
1654         if(!smb_io_unistr2("uni_logon_srv", &usr->uni_logon_srv, usr->hdr_logon_srv.buffer, ps, depth)) /* logon server unicode string */
1655                 return False;
1656         if(!smb_io_unistr2("uni_logon_dom", &usr->uni_logon_dom, usr->hdr_logon_dom.buffer, ps, depth)) /* logon domain unicode string */
1657                 return False;
1658
1659         if(!smb_io_dom_sid2("", &usr->dom_sid, ps, depth))           /* domain SID */
1660                 return False;
1661
1662         if (usr->buffer_other_sids) {
1663
1664                 uint32 num_other_sids = usr->num_other_sids;
1665
1666                 if (!(usr->user_flgs & LOGON_EXTRA_SIDS)) {
1667                         DEBUG(10,("net_io_user_info3: user_flgs attribute does not have LOGON_EXTRA_SIDS\n"));
1668                         /* return False; */
1669                 }
1670
1671                 if (!prs_uint32("num_other_sids", ps, depth,
1672                                 &num_other_sids))
1673                         return False;
1674
1675                 if (num_other_sids != usr->num_other_sids)
1676                         return False;
1677
1678                 if (UNMARSHALLING(ps)) {
1679                         usr->other_sids = PRS_ALLOC_MEM(ps, DOM_SID2, usr->num_other_sids);
1680                         usr->other_sids_attrib =
1681                                 PRS_ALLOC_MEM(ps, uint32, usr->num_other_sids);
1682                                                                
1683                         if ((num_other_sids != 0) &&
1684                             ((usr->other_sids == NULL) ||
1685                              (usr->other_sids_attrib == NULL)))
1686                                 return False;
1687                 }
1688
1689                 /* First the pointers to the SIDS and attributes */
1690
1691                 depth++;
1692
1693                 for (i=0; i<usr->num_other_sids; i++) {
1694                         uint32 ptr = 1;
1695
1696                         if (!prs_uint32("sid_ptr", ps, depth, &ptr))
1697                                 return False;
1698
1699                         if (UNMARSHALLING(ps) && (ptr == 0))
1700                                 return False;
1701
1702                         if (!prs_uint32("attribute", ps, depth,
1703                                         &usr->other_sids_attrib[i]))
1704                                 return False;
1705                 }
1706         
1707                 for (i = 0; i < usr->num_other_sids; i++) {
1708                         if(!smb_io_dom_sid2("", &usr->other_sids[i], ps, depth)) /* other domain SIDs */
1709                                 return False;
1710                 }
1711
1712                 depth--;
1713         }
1714
1715         return True;
1716 }
1717
1718 /*******************************************************************
1719  Reads or writes a structure.
1720 ********************************************************************/
1721
1722 BOOL net_io_q_sam_logon(const char *desc, NET_Q_SAM_LOGON *q_l, prs_struct *ps, int depth)
1723 {
1724         if (q_l == NULL)
1725                 return False;
1726
1727         prs_debug(ps, depth, desc, "net_io_q_sam_logon");
1728         depth++;
1729
1730         if(!prs_align(ps))
1731                 return False;
1732         
1733         if(!smb_io_sam_info("", &q_l->sam_id, ps, depth))
1734                 return False;
1735
1736         if(!prs_align_uint16(ps))
1737                 return False;
1738         
1739         if(!prs_uint16("validation_level", ps, depth, &q_l->validation_level))
1740                 return False;
1741
1742         return True;
1743 }
1744
1745 /*******************************************************************
1746  Reads or writes a structure.
1747 ********************************************************************/
1748
1749 BOOL net_io_r_sam_logon(const char *desc, NET_R_SAM_LOGON *r_l, prs_struct *ps, int depth)
1750 {
1751         if (r_l == NULL)
1752                 return False;
1753
1754         prs_debug(ps, depth, desc, "net_io_r_sam_logon");
1755         depth++;
1756
1757         if(!prs_uint32("buffer_creds", ps, depth, &r_l->buffer_creds)) /* undocumented buffer pointer */
1758                 return False;
1759         if (&r_l->buffer_creds) {
1760                 if(!smb_io_cred("", &r_l->srv_creds, ps, depth)) /* server credentials.  server time stamp appears to be ignored. */
1761                         return False;
1762         }
1763
1764         if(!prs_uint16("switch_value", ps, depth, &r_l->switch_value))
1765                 return False;
1766         if(!prs_align(ps))
1767                 return False;
1768
1769 #if 1 /* W2k always needs this - even for bad passwd. JRA */
1770         if(!net_io_user_info3("", r_l->user, ps, depth, r_l->switch_value, False))
1771                 return False;
1772 #else
1773         if (r_l->switch_value != 0) {
1774                 if(!net_io_user_info3("", r_l->user, ps, depth, r_l->switch_value, False))
1775                         return False;
1776         }
1777 #endif
1778
1779         if(!prs_uint32("auth_resp   ", ps, depth, &r_l->auth_resp)) /* 1 - Authoritative response; 0 - Non-Auth? */
1780                 return False;
1781
1782         if(!prs_ntstatus("status      ", ps, depth, &r_l->status))
1783                 return False;
1784
1785         if(!prs_align(ps))
1786                 return False;
1787
1788         return True;
1789 }
1790
1791 /*******************************************************************
1792  Reads or writes a structure.
1793 ********************************************************************/
1794
1795 BOOL net_io_q_sam_logoff(const char *desc,  NET_Q_SAM_LOGOFF *q_l, prs_struct *ps, int depth)
1796 {
1797         if (q_l == NULL)
1798                 return False;
1799
1800         prs_debug(ps, depth, desc, "net_io_q_sam_logoff");
1801         depth++;
1802
1803         if(!prs_align(ps))
1804                 return False;
1805         
1806         if(!smb_io_sam_info("", &q_l->sam_id, ps, depth))           /* domain SID */
1807                 return False;
1808
1809         return True;
1810 }
1811
1812 /*******************************************************************
1813  Reads or writes a structure.
1814 ********************************************************************/
1815
1816 BOOL net_io_r_sam_logoff(const char *desc, NET_R_SAM_LOGOFF *r_l, prs_struct *ps, int depth)
1817 {
1818         if (r_l == NULL)
1819                 return False;
1820
1821         prs_debug(ps, depth, desc, "net_io_r_sam_logoff");
1822         depth++;
1823
1824         if(!prs_align(ps))
1825                 return False;
1826         
1827         if(!prs_uint32("buffer_creds", ps, depth, &r_l->buffer_creds)) /* undocumented buffer pointer */
1828                 return False;
1829         if(!smb_io_cred("", &r_l->srv_creds, ps, depth)) /* server credentials.  server time stamp appears to be ignored. */
1830                 return False;
1831
1832         if(!prs_ntstatus("status      ", ps, depth, &r_l->status))
1833                 return False;
1834
1835         return True;
1836 }
1837
1838 /*******************************************************************
1839 makes a NET_Q_SAM_SYNC structure.
1840 ********************************************************************/
1841 BOOL init_net_q_sam_sync(NET_Q_SAM_SYNC * q_s, const char *srv_name,
1842                          const char *cli_name, DOM_CRED *cli_creds, 
1843                          DOM_CRED *ret_creds, uint32 database_id, 
1844                          uint32 next_rid)
1845 {
1846         DEBUG(5, ("init_q_sam_sync\n"));
1847
1848         init_unistr2(&q_s->uni_srv_name, srv_name, UNI_STR_TERMINATE);
1849         init_unistr2(&q_s->uni_cli_name, cli_name, UNI_STR_TERMINATE);
1850
1851         if (cli_creds)
1852                 memcpy(&q_s->cli_creds, cli_creds, sizeof(q_s->cli_creds));
1853
1854         if (cli_creds)
1855                 memcpy(&q_s->ret_creds, ret_creds, sizeof(q_s->ret_creds));
1856         else
1857                 memset(&q_s->ret_creds, 0, sizeof(q_s->ret_creds));
1858
1859         q_s->database_id = database_id;
1860         q_s->restart_state = 0;
1861         q_s->sync_context = next_rid;
1862         q_s->max_size = 0xffff;
1863
1864         return True;
1865 }
1866
1867 /*******************************************************************
1868 reads or writes a structure.
1869 ********************************************************************/
1870 BOOL net_io_q_sam_sync(const char *desc, NET_Q_SAM_SYNC * q_s, prs_struct *ps,
1871                        int depth)
1872 {
1873         prs_debug(ps, depth, desc, "net_io_q_sam_sync");
1874         depth++;
1875
1876         if (!smb_io_unistr2("", &q_s->uni_srv_name, True, ps, depth))
1877                 return False;
1878         if (!smb_io_unistr2("", &q_s->uni_cli_name, True, ps, depth))
1879                 return False;
1880
1881         if (!smb_io_cred("", &q_s->cli_creds, ps, depth))
1882                 return False;
1883         if (!smb_io_cred("", &q_s->ret_creds, ps, depth))
1884                 return False;
1885
1886         if (!prs_uint32("database_id  ", ps, depth, &q_s->database_id))
1887                 return False;
1888         if (!prs_uint32("restart_state", ps, depth, &q_s->restart_state))
1889                 return False;
1890         if (!prs_uint32("sync_context ", ps, depth, &q_s->sync_context))
1891                 return False;
1892
1893         if (!prs_uint32("max_size", ps, depth, &q_s->max_size))
1894                 return False;
1895
1896         return True;
1897 }
1898
1899 /*******************************************************************
1900 reads or writes a structure.
1901 ********************************************************************/
1902 static BOOL net_io_sam_delta_hdr(const char *desc, SAM_DELTA_HDR * delta,
1903                                  prs_struct *ps, int depth)
1904 {
1905         prs_debug(ps, depth, desc, "net_io_sam_delta_hdr");
1906         depth++;
1907
1908         if (!prs_uint16("type", ps, depth, &delta->type))
1909                 return False;
1910         if (!prs_uint16("type2", ps, depth, &delta->type2))
1911                 return False;
1912         if (!prs_uint32("target_rid", ps, depth, &delta->target_rid))
1913                 return False;
1914
1915         if (!prs_uint32("type3", ps, depth, &delta->type3))
1916                 return False;
1917
1918         /* Not sure why we need this but it seems to be necessary to get
1919            sam deltas working. */
1920
1921         if (delta->type != 0x16) {
1922                 if (!prs_uint32("ptr_delta", ps, depth, &delta->ptr_delta))
1923                         return False;
1924         }
1925
1926         return True;
1927 }
1928
1929 /*******************************************************************
1930 reads or writes a structure.
1931 ********************************************************************/
1932 static BOOL net_io_sam_delta_mod_count(const char *desc, SAM_DELTA_MOD_COUNT *info,
1933                                    prs_struct *ps, int depth)
1934 {
1935         prs_debug(ps, depth, desc, "net_io_sam_delta_stamp");
1936         depth++;
1937
1938         if (!prs_uint32("seqnum", ps, depth, &info->seqnum))
1939                 return False;
1940         if (!prs_uint32("dom_mod_count_ptr", ps, depth, 
1941                         &info->dom_mod_count_ptr))
1942                 return False;
1943
1944         if (info->dom_mod_count_ptr) {
1945                 if (!prs_uint64("dom_mod_count", ps, depth,
1946                                 &info->dom_mod_count))
1947                         return False;
1948         }
1949
1950         return True;
1951 }
1952
1953 /*******************************************************************
1954 reads or writes a structure.
1955 ********************************************************************/
1956 static BOOL net_io_sam_domain_info(const char *desc, SAM_DOMAIN_INFO * info,
1957                                    prs_struct *ps, int depth)
1958 {
1959         prs_debug(ps, depth, desc, "net_io_sam_domain_info");
1960         depth++;
1961
1962         if (!smb_io_unihdr("hdr_dom_name", &info->hdr_dom_name, ps, depth))
1963                 return False;
1964         if (!smb_io_unihdr("hdr_oem_info", &info->hdr_oem_info, ps, depth))
1965                 return False;
1966
1967         if (!prs_uint64("force_logoff", ps, depth, &info->force_logoff))
1968                 return False;
1969         if (!prs_uint16("min_pwd_len", ps, depth, &info->min_pwd_len))
1970                 return False;
1971         if (!prs_uint16("pwd_history_len", ps, depth, &info->pwd_history_len))
1972                 return False;
1973         if (!prs_uint64("max_pwd_age", ps, depth, &info->max_pwd_age))
1974                 return False;
1975         if (!prs_uint64("min_pwd_age", ps, depth, &info->min_pwd_age))
1976                 return False;
1977         if (!prs_uint64("dom_mod_count", ps, depth, &info->dom_mod_count))
1978                 return False;
1979         if (!smb_io_time("creation_time", &info->creation_time, ps, depth))
1980                 return False;
1981         if (!prs_uint32("security_information", ps, depth, &info->security_information))
1982                 return False;
1983         if (!smb_io_bufhdr4("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
1984                 return False;
1985         if (!smb_io_lockout_string_hdr("hdr_account_lockout_string", &info->hdr_account_lockout, ps, depth))
1986                 return False;
1987         if (!smb_io_unihdr("hdr_unknown2", &info->hdr_unknown2, ps, depth))
1988                 return False;
1989         if (!smb_io_unihdr("hdr_unknown3", &info->hdr_unknown3, ps, depth))
1990                 return False;
1991         if (!smb_io_unihdr("hdr_unknown4", &info->hdr_unknown4, ps, depth))
1992                 return False;
1993         if (!prs_uint32("logon_chgpass", ps, depth, &info->logon_chgpass))
1994                 return False;
1995         if (!prs_uint32("unknown6", ps, depth, &info->unknown6))
1996                 return False;
1997         if (!prs_uint32("unknown7", ps, depth, &info->unknown7))
1998                 return False;
1999         if (!prs_uint32("unknown8", ps, depth, &info->unknown8))
2000                 return False;
2001
2002         if (!smb_io_unistr2("uni_dom_name", &info->uni_dom_name,
2003                             info->hdr_dom_name.buffer, ps, depth))
2004                 return False;
2005         if (!smb_io_unistr2("buf_oem_info", &info->buf_oem_info,
2006                             info->hdr_oem_info.buffer, ps, depth))
2007                 return False;
2008
2009         if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth))
2010                 return False;
2011
2012         if (!smb_io_account_lockout_str("account_lockout", &info->account_lockout, 
2013                                         info->hdr_account_lockout.buffer, ps, depth))
2014                 return False;
2015
2016         if (!smb_io_unistr2("buf_unknown2", &info->buf_unknown2, 
2017                             info->hdr_unknown2.buffer, ps, depth))
2018                 return False;
2019         if (!smb_io_unistr2("buf_unknown3", &info->buf_unknown3, 
2020                             info->hdr_unknown3.buffer, ps, depth))
2021                 return False;
2022         if (!smb_io_unistr2("buf_unknown4", &info->buf_unknown4, 
2023                             info->hdr_unknown4.buffer, ps, depth))
2024                 return False;
2025
2026         return True;
2027 }
2028
2029 /*******************************************************************
2030 reads or writes a structure.
2031 ********************************************************************/
2032 static BOOL net_io_sam_group_info(const char *desc, SAM_GROUP_INFO * info,
2033                                   prs_struct *ps, int depth)
2034 {
2035         prs_debug(ps, depth, desc, "net_io_sam_group_info");
2036         depth++;
2037
2038         if (!smb_io_unihdr("hdr_grp_name", &info->hdr_grp_name, ps, depth))
2039                 return False;
2040         if (!smb_io_gid("gid", &info->gid, ps, depth))
2041                 return False;
2042         if (!smb_io_unihdr("hdr_grp_desc", &info->hdr_grp_desc, ps, depth))
2043                 return False;
2044         if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
2045                 return False;
2046
2047         if (ps->data_offset + 48 > ps->buffer_size)
2048                 return False;
2049         ps->data_offset += 48;
2050
2051         if (!smb_io_unistr2("uni_grp_name", &info->uni_grp_name,
2052                             info->hdr_grp_name.buffer, ps, depth))
2053                 return False;
2054         if (!smb_io_unistr2("uni_grp_desc", &info->uni_grp_desc,
2055                             info->hdr_grp_desc.buffer, ps, depth))
2056                 return False;
2057         if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth))
2058                 return False;
2059
2060         return True;
2061 }
2062
2063 /*******************************************************************
2064 reads or writes a structure.
2065 ********************************************************************/
2066 static BOOL net_io_sam_passwd_info(const char *desc, SAM_PWD * pwd,
2067                                    prs_struct *ps, int depth)
2068 {
2069         prs_debug(ps, depth, desc, "net_io_sam_passwd_info");
2070         depth++;
2071
2072         if (!prs_uint32("unk_0 ", ps, depth, &pwd->unk_0))
2073                 return False;
2074
2075         if (!smb_io_unihdr("hdr_lm_pwd", &pwd->hdr_lm_pwd, ps, depth))
2076                 return False;
2077         if (!prs_uint8s(False, "buf_lm_pwd", ps, depth, pwd->buf_lm_pwd, 16))
2078                 return False;
2079
2080         if (!smb_io_unihdr("hdr_nt_pwd", &pwd->hdr_nt_pwd, ps, depth))
2081                 return False;
2082         if (!prs_uint8s(False, "buf_nt_pwd", ps, depth, pwd->buf_nt_pwd, 16))
2083                 return False;
2084
2085         if (!smb_io_unihdr("", &pwd->hdr_empty_lm, ps, depth))
2086                 return False;
2087         if (!smb_io_unihdr("", &pwd->hdr_empty_nt, ps, depth))
2088                 return False;
2089
2090         return True;
2091 }
2092
2093 /*******************************************************************
2094 makes a SAM_ACCOUNT_INFO structure.
2095 ********************************************************************/
2096 BOOL make_sam_account_info(SAM_ACCOUNT_INFO * info,
2097                            const UNISTR2 *user_name,
2098                            const UNISTR2 *full_name,
2099                            uint32 user_rid, uint32 group_rid,
2100                            const UNISTR2 *home_dir,
2101                            const UNISTR2 *dir_drive,
2102                            const UNISTR2 *log_scr,
2103                            const UNISTR2 *desc,
2104                            uint32 acb_info,
2105                            const UNISTR2 *prof_path,
2106                            const UNISTR2 *wkstas,
2107                            const UNISTR2 *unk_str, const UNISTR2 *mung_dial)
2108 {
2109         int len_user_name = user_name != NULL ? user_name->uni_str_len : 0;
2110         int len_full_name = full_name != NULL ? full_name->uni_str_len : 0;
2111         int len_home_dir = home_dir != NULL ? home_dir->uni_str_len : 0;
2112         int len_dir_drive = dir_drive != NULL ? dir_drive->uni_str_len : 0;
2113         int len_logon_script = log_scr != NULL ? log_scr->uni_str_len : 0;
2114         int len_profile_path = prof_path != NULL ? prof_path->uni_str_len : 0;
2115         int len_description = desc != NULL ? desc->uni_str_len : 0;
2116         int len_workstations = wkstas != NULL ? wkstas->uni_str_len : 0;
2117         int len_unknown_str = unk_str != NULL ? unk_str->uni_str_len : 0;
2118         int len_munged_dial = mung_dial != NULL ? mung_dial->uni_str_len : 0;
2119
2120         DEBUG(5, ("make_sam_account_info\n"));
2121
2122         make_uni_hdr(&info->hdr_acct_name, len_user_name);
2123         make_uni_hdr(&info->hdr_full_name, len_full_name);
2124         make_uni_hdr(&info->hdr_home_dir, len_home_dir);
2125         make_uni_hdr(&info->hdr_dir_drive, len_dir_drive);
2126         make_uni_hdr(&info->hdr_logon_script, len_logon_script);
2127         make_uni_hdr(&info->hdr_profile, len_profile_path);
2128         make_uni_hdr(&info->hdr_acct_desc, len_description);
2129         make_uni_hdr(&info->hdr_workstations, len_workstations);
2130         make_uni_hdr(&info->hdr_comment, len_unknown_str);
2131         make_uni_hdr(&info->hdr_parameters, len_munged_dial);
2132
2133         /* not present */
2134         make_bufhdr2(&info->hdr_sec_desc, 0, 0, 0);
2135
2136         info->user_rid = user_rid;
2137         info->group_rid = group_rid;
2138
2139         init_nt_time(&info->logon_time);
2140         init_nt_time(&info->logoff_time);
2141         init_nt_time(&info->pwd_last_set_time);
2142         init_nt_time(&info->acct_expiry_time);
2143
2144         info->logon_divs = 0xA8;
2145         info->ptr_logon_hrs = 0;        /* Don't care right now */
2146
2147         info->bad_pwd_count = 0;
2148         info->logon_count = 0;
2149         info->acb_info = acb_info;
2150         info->nt_pwd_present = 0;
2151         info->lm_pwd_present = 0;
2152         info->pwd_expired = 0;
2153         info->country = 0;
2154         info->codepage = 0;
2155
2156         info->unknown1 = 0x4EC;
2157         info->unknown2 = 0;
2158
2159         copy_unistr2(&info->uni_acct_name, user_name);
2160         copy_unistr2(&info->uni_full_name, full_name);
2161         copy_unistr2(&info->uni_home_dir, home_dir);
2162         copy_unistr2(&info->uni_dir_drive, dir_drive);
2163         copy_unistr2(&info->uni_logon_script, log_scr);
2164         copy_unistr2(&info->uni_profile, prof_path);
2165         copy_unistr2(&info->uni_acct_desc, desc);
2166         copy_unistr2(&info->uni_workstations, wkstas);
2167         copy_unistr2(&info->uni_comment, unk_str);
2168         copy_unistr2(&info->uni_parameters, mung_dial);
2169
2170         return True;
2171 }
2172
2173 /*******************************************************************
2174 reads or writes a structure.
2175 ********************************************************************/
2176 static BOOL net_io_sam_account_info(const char *desc, SAM_ACCOUNT_INFO *info,
2177                                 prs_struct *ps, int depth)
2178 {
2179         BUFHDR2 hdr_priv_data;
2180         uint32 i;
2181
2182         prs_debug(ps, depth, desc, "net_io_sam_account_info");
2183         depth++;
2184
2185         if (!smb_io_unihdr("hdr_acct_name", &info->hdr_acct_name, ps, depth))
2186                 return False;
2187         if (!smb_io_unihdr("hdr_full_name", &info->hdr_full_name, ps, depth))
2188                 return False;
2189
2190         if (!prs_uint32("user_rid ", ps, depth, &info->user_rid))
2191                 return False;
2192         if (!prs_uint32("group_rid", ps, depth, &info->group_rid))
2193                 return False;
2194
2195         if (!smb_io_unihdr("hdr_home_dir ", &info->hdr_home_dir, ps, depth))
2196                 return False;
2197         if (!smb_io_unihdr("hdr_dir_drive", &info->hdr_dir_drive, ps, depth))
2198                 return False;
2199         if (!smb_io_unihdr("hdr_logon_script", &info->hdr_logon_script, ps,
2200                            depth))
2201                 return False;
2202
2203         if (!smb_io_unihdr("hdr_acct_desc", &info->hdr_acct_desc, ps, depth))
2204                 return False;
2205         if (!smb_io_unihdr("hdr_workstations", &info->hdr_workstations, ps,
2206                            depth))
2207                 return False;
2208
2209         if (!smb_io_time("logon_time", &info->logon_time, ps, depth))
2210                 return False;
2211         if (!smb_io_time("logoff_time", &info->logoff_time, ps, depth))
2212                 return False;
2213
2214         if (!prs_uint32("logon_divs   ", ps, depth, &info->logon_divs))
2215                 return False;
2216         if (!prs_uint32("ptr_logon_hrs", ps, depth, &info->ptr_logon_hrs))
2217                 return False;
2218
2219         if (!prs_uint16("bad_pwd_count", ps, depth, &info->bad_pwd_count))
2220                 return False;
2221         if (!prs_uint16("logon_count", ps, depth, &info->logon_count))
2222                 return False;
2223         if (!smb_io_time("pwd_last_set_time", &info->pwd_last_set_time, ps,
2224                          depth))
2225                 return False;
2226         if (!smb_io_time("acct_expiry_time", &info->acct_expiry_time, ps, 
2227                          depth))
2228                 return False;
2229
2230         if (!prs_uint32("acb_info", ps, depth, &info->acb_info))
2231                 return False;
2232         if (!prs_uint8s(False, "nt_pwd", ps, depth, info->nt_pwd, 16))
2233                 return False;
2234         if (!prs_uint8s(False, "lm_pwd", ps, depth, info->lm_pwd, 16))
2235                 return False;
2236         if (!prs_uint8("lm_pwd_present", ps, depth, &info->lm_pwd_present))
2237                 return False;
2238         if (!prs_uint8("nt_pwd_present", ps, depth, &info->nt_pwd_present))
2239                 return False;
2240         if (!prs_uint8("pwd_expired", ps, depth, &info->pwd_expired))
2241                 return False;
2242
2243         if (!smb_io_unihdr("hdr_comment", &info->hdr_comment, ps, depth))
2244                 return False;
2245         if (!smb_io_unihdr("hdr_parameters", &info->hdr_parameters, ps, 
2246                            depth))
2247                 return False;
2248         if (!prs_uint16("country", ps, depth, &info->country))
2249                 return False;
2250         if (!prs_uint16("codepage", ps, depth, &info->codepage))
2251                 return False;
2252
2253         if (!smb_io_bufhdr2("hdr_priv_data", &hdr_priv_data, ps, depth))
2254                 return False;
2255         if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
2256                 return False;
2257         if (!smb_io_unihdr("hdr_profile", &info->hdr_profile, ps, depth))
2258                 return False;
2259
2260         for (i = 0; i < 3; i++)
2261         {
2262                 if (!smb_io_unihdr("hdr_reserved", &info->hdr_reserved[i], 
2263                                    ps, depth))
2264                         return False;                                          
2265         }
2266
2267         for (i = 0; i < 4; i++)
2268         {
2269                 if (!prs_uint32("dw_reserved", ps, depth, 
2270                                 &info->dw_reserved[i]))
2271                         return False;
2272         }
2273
2274         if (!smb_io_unistr2("uni_acct_name", &info->uni_acct_name,
2275                             info->hdr_acct_name.buffer, ps, depth))
2276                 return False;
2277         prs_align(ps);
2278         if (!smb_io_unistr2("uni_full_name", &info->uni_full_name,
2279                             info->hdr_full_name.buffer, ps, depth))
2280                 return False;
2281         prs_align(ps);
2282         if (!smb_io_unistr2("uni_home_dir ", &info->uni_home_dir,
2283                             info->hdr_home_dir.buffer, ps, depth))
2284                 return False;
2285         prs_align(ps);
2286         if (!smb_io_unistr2("uni_dir_drive", &info->uni_dir_drive,
2287                             info->hdr_dir_drive.buffer, ps, depth))
2288                 return False;
2289         prs_align(ps);
2290         if (!smb_io_unistr2("uni_logon_script", &info->uni_logon_script,
2291                             info->hdr_logon_script.buffer, ps, depth))
2292                 return False;
2293         prs_align(ps);
2294         if (!smb_io_unistr2("uni_acct_desc", &info->uni_acct_desc,
2295                             info->hdr_acct_desc.buffer, ps, depth))
2296                 return False;
2297         prs_align(ps);
2298         if (!smb_io_unistr2("uni_workstations", &info->uni_workstations,
2299                             info->hdr_workstations.buffer, ps, depth))
2300                 return False;
2301         prs_align(ps);
2302
2303         if (!prs_uint32("unknown1", ps, depth, &info->unknown1))
2304                 return False;
2305         if (!prs_uint32("unknown2", ps, depth, &info->unknown2))
2306                 return False;
2307
2308         if (!smb_io_rpc_blob("buf_logon_hrs", &info->buf_logon_hrs, ps, depth))
2309                 return False;
2310         prs_align(ps);
2311         if (!smb_io_unistr2("uni_comment", &info->uni_comment,
2312                             info->hdr_comment.buffer, ps, depth))
2313                 return False;
2314         prs_align(ps);
2315         if (!smb_io_unistr2("uni_parameters", &info->uni_parameters,
2316                             info->hdr_parameters.buffer, ps, depth))
2317                 return False;
2318         prs_align(ps);
2319         if (hdr_priv_data.buffer != 0)
2320         {
2321                 int old_offset = 0;
2322                 uint32 len = 0x44;
2323                 if (!prs_uint32("pwd_len", ps, depth, &len))
2324                         return False;
2325                 old_offset = ps->data_offset;
2326                 if (len > 0)
2327                 {
2328                         if (ps->io)
2329                         {
2330                                 /* reading */
2331                                 if (!prs_hash1(ps, ps->data_offset, len))
2332                                         return False;
2333                         }
2334                         if (!net_io_sam_passwd_info("pass", &info->pass, 
2335                                                     ps, depth))
2336                                 return False;
2337
2338                         if (!ps->io)
2339                         {
2340                                 /* writing */
2341                                 if (!prs_hash1(ps, old_offset, len))
2342                                         return False;
2343                         }
2344                 }
2345                 if (old_offset + len > ps->buffer_size)
2346                         return False;
2347                 ps->data_offset = old_offset + len;
2348         }
2349         if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth))
2350                 return False;
2351         prs_align(ps);
2352         if (!smb_io_unistr2("uni_profile", &info->uni_profile,
2353                             info->hdr_profile.buffer, ps, depth))
2354                 return False;
2355
2356         prs_align(ps);
2357
2358         return True;
2359 }
2360
2361 /*******************************************************************
2362 reads or writes a structure.
2363 ********************************************************************/
2364 static BOOL net_io_sam_group_mem_info(const char *desc, SAM_GROUP_MEM_INFO * info,
2365                                       prs_struct *ps, int depth)
2366 {
2367         uint32 i;
2368         fstring tmp;
2369
2370         prs_debug(ps, depth, desc, "net_io_sam_group_mem_info");
2371         depth++;
2372
2373         prs_align(ps);
2374         if (!prs_uint32("ptr_rids   ", ps, depth, &info->ptr_rids))
2375                 return False;
2376         if (!prs_uint32("ptr_attribs", ps, depth, &info->ptr_attribs))
2377                 return False;
2378         if (!prs_uint32("num_members", ps, depth, &info->num_members))
2379                 return False;
2380
2381         if (ps->data_offset + 16 > ps->buffer_size)
2382                 return False;
2383         ps->data_offset += 16;
2384
2385         if (info->ptr_rids != 0)
2386         {
2387                 if (!prs_uint32("num_members2", ps, depth, 
2388                                 &info->num_members2))
2389                         return False;
2390
2391                 if (info->num_members2 != info->num_members)
2392                 {
2393                         /* RPC fault */
2394                         return False;
2395                 }
2396
2397                 info->rids = TALLOC_ARRAY(ps->mem_ctx, uint32, info->num_members2);
2398
2399                 if (info->rids == NULL) {
2400                         DEBUG(0, ("out of memory allocating %d rids\n",
2401                                   info->num_members2));
2402                         return False;
2403                 }
2404
2405                 for (i = 0; i < info->num_members2; i++)
2406                 {
2407                         slprintf(tmp, sizeof(tmp) - 1, "rids[%02d]", i);
2408                         if (!prs_uint32(tmp, ps, depth, &info->rids[i]))
2409                                 return False;
2410                 }
2411         }
2412
2413         if (info->ptr_attribs != 0)
2414         {
2415                 if (!prs_uint32("num_members3", ps, depth, 
2416                                 &info->num_members3))
2417                         return False;
2418                 if (info->num_members3 != info->num_members)
2419                 {
2420                         /* RPC fault */
2421                         return False;
2422                 }
2423
2424                 info->attribs = TALLOC_ARRAY(ps->mem_ctx, uint32, info->num_members3);
2425
2426                 if (info->attribs == NULL) {
2427                         DEBUG(0, ("out of memory allocating %d attribs\n",
2428                                   info->num_members3));
2429                         return False;
2430                 }
2431
2432                 for (i = 0; i < info->num_members3; i++)
2433                 {
2434                         slprintf(tmp, sizeof(tmp) - 1, "attribs[%02d]", i);
2435                         if (!prs_uint32(tmp, ps, depth, &info->attribs[i]))
2436                                 return False;
2437                 }
2438         }
2439
2440         return True;
2441 }
2442
2443 /*******************************************************************
2444 reads or writes a structure.
2445 ********************************************************************/
2446 static BOOL net_io_sam_alias_info(const char *desc, SAM_ALIAS_INFO * info,
2447                                   prs_struct *ps, int depth)
2448 {
2449         prs_debug(ps, depth, desc, "net_io_sam_alias_info");
2450         depth++;
2451
2452         if (!smb_io_unihdr("hdr_als_name", &info->hdr_als_name, ps, depth))
2453                 return False;
2454         if (!prs_uint32("als_rid", ps, depth, &info->als_rid))
2455                 return False;
2456         if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
2457                 return False;
2458         if (!smb_io_unihdr("hdr_als_desc", &info->hdr_als_desc, ps, depth))
2459                 return False;
2460
2461         if (ps->data_offset + 40 > ps->buffer_size)
2462                 return False;
2463         ps->data_offset += 40;
2464
2465         if (!smb_io_unistr2("uni_als_name", &info->uni_als_name,
2466                             info->hdr_als_name.buffer, ps, depth))
2467                 return False;
2468         if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth))
2469                 return False;
2470
2471         if (!smb_io_unistr2("uni_als_desc", &info->uni_als_desc,
2472                             info->hdr_als_desc.buffer, ps, depth))
2473                 return False;
2474
2475         return True;
2476 }
2477
2478 /*******************************************************************
2479 reads or writes a structure.
2480 ********************************************************************/
2481 static BOOL net_io_sam_alias_mem_info(const char *desc, SAM_ALIAS_MEM_INFO * info,
2482                                       prs_struct *ps, int depth)
2483 {
2484         uint32 i;
2485         fstring tmp;
2486
2487         prs_debug(ps, depth, desc, "net_io_sam_alias_mem_info");
2488         depth++;
2489
2490         prs_align(ps);
2491         if (!prs_uint32("num_members", ps, depth, &info->num_members))
2492                 return False;
2493         if (!prs_uint32("ptr_members", ps, depth, &info->ptr_members))
2494                 return False;
2495
2496         if (ps->data_offset + 16 > ps->buffer_size)
2497                 return False;
2498         ps->data_offset += 16;
2499
2500         if (info->ptr_members != 0)
2501         {
2502                 if (!prs_uint32("num_sids", ps, depth, &info->num_sids))
2503                         return False;
2504                 if (info->num_sids != info->num_members)
2505                 {
2506                         /* RPC fault */
2507                         return False;
2508                 }
2509
2510                 info->ptr_sids = TALLOC_ARRAY(ps->mem_ctx, uint32, info->num_sids);
2511                 
2512                 if (info->ptr_sids == NULL) {
2513                         DEBUG(0, ("out of memory allocating %d ptr_sids\n",
2514                                   info->num_sids));
2515                         return False;
2516                 }
2517
2518                 for (i = 0; i < info->num_sids; i++)
2519                 {
2520                         slprintf(tmp, sizeof(tmp) - 1, "ptr_sids[%02d]", i);
2521                         if (!prs_uint32(tmp, ps, depth, &info->ptr_sids[i]))
2522                                 return False;
2523                 }
2524
2525                 info->sids = TALLOC_ARRAY(ps->mem_ctx, DOM_SID2, info->num_sids);
2526
2527                 if (info->sids == NULL) {
2528                         DEBUG(0, ("error allocating %d sids\n",
2529                                   info->num_sids));
2530                         return False;
2531                 }
2532
2533                 for (i = 0; i < info->num_sids; i++)
2534                 {
2535                         if (info->ptr_sids[i] != 0)
2536                         {
2537                                 slprintf(tmp, sizeof(tmp) - 1, "sids[%02d]",
2538                                          i);
2539                                 if (!smb_io_dom_sid2(tmp, &info->sids[i], 
2540                                                      ps, depth))
2541                                         return False;
2542                         }
2543                 }
2544         }
2545
2546         return True;
2547 }
2548
2549 /*******************************************************************
2550 reads or writes a structure.
2551 ********************************************************************/
2552 static BOOL net_io_sam_policy_info(const char *desc, SAM_DELTA_POLICY *info,
2553                                       prs_struct *ps, int depth)
2554 {
2555         unsigned int i;
2556         prs_debug(ps, depth, desc, "net_io_sam_policy_info");
2557         depth++;
2558
2559         if(!prs_align(ps))
2560                 return False;
2561
2562         if (!prs_uint32("max_log_size", ps, depth, &info->max_log_size))
2563                 return False;
2564         if (!prs_uint64("audit_retention_period", ps, depth,
2565                         &info->audit_retention_period))
2566                 return False;
2567         if (!prs_uint32("auditing_mode", ps, depth, &info->auditing_mode))
2568                 return False;
2569         if (!prs_uint32("num_events", ps, depth, &info->num_events))
2570                 return False;
2571         if (!prs_uint32("ptr_events", ps, depth, &info->ptr_events))
2572                 return False;
2573
2574         if (!smb_io_unihdr("hdr_dom_name", &info->hdr_dom_name, ps, depth))
2575                 return False;
2576
2577         if (!prs_uint32("sid_ptr", ps, depth, &info->sid_ptr))
2578                 return False;
2579
2580         if (!prs_uint32("paged_pool_limit", ps, depth, &info->paged_pool_limit))
2581                 return False;
2582         if (!prs_uint32("non_paged_pool_limit", ps, depth,
2583                         &info->non_paged_pool_limit))
2584                 return False;
2585         if (!prs_uint32("min_workset_size", ps, depth, &info->min_workset_size))
2586                 return False;
2587         if (!prs_uint32("max_workset_size", ps, depth, &info->max_workset_size))
2588                 return False;
2589         if (!prs_uint32("page_file_limit", ps, depth, &info->page_file_limit))
2590                 return False;
2591         if (!prs_uint64("time_limit", ps, depth, &info->time_limit))
2592                 return False;
2593         if (!smb_io_time("modify_time", &info->modify_time, ps, depth))
2594                 return False;
2595         if (!smb_io_time("create_time", &info->create_time, ps, depth))
2596                 return False;
2597         if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
2598                 return False;
2599
2600         for (i=0; i<4; i++) {
2601                 UNIHDR dummy;
2602                 if (!smb_io_unihdr("dummy", &dummy, ps, depth))
2603                         return False;
2604         }
2605
2606         for (i=0; i<4; i++) {
2607                 uint32 reserved;
2608                 if (!prs_uint32("reserved", ps, depth, &reserved))
2609                         return False;
2610         }
2611
2612         if (!prs_uint32("num_event_audit_options", ps, depth,
2613                         &info->num_event_audit_options))
2614                 return False;
2615
2616         for (i=0; i<info->num_event_audit_options; i++)
2617                 if (!prs_uint32("event_audit_option", ps, depth,
2618                                 &info->event_audit_option))
2619                         return False;
2620
2621         if (!smb_io_unistr2("domain_name", &info->domain_name, True, ps, depth))
2622                 return False;
2623
2624         if(!smb_io_dom_sid2("domain_sid", &info->domain_sid, ps, depth))
2625                 return False;
2626
2627         if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth))
2628
2629                 return False;
2630
2631         return True;
2632 }
2633
2634 #if 0
2635
2636 /* This function is pretty broken - see bug #334 */
2637
2638 /*******************************************************************
2639 reads or writes a structure.
2640 ********************************************************************/
2641 static BOOL net_io_sam_trustdoms_info(const char *desc, SAM_DELTA_TRUSTDOMS *info,
2642                                       prs_struct *ps, int depth)
2643 {
2644         int i;
2645
2646         prs_debug(ps, depth, desc, "net_io_sam_trustdoms_info");
2647         depth++;
2648
2649         if(!prs_align(ps))
2650                 return False;
2651
2652         if(!prs_uint32("buf_size", ps, depth, &info->buf_size))
2653                 return False;
2654
2655         if(!sec_io_desc("sec_desc", &info->sec_desc, ps, depth))
2656                 return False;
2657
2658         if(!smb_io_dom_sid2("sid", &info->sid, ps, depth))
2659                 return False;
2660
2661         if(!smb_io_unihdr("hdr_domain", &info->hdr_domain, ps, depth))
2662                 return False;
2663
2664         if(!prs_uint32("unknown0", ps, depth, &info->unknown0))
2665                 return False;
2666         if(!prs_uint32("unknown1", ps, depth, &info->unknown1))
2667                 return False;
2668         if(!prs_uint32("unknown2", ps, depth, &info->unknown2))
2669                 return False;
2670
2671         if(!prs_uint32("buf_size2", ps, depth, &info->buf_size2))
2672                 return False;
2673         if(!prs_uint32("ptr", ps, depth, &info->ptr))
2674                 return False;
2675
2676         for (i=0; i<12; i++)
2677                 if(!prs_uint32("unknown3", ps, depth, &info->unknown3))
2678                         return False;
2679
2680         if (!smb_io_unistr2("domain", &info->domain, True, ps, depth))
2681                 return False;
2682
2683         return True;
2684 }
2685
2686 #endif
2687
2688 #if 0
2689
2690 /* This function doesn't work - see bug #334 */
2691
2692 /*******************************************************************
2693 reads or writes a structure.
2694 ********************************************************************/
2695 static BOOL net_io_sam_secret_info(const char *desc, SAM_DELTA_SECRET *info,
2696                                    prs_struct *ps, int depth)
2697 {
2698         int i;
2699
2700         prs_debug(ps, depth, desc, "net_io_sam_secret_info");
2701         depth++;
2702
2703         if(!prs_align(ps))
2704                 return False;
2705
2706         if(!prs_uint32("buf_size", ps, depth, &info->buf_size))
2707                 return False;
2708
2709         if(!sec_io_desc("sec_desc", &info->sec_desc, ps, depth))
2710                 return False;
2711
2712         if (!smb_io_unistr2("secret", &info->secret, True, ps, depth))
2713                 return False;
2714
2715         if(!prs_align(ps))
2716                 return False;
2717
2718         if(!prs_uint32("count1", ps, depth, &info->count1))
2719                 return False;
2720         if(!prs_uint32("count2", ps, depth, &info->count2))
2721                 return False;
2722         if(!prs_uint32("ptr", ps, depth, &info->ptr))
2723                 return False;
2724
2725
2726         if(!smb_io_time("time1", &info->time1, ps, depth)) /* logon time */
2727                 return False;
2728         if(!prs_uint32("count3", ps, depth, &info->count3))
2729                 return False;
2730         if(!prs_uint32("count4", ps, depth, &info->count4))
2731                 return False;
2732         if(!prs_uint32("ptr2", ps, depth, &info->ptr2))
2733                 return False;
2734         if(!smb_io_time("time2", &info->time2, ps, depth)) /* logon time */
2735                 return False;
2736         if(!prs_uint32("unknow1", ps, depth, &info->unknow1))
2737                 return False;
2738
2739
2740         if(!prs_uint32("buf_size2", ps, depth, &info->buf_size2))
2741                 return False;
2742         if(!prs_uint32("ptr3", ps, depth, &info->ptr3))
2743                 return False;
2744         for(i=0; i<12; i++)
2745                 if(!prs_uint32("unknow2", ps, depth, &info->unknow2))
2746                         return False;
2747
2748         if(!prs_uint32("chal_len", ps, depth, &info->chal_len))
2749                 return False;
2750         if(!prs_uint32("reserved1", ps, depth, &info->reserved1))
2751                 return False;
2752         if(!prs_uint32("chal_len2", ps, depth, &info->chal_len2))
2753                 return False;
2754
2755         if(!prs_uint8s (False, "chal", ps, depth, info->chal, info->chal_len2))
2756                 return False;
2757
2758         if(!prs_uint32("key_len", ps, depth, &info->key_len))
2759                 return False;
2760         if(!prs_uint32("reserved2", ps, depth, &info->reserved2))
2761                 return False;
2762         if(!prs_uint32("key_len2", ps, depth, &info->key_len2))
2763                 return False;
2764
2765         if(!prs_uint8s (False, "key", ps, depth, info->key, info->key_len2))
2766                 return False;
2767
2768
2769         if(!prs_uint32("buf_size3", ps, depth, &info->buf_size3))
2770                 return False;
2771
2772         if(!sec_io_desc("sec_desc2", &info->sec_desc2, ps, depth))
2773                 return False;
2774
2775
2776         return True;
2777 }
2778
2779 #endif
2780
2781 /*******************************************************************
2782 reads or writes a structure.
2783 ********************************************************************/
2784 static BOOL net_io_sam_privs_info(const char *desc, SAM_DELTA_PRIVS *info,
2785                                       prs_struct *ps, int depth)
2786 {
2787         unsigned int i;
2788
2789         prs_debug(ps, depth, desc, "net_io_sam_privs_info");
2790         depth++;
2791
2792         if(!prs_align(ps))
2793                 return False;
2794
2795         if(!smb_io_dom_sid2("sid", &info->sid, ps, depth))
2796                 return False;
2797
2798         if(!prs_uint32("priv_count", ps, depth, &info->priv_count))
2799                 return False;
2800         if(!prs_uint32("priv_control", ps, depth, &info->priv_control))
2801                 return False;
2802
2803         if(!prs_uint32("priv_attr_ptr", ps, depth, &info->priv_attr_ptr))
2804                 return False;
2805         if(!prs_uint32("priv_name_ptr", ps, depth, &info->priv_name_ptr))
2806                 return False;
2807
2808         if (!prs_uint32("paged_pool_limit", ps, depth, &info->paged_pool_limit))
2809                 return False;
2810         if (!prs_uint32("non_paged_pool_limit", ps, depth,
2811                         &info->non_paged_pool_limit))
2812                 return False;
2813         if (!prs_uint32("min_workset_size", ps, depth, &info->min_workset_size))
2814                 return False;
2815         if (!prs_uint32("max_workset_size", ps, depth, &info->max_workset_size))
2816                 return False;
2817         if (!prs_uint32("page_file_limit", ps, depth, &info->page_file_limit))
2818                 return False;
2819         if (!prs_uint64("time_limit", ps, depth, &info->time_limit))
2820                 return False;
2821         if (!prs_uint32("system_flags", ps, depth, &info->system_flags))
2822                 return False;
2823         if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
2824                 return False;
2825
2826         for (i=0; i<4; i++) {
2827                 UNIHDR dummy;
2828                 if (!smb_io_unihdr("dummy", &dummy, ps, depth))
2829                         return False;
2830         }
2831
2832         for (i=0; i<4; i++) {
2833                 uint32 reserved;
2834                 if (!prs_uint32("reserved", ps, depth, &reserved))
2835                         return False;
2836         }
2837
2838         if(!prs_uint32("attribute_count", ps, depth, &info->attribute_count))
2839                 return False;
2840
2841         info->attributes = TALLOC_ARRAY(ps->mem_ctx, uint32, info->attribute_count);
2842
2843         for (i=0; i<info->attribute_count; i++)
2844                 if(!prs_uint32("attributes", ps, depth, &info->attributes[i]))
2845                         return False;
2846
2847         if(!prs_uint32("privlist_count", ps, depth, &info->privlist_count))
2848                 return False;
2849
2850         info->hdr_privslist = TALLOC_ARRAY(ps->mem_ctx, UNIHDR, info->privlist_count);
2851         info->uni_privslist = TALLOC_ARRAY(ps->mem_ctx, UNISTR2, info->privlist_count);
2852
2853         for (i=0; i<info->privlist_count; i++)
2854                 if(!smb_io_unihdr("hdr_privslist", &info->hdr_privslist[i], ps, depth))
2855                         return False;
2856
2857         for (i=0; i<info->privlist_count; i++)
2858                 if (!smb_io_unistr2("uni_privslist", &info->uni_privslist[i], True, ps, depth))
2859                         return False;
2860
2861         if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth))
2862                 return False;
2863
2864         return True;
2865 }
2866
2867 /*******************************************************************
2868 reads or writes a structure.
2869 ********************************************************************/
2870 static BOOL net_io_sam_delta_ctr(const char *desc,
2871                                  SAM_DELTA_CTR * delta, uint16 type,
2872                                  prs_struct *ps, int depth)
2873 {
2874         prs_debug(ps, depth, desc, "net_io_sam_delta_ctr");
2875         depth++;
2876
2877         switch (type) {
2878                 /* Seen in sam deltas */
2879                 case SAM_DELTA_MODIFIED_COUNT:
2880                         if (!net_io_sam_delta_mod_count("", &delta->mod_count, ps, depth))
2881                                 return False;
2882                         break;
2883
2884                 case SAM_DELTA_DOMAIN_INFO:
2885                         if (!net_io_sam_domain_info("", &delta->domain_info, ps, depth))
2886                                 return False;
2887                         break;
2888
2889                 case SAM_DELTA_GROUP_INFO:
2890                         if (!net_io_sam_group_info("", &delta->group_info, ps, depth))
2891                                 return False;
2892                         break;
2893
2894                 case SAM_DELTA_ACCOUNT_INFO:
2895                         if (!net_io_sam_account_info("", &delta->account_info, ps, depth))
2896                                 return False;
2897                         break;
2898
2899                 case SAM_DELTA_GROUP_MEM:
2900                         if (!net_io_sam_group_mem_info("", &delta->grp_mem_info, ps, depth))
2901                                 return False;
2902                         break;
2903
2904                 case SAM_DELTA_ALIAS_INFO:
2905                         if (!net_io_sam_alias_info("", &delta->alias_info, ps, depth))
2906                                 return False;
2907                         break;
2908
2909                 case SAM_DELTA_POLICY_INFO:
2910                         if (!net_io_sam_policy_info("", &delta->policy_info, ps, depth))
2911                                 return False;
2912                         break;
2913
2914                 case SAM_DELTA_ALIAS_MEM:
2915                         if (!net_io_sam_alias_mem_info("", &delta->als_mem_info, ps, depth))
2916                                 return False;
2917                         break;
2918
2919                 case SAM_DELTA_PRIVS_INFO:
2920                         if (!net_io_sam_privs_info("", &delta->privs_info, ps, depth))
2921                                 return False;
2922                         break;
2923
2924                         /* These guys are implemented but broken */
2925
2926                 case SAM_DELTA_TRUST_DOMS:
2927                 case SAM_DELTA_SECRET_INFO:
2928                         break;
2929
2930                         /* These guys are not implemented yet */
2931
2932                 case SAM_DELTA_RENAME_GROUP:
2933                 case SAM_DELTA_RENAME_USER:
2934                 case SAM_DELTA_RENAME_ALIAS:
2935                 case SAM_DELTA_DELETE_GROUP:
2936                 case SAM_DELTA_DELETE_USER:
2937                 default:
2938                         DEBUG(0, ("Replication error: Unknown delta type 0x%x\n", type));
2939                         break;
2940         }
2941
2942         return True;
2943 }
2944
2945 /*******************************************************************
2946 reads or writes a structure.
2947 ********************************************************************/
2948 BOOL net_io_r_sam_sync(const char *desc,
2949                        NET_R_SAM_SYNC * r_s, prs_struct *ps, int depth)
2950 {
2951         uint32 i;
2952
2953         prs_debug(ps, depth, desc, "net_io_r_sam_sync");
2954         depth++;
2955
2956         if (!smb_io_cred("srv_creds", &r_s->srv_creds, ps, depth))
2957                 return False;
2958         if (!prs_uint32("sync_context", ps, depth, &r_s->sync_context))
2959                 return False;
2960
2961         if (!prs_uint32("ptr_deltas", ps, depth, &r_s->ptr_deltas))
2962                 return False;
2963         if (r_s->ptr_deltas != 0)
2964         {
2965                 if (!prs_uint32("num_deltas ", ps, depth, &r_s->num_deltas))
2966                         return False;
2967                 if (!prs_uint32("ptr_deltas2", ps, depth, &r_s->ptr_deltas2))
2968                         return False;
2969                 if (r_s->ptr_deltas2 != 0)
2970                 {
2971                         if (!prs_uint32("num_deltas2", ps, depth,
2972                                         &r_s->num_deltas2))
2973                                 return False;
2974
2975                         if (r_s->num_deltas2 != r_s->num_deltas)
2976                         {
2977                                 /* RPC fault */
2978                                 return False;
2979                         }
2980
2981                         if (r_s->num_deltas2 > 0) {
2982                                 r_s->hdr_deltas = TALLOC_ARRAY(ps->mem_ctx, SAM_DELTA_HDR, r_s->num_deltas2);
2983                                 if (r_s->hdr_deltas == NULL) {
2984                                         DEBUG(0, ("error tallocating memory "
2985                                                   "for %d delta headers\n", 
2986                                                   r_s->num_deltas2));
2987                                         return False;
2988                                 }
2989                         }
2990
2991                         for (i = 0; i < r_s->num_deltas2; i++)
2992                         {
2993                                 if (!net_io_sam_delta_hdr("", 
2994                                                           &r_s->hdr_deltas[i],
2995                                                           ps, depth))
2996                                         return False;
2997                         }
2998
2999                         if (r_s->num_deltas2 > 0) {
3000                                 r_s->deltas = TALLOC_ARRAY(ps->mem_ctx, SAM_DELTA_CTR, r_s->num_deltas2);
3001                                 if (r_s->deltas == NULL) {
3002                                         DEBUG(0, ("error tallocating memory "
3003                                                   "for %d deltas\n", 
3004                                                   r_s->num_deltas2));
3005                                         return False;
3006                                 }
3007                         }
3008
3009                         for (i = 0; i < r_s->num_deltas2; i++)
3010                         {
3011                                 if (!net_io_sam_delta_ctr(
3012                                         "", &r_s->deltas[i],
3013                                         r_s->hdr_deltas[i].type3,
3014                                         ps, depth)) {
3015                                         DEBUG(0, ("hmm, failed on i=%d\n", i));
3016                                         return False;
3017                                 }
3018                         }
3019                 }
3020         }
3021
3022         prs_align(ps);
3023         if (!prs_ntstatus("status", ps, depth, &(r_s->status)))
3024                 return False;
3025
3026         return True;
3027 }
3028
3029 /*******************************************************************
3030 makes a NET_Q_SAM_DELTAS structure.
3031 ********************************************************************/
3032 BOOL init_net_q_sam_deltas(NET_Q_SAM_DELTAS *q_s, const char *srv_name, 
3033                            const char *cli_name, DOM_CRED *cli_creds, 
3034                            uint32 database_id, UINT64_S dom_mod_count)
3035 {
3036         DEBUG(5, ("init_net_q_sam_deltas\n"));
3037
3038         init_unistr2(&q_s->uni_srv_name, srv_name, UNI_STR_TERMINATE);
3039         init_unistr2(&q_s->uni_cli_name, cli_name, UNI_STR_TERMINATE);
3040
3041         memcpy(&q_s->cli_creds, cli_creds, sizeof(q_s->cli_creds));
3042         memset(&q_s->ret_creds, 0, sizeof(q_s->ret_creds));
3043
3044         q_s->database_id = database_id;
3045         q_s->dom_mod_count.low = dom_mod_count.low;
3046         q_s->dom_mod_count.high = dom_mod_count.high;
3047         q_s->max_size = 0xffff;
3048
3049         return True;
3050 }
3051
3052 /*******************************************************************
3053 reads or writes a structure.
3054 ********************************************************************/
3055 BOOL net_io_q_sam_deltas(const char *desc, NET_Q_SAM_DELTAS *q_s, prs_struct *ps,
3056                          int depth)
3057 {
3058         prs_debug(ps, depth, desc, "net_io_q_sam_deltas");
3059         depth++;
3060
3061         if (!smb_io_unistr2("", &q_s->uni_srv_name, True, ps, depth))
3062                 return False;
3063         if (!smb_io_unistr2("", &q_s->uni_cli_name, True, ps, depth))
3064                 return False;
3065
3066         if (!smb_io_cred("", &q_s->cli_creds, ps, depth))
3067                 return False;
3068         if (!smb_io_cred("", &q_s->ret_creds, ps, depth))
3069                 return False;
3070
3071         if (!prs_uint32("database_id  ", ps, depth, &q_s->database_id))
3072                 return False;
3073         if (!prs_uint64("dom_mod_count", ps, depth, &q_s->dom_mod_count))
3074                 return False;
3075         if (!prs_uint32("max_size", ps, depth, &q_s->max_size))
3076                 return False;
3077
3078         return True;
3079 }
3080
3081 /*******************************************************************
3082 reads or writes a structure.
3083 ********************************************************************/
3084 BOOL net_io_r_sam_deltas(const char *desc,
3085                          NET_R_SAM_DELTAS *r_s, prs_struct *ps, int depth)
3086 {
3087         unsigned int i;
3088
3089         prs_debug(ps, depth, desc, "net_io_r_sam_deltas");
3090         depth++;
3091
3092         if (!smb_io_cred("srv_creds", &r_s->srv_creds, ps, depth))
3093                 return False;
3094         if (!prs_uint64("dom_mod_count", ps, depth, &r_s->dom_mod_count))
3095                 return False;
3096
3097         if (!prs_uint32("ptr_deltas", ps, depth, &r_s->ptr_deltas))
3098                 return False;
3099         if (!prs_uint32("num_deltas", ps, depth, &r_s->num_deltas))
3100                 return False;
3101         if (!prs_uint32("ptr_deltas2", ps, depth, &r_s->num_deltas2))
3102                 return False;
3103
3104         if (r_s->num_deltas2 != 0)
3105         {
3106                 if (!prs_uint32("num_deltas2 ", ps, depth, &r_s->num_deltas2))
3107                         return False;
3108
3109                 if (r_s->ptr_deltas != 0)
3110                 {
3111                         if (r_s->num_deltas > 0) {
3112                                 r_s->hdr_deltas = TALLOC_ARRAY(ps->mem_ctx, SAM_DELTA_HDR, r_s->num_deltas);
3113                                 if (r_s->hdr_deltas == NULL) {
3114                                         DEBUG(0, ("error tallocating memory "
3115                                                   "for %d delta headers\n", 
3116                                                   r_s->num_deltas));
3117                                         return False;
3118                                 }
3119                         }
3120
3121                         for (i = 0; i < r_s->num_deltas; i++)
3122                         {
3123                                 net_io_sam_delta_hdr("", &r_s->hdr_deltas[i],
3124                                                       ps, depth);
3125                         }
3126                         
3127                         if (r_s->num_deltas > 0) {
3128                                 r_s->deltas = TALLOC_ARRAY(ps->mem_ctx, SAM_DELTA_CTR, r_s->num_deltas);
3129                                 if (r_s->deltas == NULL) {
3130                                         DEBUG(0, ("error tallocating memory "
3131                                                   "for %d deltas\n", 
3132                                                   r_s->num_deltas));
3133                                         return False;
3134                                 }
3135                         }
3136
3137                         for (i = 0; i < r_s->num_deltas; i++)
3138                         {
3139                                 if (!net_io_sam_delta_ctr(
3140                                         "",
3141                                         &r_s->deltas[i],
3142                                         r_s->hdr_deltas[i].type2,
3143                                         ps, depth))
3144                                         
3145                                         return False;
3146                         }
3147                 }
3148         }
3149
3150         prs_align(ps);
3151         if (!prs_ntstatus("status", ps, depth, &r_s->status))
3152                 return False;
3153
3154         return True;
3155 }
3156
3157 /*******************************************************************
3158  Inits a NET_Q_DSR_GETDCNAME structure.
3159 ********************************************************************/
3160
3161 void init_net_q_dsr_getdcname(NET_Q_DSR_GETDCNAME *r_t, const char *server_unc,
3162                               const char *domain_name,
3163                               struct uuid *domain_guid,
3164                               struct uuid *site_guid,
3165                               uint32_t flags)
3166 {
3167         DEBUG(5, ("init_net_q_dsr_getdcname\n"));
3168
3169         r_t->ptr_server_unc = (server_unc != NULL);
3170         init_unistr2(&r_t->uni_server_unc, server_unc, UNI_STR_TERMINATE);
3171
3172         r_t->ptr_domain_name = (domain_name != NULL);
3173         init_unistr2(&r_t->uni_domain_name, domain_name, UNI_STR_TERMINATE);
3174
3175         r_t->ptr_domain_guid = (domain_guid != NULL);
3176         r_t->domain_guid = domain_guid;
3177
3178         r_t->ptr_site_guid = (site_guid != NULL);
3179         r_t->site_guid = site_guid;
3180
3181         r_t->flags = flags;
3182 }
3183
3184 /*******************************************************************
3185  Reads or writes an NET_Q_DSR_GETDCNAME structure.
3186 ********************************************************************/
3187
3188 BOOL net_io_q_dsr_getdcname(const char *desc, NET_Q_DSR_GETDCNAME *r_t,
3189                             prs_struct *ps, int depth)
3190 {
3191         if (r_t == NULL)
3192                 return False;
3193
3194         prs_debug(ps, depth, desc, "net_io_q_dsr_getdcname");
3195         depth++;
3196
3197         if (!prs_uint32("ptr_server_unc", ps, depth, &r_t->ptr_server_unc))
3198                 return False;
3199
3200         if (!smb_io_unistr2("server_unc", &r_t->uni_server_unc,
3201                             r_t->ptr_server_unc, ps, depth))
3202                 return False;
3203
3204         if (!prs_align(ps))
3205                 return False;
3206
3207         if (!prs_uint32("ptr_domain_name", ps, depth, &r_t->ptr_domain_name))
3208                 return False;
3209
3210         if (!smb_io_unistr2("domain_name", &r_t->uni_domain_name,
3211                             r_t->ptr_domain_name, ps, depth))
3212                 return False;
3213
3214         if (!prs_align(ps))
3215                 return False;
3216
3217         if (!prs_uint32("ptr_domain_guid", ps, depth, &r_t->ptr_domain_guid))
3218                 return False;
3219
3220         if (UNMARSHALLING(ps) && (r_t->ptr_domain_guid)) {
3221                 r_t->domain_guid = PRS_ALLOC_MEM(ps, struct uuid, 1);
3222                 if (r_t->domain_guid == NULL)
3223                         return False;
3224         }
3225
3226         if ((r_t->ptr_domain_guid) &&
3227             (!smb_io_uuid("domain_guid", r_t->domain_guid, ps, depth)))
3228                 return False;
3229
3230         if (!prs_align(ps))
3231                 return False;
3232
3233         if (!prs_uint32("ptr_site_guid", ps, depth, &r_t->ptr_site_guid))
3234                 return False;
3235
3236         if (UNMARSHALLING(ps) && (r_t->ptr_site_guid)) {
3237                 r_t->site_guid = PRS_ALLOC_MEM(ps, struct uuid, 1);
3238                 if (r_t->site_guid == NULL)
3239                         return False;
3240         }
3241
3242         if ((r_t->ptr_site_guid) &&
3243             (!smb_io_uuid("site_guid", r_t->site_guid, ps, depth)))
3244                 return False;
3245
3246         if (!prs_align(ps))
3247                 return False;
3248
3249         if (!prs_uint32("flags", ps, depth, &r_t->flags))
3250                 return False;
3251
3252         return True;
3253 }
3254
3255 /*******************************************************************
3256  Inits a NET_R_DSR_GETDCNAME structure.
3257 ********************************************************************/
3258 void init_net_r_dsr_getdcname(NET_R_DSR_GETDCNAME *r_t, const char *dc_unc,
3259                               const char *dc_address, int32 dc_address_type,
3260                               struct uuid domain_guid, const char *domain_name,
3261                               const char *forest_name, uint32 dc_flags,
3262                               const char *dc_site_name,
3263                               const char *client_site_name)
3264 {
3265         DEBUG(5, ("init_net_q_dsr_getdcname\n"));
3266
3267         r_t->ptr_dc_unc = (dc_unc != NULL);
3268         init_unistr2(&r_t->uni_dc_unc, dc_unc, UNI_STR_TERMINATE);
3269
3270         r_t->ptr_dc_address = (dc_address != NULL);
3271         init_unistr2(&r_t->uni_dc_address, dc_address, UNI_STR_TERMINATE);
3272
3273         r_t->dc_address_type = dc_address_type;
3274         r_t->domain_guid = domain_guid;
3275
3276         r_t->ptr_domain_name = (domain_name != NULL);
3277         init_unistr2(&r_t->uni_domain_name, domain_name, UNI_STR_TERMINATE);
3278
3279         r_t->ptr_forest_name = (forest_name != NULL);
3280         init_unistr2(&r_t->uni_forest_name, forest_name, UNI_STR_TERMINATE);
3281
3282         r_t->dc_flags = dc_flags;
3283
3284         r_t->ptr_dc_site_name = (dc_site_name != NULL);
3285         init_unistr2(&r_t->uni_dc_site_name, dc_site_name, UNI_STR_TERMINATE);
3286
3287         r_t->ptr_client_site_name = (client_site_name != NULL);
3288         init_unistr2(&r_t->uni_client_site_name, client_site_name,
3289                      UNI_STR_TERMINATE);
3290 }
3291
3292 /*******************************************************************
3293  Reads or writes an NET_R_DSR_GETDCNAME structure.
3294 ********************************************************************/
3295
3296 BOOL net_io_r_dsr_getdcname(const char *desc, NET_R_DSR_GETDCNAME *r_t,
3297                             prs_struct *ps, int depth)
3298 {
3299         uint32 info_ptr = 1;
3300
3301         if (r_t == NULL)
3302                 return False;
3303
3304         prs_debug(ps, depth, desc, "net_io_r_dsr_getdcname");
3305         depth++;
3306
3307         /* The reply contains *just* an info struct, this is the ptr to it */
3308         if (!prs_uint32("info_ptr", ps, depth, &info_ptr))
3309                 return False;
3310
3311         if (info_ptr == 0)
3312                 return False;
3313
3314         if (!prs_uint32("ptr_dc_unc", ps, depth, &r_t->ptr_dc_unc))
3315                 return False;
3316
3317         if (!prs_uint32("ptr_dc_address", ps, depth, &r_t->ptr_dc_address))
3318                 return False;
3319
3320         if (!prs_uint32("dc_address_type", ps, depth, &r_t->dc_address_type))
3321                 return False;
3322
3323         if (!smb_io_uuid("domain_guid", &r_t->domain_guid, ps, depth))
3324                 return False;
3325
3326         if (!prs_uint32("ptr_domain_name", ps, depth, &r_t->ptr_domain_name))
3327                 return False;
3328
3329         if (!prs_uint32("ptr_forest_name", ps, depth, &r_t->ptr_forest_name))
3330                 return False;
3331
3332         if (!prs_uint32("dc_flags", ps, depth, &r_t->dc_flags))
3333                 return False;
3334
3335         if (!prs_uint32("ptr_dc_site_name", ps, depth, &r_t->ptr_dc_site_name))
3336                 return False;
3337
3338         if (!prs_uint32("ptr_client_site_name", ps, depth,
3339                         &r_t->ptr_client_site_name))
3340                 return False;
3341
3342         if (!prs_align(ps))
3343                 return False;
3344
3345         if (!smb_io_unistr2("dc_unc", &r_t->uni_dc_unc,
3346                             r_t->ptr_dc_unc, ps, depth))
3347                 return False;
3348
3349         if (!prs_align(ps))
3350                 return False;
3351
3352         if (!smb_io_unistr2("dc_address", &r_t->uni_dc_address,
3353                             r_t->ptr_dc_address, ps, depth))
3354                 return False;
3355
3356         if (!prs_align(ps))
3357                 return False;
3358
3359         if (!smb_io_unistr2("domain_name", &r_t->uni_domain_name,
3360                             r_t->ptr_domain_name, ps, depth))
3361                 return False;
3362
3363         if (!prs_align(ps))
3364                 return False;
3365
3366         if (!smb_io_unistr2("forest_name", &r_t->uni_forest_name,
3367                             r_t->ptr_forest_name, ps, depth))
3368                 return False;
3369
3370         if (!prs_align(ps))
3371                 return False;
3372
3373         if (!smb_io_unistr2("dc_site_name", &r_t->uni_dc_site_name,
3374                             r_t->ptr_dc_site_name, ps, depth))
3375                 return False;
3376
3377         if (!prs_align(ps))
3378                 return False;
3379
3380         if (!smb_io_unistr2("client_site_name", &r_t->uni_client_site_name,
3381                             r_t->ptr_client_site_name, ps, depth))
3382                 return False;
3383
3384         if (!prs_align(ps))
3385                 return False;
3386
3387         if (!prs_werror("result", ps, depth, &r_t->result))
3388                 return False;
3389
3390         return True;
3391 }