f4ba0e76a1e615bba6e0cbf570218c52555a05fc
[abartlet/samba.git/.git] / source3 / 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_ntstatus("status", ps, depth, &r_t->status))
561                 return False;
562
563         return True;
564 }
565
566 /*******************************************************************
567  Inits an NET_R_TRUST_DOM_LIST structure.
568 ********************************************************************/
569
570 void init_r_trust_dom(NET_R_TRUST_DOM_LIST *r_t,
571                         uint32 num_doms, const char *dom_name)
572 {
573         unsigned int i = 0;
574
575         DEBUG(5,("init_r_trust_dom\n"));
576
577         for (i = 0; i < MAX_TRUST_DOMS; i++) {
578                 r_t->uni_trust_dom_name[i].uni_str_len = 0;
579                 r_t->uni_trust_dom_name[i].uni_max_len = 0;
580         }
581         if (num_doms > MAX_TRUST_DOMS)
582                 num_doms = MAX_TRUST_DOMS;
583
584         for (i = 0; i < num_doms; i++) {
585                 fstring domain_name;
586                 fstrcpy(domain_name, dom_name);
587                 strupper_m(domain_name);
588                 init_unistr2(&r_t->uni_trust_dom_name[i], domain_name, UNI_STR_TERMINATE);
589                 /* the use of UNISTR2 here is non-standard. */
590                 r_t->uni_trust_dom_name[i].offset = 0x1;
591         }
592         
593         r_t->status = NT_STATUS_OK;
594 }
595
596 /*******************************************************************
597  Reads or writes an NET_R_TRUST_DOM_LIST structure.
598 ********************************************************************/
599
600 BOOL net_io_r_trust_dom(const char *desc, NET_R_TRUST_DOM_LIST *r_t, prs_struct *ps, int depth)
601 {
602         uint32 value;
603
604         if (r_t == NULL)
605                  return False;
606
607         prs_debug(ps, depth, desc, "net_io_r_trust_dom");
608         depth++;
609
610         /* temporary code to give a valid response */
611         value=2;
612         if(!prs_uint32("status", ps, depth, &value))
613                  return False;
614
615         value=1;
616         if(!prs_uint32("status", ps, depth, &value))
617                  return False;
618         value=2;
619         if(!prs_uint32("status", ps, depth, &value))
620                  return False;
621
622         value=0;
623         if(!prs_uint32("status", ps, depth, &value))
624                  return False;
625
626         value=0;
627         if(!prs_uint32("status", ps, depth, &value))
628                  return False;
629
630 /* old non working code */
631 #if 0
632         int i;
633
634         for (i = 0; i < MAX_TRUST_DOMS; i++) {
635                 if (r_t->uni_trust_dom_name[i].uni_str_len == 0)
636                         break;
637                 if(!smb_io_unistr2("", &r_t->uni_trust_dom_name[i], True, ps, depth))
638                          return False;
639         }
640
641         if(!prs_ntstatus("status", ps, depth, &r_t->status))
642                  return False;
643 #endif
644         return True;
645 }
646
647
648 /*******************************************************************
649  Reads or writes an NET_Q_TRUST_DOM_LIST structure.
650 ********************************************************************/
651
652 BOOL net_io_q_trust_dom(const char *desc, NET_Q_TRUST_DOM_LIST *q_l, prs_struct *ps, int depth)
653 {
654         if (q_l == NULL)
655                  return False;
656
657         prs_debug(ps, depth, desc, "net_io_q_trust_dom");
658         depth++;
659
660         if(!prs_uint32("ptr          ", ps, depth, &q_l->ptr))
661                  return False;
662         if(!smb_io_unistr2 ("", &q_l->uni_server_name, q_l->ptr, ps, depth))
663                  return False;
664
665         return True;
666 }
667
668 /*******************************************************************
669  Inits an NET_Q_REQ_CHAL structure.
670 ********************************************************************/
671
672 void init_q_req_chal(NET_Q_REQ_CHAL *q_c,
673                      const char *logon_srv, const char *logon_clnt,
674                      const DOM_CHAL *clnt_chal)
675 {
676         DEBUG(5,("init_q_req_chal: %d\n", __LINE__));
677
678         q_c->undoc_buffer = 1; /* don't know what this buffer is */
679
680         init_unistr2(&q_c->uni_logon_srv, logon_srv , UNI_STR_TERMINATE);
681         init_unistr2(&q_c->uni_logon_clnt, logon_clnt, UNI_STR_TERMINATE);
682
683         memcpy(q_c->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data));
684
685         DEBUG(5,("init_q_req_chal: %d\n", __LINE__));
686 }
687
688 /*******************************************************************
689  Reads or writes an NET_Q_REQ_CHAL structure.
690 ********************************************************************/
691
692 BOOL net_io_q_req_chal(const char *desc,  NET_Q_REQ_CHAL *q_c, prs_struct *ps, int depth)
693 {
694         if (q_c == NULL)
695                 return False;
696
697         prs_debug(ps, depth, desc, "net_io_q_req_chal");
698         depth++;
699
700         if(!prs_align(ps))
701                 return False;
702     
703         if(!prs_uint32("undoc_buffer", ps, depth, &q_c->undoc_buffer))
704                 return False;
705
706         if(!smb_io_unistr2("", &q_c->uni_logon_srv, True, ps, depth)) /* logon server unicode string */
707                 return False;
708         if(!smb_io_unistr2("", &q_c->uni_logon_clnt, True, ps, depth)) /* logon client unicode string */
709                 return False;
710
711         if(!smb_io_chal("", &q_c->clnt_chal, ps, depth))
712                 return False;
713
714         return True;
715 }
716
717 /*******************************************************************
718  Reads or writes a structure.
719 ********************************************************************/
720
721 BOOL net_io_r_req_chal(const char *desc, NET_R_REQ_CHAL *r_c, prs_struct *ps, int depth)
722 {
723         if (r_c == NULL)
724                 return False;
725
726         prs_debug(ps, depth, desc, "net_io_r_req_chal");
727         depth++;
728
729         if(!prs_align(ps))
730                 return False;
731     
732         if(!smb_io_chal("", &r_c->srv_chal, ps, depth)) /* server challenge */
733                 return False;
734
735         if(!prs_ntstatus("status", ps, depth, &r_c->status))
736                 return False;
737
738         return True;
739 }
740
741
742 /*******************************************************************
743  Reads or writes a structure.
744 ********************************************************************/
745
746 BOOL net_io_q_auth(const char *desc, NET_Q_AUTH *q_a, prs_struct *ps, int depth)
747 {
748         if (q_a == NULL)
749                 return False;
750
751         prs_debug(ps, depth, desc, "net_io_q_auth");
752         depth++;
753
754         if(!prs_align(ps))
755                 return False;
756     
757         if(!smb_io_log_info ("", &q_a->clnt_id, ps, depth)) /* client identification info */
758                 return False;
759         if(!smb_io_chal("", &q_a->clnt_chal, ps, depth))
760                 return False;
761
762         return True;
763 }
764
765 /*******************************************************************
766  Reads or writes a structure.
767 ********************************************************************/
768
769 BOOL net_io_r_auth(const char *desc, NET_R_AUTH *r_a, prs_struct *ps, int depth)
770 {
771         if (r_a == NULL)
772                 return False;
773
774         prs_debug(ps, depth, desc, "net_io_r_auth");
775         depth++;
776
777         if(!prs_align(ps))
778                 return False;
779     
780         if(!smb_io_chal("", &r_a->srv_chal, ps, depth)) /* server challenge */
781                 return False;
782
783         if(!prs_ntstatus("status", ps, depth, &r_a->status))
784                 return False;
785
786         return True;
787 }
788
789 /*******************************************************************
790  Inits a NET_Q_AUTH_2 struct.
791 ********************************************************************/
792
793 void init_q_auth_2(NET_Q_AUTH_2 *q_a,
794                 const char *logon_srv, const char *acct_name, uint16 sec_chan, const char *comp_name,
795                 const DOM_CHAL *clnt_chal, uint32 clnt_flgs)
796 {
797         DEBUG(5,("init_q_auth_2: %d\n", __LINE__));
798
799         init_log_info(&q_a->clnt_id, logon_srv, acct_name, sec_chan, comp_name);
800         memcpy(q_a->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data));
801         q_a->clnt_flgs.neg_flags = clnt_flgs;
802
803         DEBUG(5,("init_q_auth_2: %d\n", __LINE__));
804 }
805
806 /*******************************************************************
807  Reads or writes a structure.
808 ********************************************************************/
809
810 BOOL net_io_q_auth_2(const char *desc, NET_Q_AUTH_2 *q_a, prs_struct *ps, int depth)
811 {
812         if (q_a == NULL)
813                 return False;
814
815         prs_debug(ps, depth, desc, "net_io_q_auth_2");
816         depth++;
817
818         if(!prs_align(ps))
819                 return False;
820     
821         if(!smb_io_log_info ("", &q_a->clnt_id, ps, depth)) /* client identification info */
822                 return False;
823         if(!smb_io_chal("", &q_a->clnt_chal, ps, depth))
824                 return False;
825         if(!net_io_neg_flags("", &q_a->clnt_flgs, ps, depth))
826                 return False;
827
828         return True;
829 }
830
831 /*******************************************************************
832  Reads or writes a structure.
833 ********************************************************************/
834
835 BOOL net_io_r_auth_2(const char *desc, NET_R_AUTH_2 *r_a, prs_struct *ps, int depth)
836 {
837         if (r_a == NULL)
838                 return False;
839
840         prs_debug(ps, depth, desc, "net_io_r_auth_2");
841         depth++;
842
843         if(!prs_align(ps))
844                 return False;
845     
846         if(!smb_io_chal("", &r_a->srv_chal, ps, depth)) /* server challenge */
847                 return False;
848         if(!net_io_neg_flags("", &r_a->srv_flgs, ps, depth))
849                 return False;
850
851         if(!prs_ntstatus("status", ps, depth, &r_a->status))
852                 return False;
853
854         return True;
855 }
856
857 /*******************************************************************
858  Inits a NET_Q_AUTH_3 struct.
859 ********************************************************************/
860
861 void init_q_auth_3(NET_Q_AUTH_3 *q_a,
862                 const char *logon_srv, const char *acct_name, uint16 sec_chan, const char *comp_name,
863                 const DOM_CHAL *clnt_chal, uint32 clnt_flgs)
864 {
865         DEBUG(5,("init_q_auth_3: %d\n", __LINE__));
866
867         init_log_info(&q_a->clnt_id, logon_srv, acct_name, sec_chan, comp_name);
868         memcpy(q_a->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data));
869         q_a->clnt_flgs.neg_flags = clnt_flgs;
870
871         DEBUG(5,("init_q_auth_3: %d\n", __LINE__));
872 }
873
874 /*******************************************************************
875  Reads or writes a structure.
876 ********************************************************************/
877
878 BOOL net_io_q_auth_3(const char *desc, NET_Q_AUTH_3 *q_a, prs_struct *ps, int depth)
879 {
880         if (q_a == NULL)
881                 return False;
882
883         prs_debug(ps, depth, desc, "net_io_q_auth_3");
884         depth++;
885
886         if(!prs_align(ps))
887                 return False;
888     
889         if(!smb_io_log_info ("", &q_a->clnt_id, ps, depth)) /* client identification info */
890                 return False;
891         if(!smb_io_chal("", &q_a->clnt_chal, ps, depth))
892                 return False;
893         if(!net_io_neg_flags("", &q_a->clnt_flgs, ps, depth))
894                 return False;
895
896         return True;
897 }
898
899 /*******************************************************************
900  Reads or writes a structure.
901 ********************************************************************/
902
903 BOOL net_io_r_auth_3(const char *desc, NET_R_AUTH_3 *r_a, prs_struct *ps, int depth)
904 {
905         if (r_a == NULL)
906                 return False;
907
908         prs_debug(ps, depth, desc, "net_io_r_auth_3");
909         depth++;
910
911         if(!prs_align(ps))
912                 return False;
913     
914         if(!smb_io_chal("srv_chal", &r_a->srv_chal, ps, depth)) /* server challenge */
915                 return False;
916         if(!net_io_neg_flags("srv_flgs", &r_a->srv_flgs, ps, depth))
917                 return False;
918         if (!prs_uint32("unknown", ps, depth, &r_a->unknown))
919                 return False;
920
921         if(!prs_ntstatus("status", ps, depth, &r_a->status))
922                 return False;
923
924         return True;
925 }
926
927
928 /*******************************************************************
929  Inits a NET_Q_SRV_PWSET.
930 ********************************************************************/
931
932 void init_q_srv_pwset(NET_Q_SRV_PWSET *q_s,
933                 const char *logon_srv, const char *sess_key, const char *acct_name, 
934                 uint16 sec_chan, const char *comp_name,
935                 DOM_CRED *cred, uchar hashed_mach_pwd[16])
936 {
937         unsigned char nt_cypher[16];
938         
939         DEBUG(5,("init_q_srv_pwset\n"));
940         
941         /* Process the new password. */
942         cred_hash3( nt_cypher, hashed_mach_pwd, (const unsigned char *)sess_key, 1);
943
944         init_clnt_info(&q_s->clnt_id, logon_srv, acct_name, sec_chan, comp_name, cred);
945
946         memcpy(q_s->pwd, nt_cypher, sizeof(q_s->pwd)); 
947 }
948
949 /*******************************************************************
950  Reads or writes a structure.
951 ********************************************************************/
952
953 BOOL net_io_q_srv_pwset(const char *desc, NET_Q_SRV_PWSET *q_s, prs_struct *ps, int depth)
954 {
955         if (q_s == NULL)
956                 return False;
957
958         prs_debug(ps, depth, desc, "net_io_q_srv_pwset");
959         depth++;
960
961         if(!prs_align(ps))
962                 return False;
963     
964         if(!smb_io_clnt_info("", &q_s->clnt_id, ps, depth)) /* client identification/authentication info */
965                 return False;
966         if(!prs_uint8s (False, "pwd", ps, depth, q_s->pwd, 16)) /* new password - undocumented */
967                 return False;
968
969         return True;
970 }
971
972 /*******************************************************************
973  Reads or writes a structure.
974 ********************************************************************/
975
976 BOOL net_io_r_srv_pwset(const char *desc, NET_R_SRV_PWSET *r_s, prs_struct *ps, int depth)
977 {
978         if (r_s == NULL)
979                 return False;
980
981         prs_debug(ps, depth, desc, "net_io_r_srv_pwset");
982         depth++;
983
984         if(!prs_align(ps))
985                 return False;
986     
987         if(!smb_io_cred("", &r_s->srv_cred, ps, depth)) /* server challenge */
988                 return False;
989
990         if(!prs_ntstatus("status", ps, depth, &r_s->status))
991                 return False;
992
993         return True;
994 }
995
996 /*************************************************************************
997  Init DOM_SID2 array from a string containing multiple sids
998  *************************************************************************/
999
1000 static int init_dom_sid2s(TALLOC_CTX *ctx, const char *sids_str, DOM_SID2 **ppsids)
1001 {
1002         const char *ptr;
1003         pstring s2;
1004         int count = 0;
1005
1006         DEBUG(4,("init_dom_sid2s: %s\n", sids_str ? sids_str:""));
1007
1008         *ppsids = NULL;
1009
1010         if(sids_str) {
1011                 int number;
1012                 DOM_SID2 *sids;
1013
1014                 /* Count the number of valid SIDs. */
1015                 for (count = 0, ptr = sids_str; next_token(&ptr, s2, NULL, sizeof(s2)); ) {
1016                         DOM_SID tmpsid;
1017                         if (string_to_sid(&tmpsid, s2))
1018                                 count++;
1019                 }
1020
1021                 /* Now allocate space for them. */
1022                 *ppsids = TALLOC_ZERO_ARRAY(ctx, DOM_SID2, count);
1023                 if (*ppsids == NULL)
1024                         return 0;
1025
1026                 sids = *ppsids;
1027
1028                 for (number = 0, ptr = sids_str; next_token(&ptr, s2, NULL, sizeof(s2)); ) {
1029                         DOM_SID tmpsid;
1030                         if (string_to_sid(&tmpsid, s2)) {
1031                                 /* count only valid sids */
1032                                 init_dom_sid2(&sids[number], &tmpsid);
1033                                 number++;
1034                         }
1035                 }
1036         }
1037
1038         return count;
1039 }
1040
1041 /*******************************************************************
1042  Inits a NET_ID_INFO_1 structure.
1043 ********************************************************************/
1044
1045 void init_id_info1(NET_ID_INFO_1 *id, const char *domain_name,
1046                                 uint32 param_ctrl, uint32 log_id_low, uint32 log_id_high,
1047                                 const char *user_name, const char *wksta_name,
1048                                 const char *sess_key,
1049                                 unsigned char lm_cypher[16], unsigned char nt_cypher[16])
1050 {
1051         unsigned char lm_owf[16];
1052         unsigned char nt_owf[16];
1053
1054         DEBUG(5,("init_id_info1: %d\n", __LINE__));
1055
1056         id->ptr_id_info1 = 1;
1057
1058         id->param_ctrl = param_ctrl;
1059         init_logon_id(&id->logon_id, log_id_low, log_id_high);
1060
1061
1062         if (lm_cypher && nt_cypher) {
1063                 unsigned char key[16];
1064 #ifdef DEBUG_PASSWORD
1065                 DEBUG(100,("lm cypher:"));
1066                 dump_data(100, (char *)lm_cypher, 16);
1067
1068                 DEBUG(100,("nt cypher:"));
1069                 dump_data(100, (char *)nt_cypher, 16);
1070 #endif
1071
1072                 memset(key, 0, 16);
1073                 memcpy(key, sess_key, 8);
1074
1075                 memcpy(lm_owf, lm_cypher, 16);
1076                 SamOEMhash(lm_owf, key, 16);
1077                 memcpy(nt_owf, nt_cypher, 16);
1078                 SamOEMhash(nt_owf, key, 16);
1079
1080 #ifdef DEBUG_PASSWORD
1081                 DEBUG(100,("encrypt of lm owf password:"));
1082                 dump_data(100, (char *)lm_owf, 16);
1083
1084                 DEBUG(100,("encrypt of nt owf password:"));
1085                 dump_data(100, (char *)nt_owf, 16);
1086 #endif
1087                 /* set up pointers to cypher blocks */
1088                 lm_cypher = lm_owf;
1089                 nt_cypher = nt_owf;
1090         }
1091
1092         init_owf_info(&id->lm_owf, lm_cypher);
1093         init_owf_info(&id->nt_owf, nt_cypher);
1094
1095         init_unistr2(&id->uni_domain_name, domain_name, UNI_FLAGS_NONE);
1096         init_uni_hdr(&id->hdr_domain_name, &id->uni_domain_name);
1097         init_unistr2(&id->uni_user_name, user_name, UNI_FLAGS_NONE);
1098         init_uni_hdr(&id->hdr_user_name, &id->uni_user_name);
1099         init_unistr2(&id->uni_wksta_name, wksta_name, UNI_FLAGS_NONE);
1100         init_uni_hdr(&id->hdr_wksta_name, &id->uni_wksta_name);
1101 }
1102
1103 /*******************************************************************
1104  Reads or writes an NET_ID_INFO_1 structure.
1105 ********************************************************************/
1106
1107 static BOOL net_io_id_info1(const char *desc,  NET_ID_INFO_1 *id, prs_struct *ps, int depth)
1108 {
1109         if (id == NULL)
1110                 return False;
1111
1112         prs_debug(ps, depth, desc, "net_io_id_info1");
1113         depth++;
1114
1115         if(!prs_align(ps))
1116                 return False;
1117         
1118         if(!prs_uint32("ptr_id_info1", ps, depth, &id->ptr_id_info1))
1119                 return False;
1120
1121         if (id->ptr_id_info1 != 0) {
1122                 if(!smb_io_unihdr("unihdr", &id->hdr_domain_name, ps, depth))
1123                         return False;
1124
1125                 if(!prs_uint32("param_ctrl", ps, depth, &id->param_ctrl))
1126                         return False;
1127                 if(!smb_io_logon_id("", &id->logon_id, ps, depth))
1128                         return False;
1129
1130                 if(!smb_io_unihdr("unihdr", &id->hdr_user_name, ps, depth))
1131                         return False;
1132                 if(!smb_io_unihdr("unihdr", &id->hdr_wksta_name, ps, depth))
1133                         return False;
1134
1135                 if(!smb_io_owf_info("", &id->lm_owf, ps, depth))
1136                         return False;
1137                 if(!smb_io_owf_info("", &id->nt_owf, ps, depth))
1138                         return False;
1139
1140                 if(!smb_io_unistr2("unistr2", &id->uni_domain_name,
1141                                 id->hdr_domain_name.buffer, ps, depth))
1142                         return False;
1143                 if(!smb_io_unistr2("unistr2", &id->uni_user_name,
1144                                 id->hdr_user_name.buffer, ps, depth))
1145                         return False;
1146                 if(!smb_io_unistr2("unistr2", &id->uni_wksta_name,
1147                                 id->hdr_wksta_name.buffer, ps, depth))
1148                         return False;
1149         }
1150
1151         return True;
1152 }
1153
1154 /*******************************************************************
1155 Inits a NET_ID_INFO_2 structure.
1156
1157 This is a network logon packet. The log_id parameters
1158 are what an NT server would generate for LUID once the
1159 user is logged on. I don't think we care about them.
1160
1161 Note that this has no access to the NT and LM hashed passwords,
1162 so it forwards the challenge, and the NT and LM responses (24
1163 bytes each) over the secure channel to the Domain controller
1164 for it to say yea or nay. This is the preferred method of 
1165 checking for a logon as it doesn't export the password
1166 hashes to anyone who has compromised the secure channel. JRA.
1167 ********************************************************************/
1168
1169 void init_id_info2(NET_ID_INFO_2 * id, const char *domain_name,
1170                    uint32 param_ctrl,
1171                    uint32 log_id_low, uint32 log_id_high,
1172                    const char *user_name, const char *wksta_name,
1173                    const uchar lm_challenge[8],
1174                    const uchar * lm_chal_resp, size_t lm_chal_resp_len,
1175                    const uchar * nt_chal_resp, size_t nt_chal_resp_len)
1176 {
1177
1178         DEBUG(5,("init_id_info2: %d\n", __LINE__));
1179
1180         id->ptr_id_info2 = 1;
1181
1182         id->param_ctrl = param_ctrl;
1183         init_logon_id(&id->logon_id, log_id_low, log_id_high);
1184
1185         memcpy(id->lm_chal, lm_challenge, sizeof(id->lm_chal));
1186         init_str_hdr(&id->hdr_nt_chal_resp, nt_chal_resp_len, nt_chal_resp_len, (nt_chal_resp != NULL) ? 1 : 0);
1187         init_str_hdr(&id->hdr_lm_chal_resp, lm_chal_resp_len, lm_chal_resp_len, (lm_chal_resp != NULL) ? 1 : 0);
1188
1189         init_unistr2(&id->uni_domain_name, domain_name, UNI_FLAGS_NONE);
1190         init_uni_hdr(&id->hdr_domain_name, &id->uni_domain_name);
1191         init_unistr2(&id->uni_user_name, user_name, UNI_FLAGS_NONE);
1192         init_uni_hdr(&id->hdr_user_name, &id->uni_user_name);
1193         init_unistr2(&id->uni_wksta_name, wksta_name, UNI_FLAGS_NONE);
1194         init_uni_hdr(&id->hdr_wksta_name, &id->uni_wksta_name);
1195
1196         init_string2(&id->nt_chal_resp, (const char *)nt_chal_resp, nt_chal_resp_len, nt_chal_resp_len);
1197         init_string2(&id->lm_chal_resp, (const char *)lm_chal_resp, lm_chal_resp_len, lm_chal_resp_len);
1198
1199 }
1200
1201 /*******************************************************************
1202  Reads or writes an NET_ID_INFO_2 structure.
1203 ********************************************************************/
1204
1205 static BOOL net_io_id_info2(const char *desc,  NET_ID_INFO_2 *id, prs_struct *ps, int depth)
1206 {
1207         if (id == NULL)
1208                 return False;
1209
1210         prs_debug(ps, depth, desc, "net_io_id_info2");
1211         depth++;
1212
1213         if(!prs_align(ps))
1214                 return False;
1215         
1216         if(!prs_uint32("ptr_id_info2", ps, depth, &id->ptr_id_info2))
1217                 return False;
1218
1219         if (id->ptr_id_info2 != 0) {
1220                 if(!smb_io_unihdr("unihdr", &id->hdr_domain_name, ps, depth))
1221                         return False;
1222
1223                 if(!prs_uint32("param_ctrl", ps, depth, &id->param_ctrl))
1224                         return False;
1225                 if(!smb_io_logon_id("", &id->logon_id, ps, depth))
1226                         return False;
1227
1228                 if(!smb_io_unihdr("unihdr", &id->hdr_user_name, ps, depth))
1229                         return False;
1230                 if(!smb_io_unihdr("unihdr", &id->hdr_wksta_name, ps, depth))
1231                         return False;
1232
1233                 if(!prs_uint8s (False, "lm_chal", ps, depth, id->lm_chal, 8)) /* lm 8 byte challenge */
1234                         return False;
1235
1236                 if(!smb_io_strhdr("hdr_nt_chal_resp", &id->hdr_nt_chal_resp, ps, depth))
1237                         return False;
1238                 if(!smb_io_strhdr("hdr_lm_chal_resp", &id->hdr_lm_chal_resp, ps, depth))
1239                         return False;
1240
1241                 if(!smb_io_unistr2("uni_domain_name", &id->uni_domain_name,
1242                                 id->hdr_domain_name.buffer, ps, depth))
1243                         return False;
1244                 if(!smb_io_unistr2("uni_user_name  ", &id->uni_user_name,
1245                                 id->hdr_user_name.buffer, ps, depth))
1246                         return False;
1247                 if(!smb_io_unistr2("uni_wksta_name ", &id->uni_wksta_name,
1248                                 id->hdr_wksta_name.buffer, ps, depth))
1249                         return False;
1250                 if(!smb_io_string2("nt_chal_resp", &id->nt_chal_resp,
1251                                 id->hdr_nt_chal_resp.buffer, ps, depth))
1252                         return False;
1253                 if(!smb_io_string2("lm_chal_resp", &id->lm_chal_resp,
1254                                 id->hdr_lm_chal_resp.buffer, ps, depth))
1255                         return False;
1256         }
1257
1258         return True;
1259 }
1260
1261
1262 /*******************************************************************
1263  Inits a DOM_SAM_INFO structure.
1264 ********************************************************************/
1265
1266 void init_sam_info(DOM_SAM_INFO *sam,
1267                                 const char *logon_srv, const char *comp_name,
1268                                 DOM_CRED *clnt_cred,
1269                                 DOM_CRED *rtn_cred, uint16 logon_level,
1270                                 NET_ID_INFO_CTR *ctr)
1271 {
1272         DEBUG(5,("init_sam_info: %d\n", __LINE__));
1273
1274         init_clnt_info2(&sam->client, logon_srv, comp_name, clnt_cred);
1275
1276         if (rtn_cred != NULL) {
1277                 sam->ptr_rtn_cred = 1;
1278                 memcpy(&sam->rtn_cred, rtn_cred, sizeof(sam->rtn_cred));
1279         } else {
1280                 sam->ptr_rtn_cred = 0;
1281         }
1282
1283         sam->logon_level  = logon_level;
1284         sam->ctr          = ctr;
1285 }
1286
1287 /*******************************************************************
1288  Reads or writes a DOM_SAM_INFO structure.
1289 ********************************************************************/
1290
1291 static BOOL net_io_id_info_ctr(const char *desc, NET_ID_INFO_CTR **pp_ctr, prs_struct *ps, int depth)
1292 {
1293         NET_ID_INFO_CTR *ctr = *pp_ctr;
1294
1295         prs_debug(ps, depth, desc, "smb_io_sam_info");
1296         depth++;
1297
1298         if (UNMARSHALLING(ps)) {
1299                 ctr = *pp_ctr = PRS_ALLOC_MEM(ps, NET_ID_INFO_CTR, 1);
1300                 if (ctr == NULL)
1301                         return False;
1302         }
1303         
1304         if (ctr == NULL)
1305                 return False;
1306
1307         /* don't 4-byte align here! */
1308
1309         if(!prs_uint16("switch_value ", ps, depth, &ctr->switch_value))
1310                 return False;
1311
1312         switch (ctr->switch_value) {
1313         case 1:
1314                 if(!net_io_id_info1("", &ctr->auth.id1, ps, depth))
1315                         return False;
1316                 break;
1317         case 2:
1318                 if(!net_io_id_info2("", &ctr->auth.id2, ps, depth))
1319                         return False;
1320                 break;
1321         default:
1322                 /* PANIC! */
1323                 DEBUG(4,("smb_io_sam_info: unknown switch_value!\n"));
1324                 break;
1325         }
1326
1327         return True;
1328 }
1329
1330 /*******************************************************************
1331  Reads or writes a DOM_SAM_INFO structure.
1332  ********************************************************************/
1333
1334 static BOOL smb_io_sam_info(const char *desc, DOM_SAM_INFO *sam, prs_struct *ps, int depth)
1335 {
1336         if (sam == NULL)
1337                 return False;
1338
1339         prs_debug(ps, depth, desc, "smb_io_sam_info");
1340         depth++;
1341
1342         if(!prs_align(ps))
1343                 return False;
1344         
1345         if(!smb_io_clnt_info2("", &sam->client, ps, depth))
1346                 return False;
1347
1348         if(!prs_uint32("ptr_rtn_cred ", ps, depth, &sam->ptr_rtn_cred))
1349                 return False;
1350         if(!smb_io_cred("", &sam->rtn_cred, ps, depth))
1351                 return False;
1352
1353         if(!prs_uint16("logon_level  ", ps, depth, &sam->logon_level))
1354                 return False;
1355
1356         if (sam->logon_level != 0) {
1357                 if(!net_io_id_info_ctr("logon_info", &sam->ctr, ps, depth))
1358                         return False;
1359         }
1360
1361         return True;
1362 }
1363
1364 /*************************************************************************
1365  Inits a NET_USER_INFO_3 structure.
1366
1367  This is a network logon reply packet, and contains much information about
1368  the user.  This information is passed as a (very long) paramater list
1369  to avoid having to link in the PASSDB code to every program that deals 
1370  with this file.
1371  *************************************************************************/
1372
1373 void init_net_user_info3(TALLOC_CTX *ctx, NET_USER_INFO_3 *usr, 
1374                          uint32                user_rid,
1375                          uint32                group_rid,
1376
1377                          const char*            user_name,
1378                          const char*            full_name,
1379                          const char*            home_dir,
1380                          const char*            dir_drive,
1381                          const char*            logon_script,
1382                          const char*            profile_path,
1383
1384                          time_t unix_logon_time,
1385                          time_t unix_logoff_time,
1386                          time_t unix_kickoff_time,
1387                          time_t unix_pass_last_set_time,
1388                          time_t unix_pass_can_change_time,
1389                          time_t unix_pass_must_change_time,
1390                          
1391                          uint16 logon_count, uint16 bad_pw_count,
1392                          uint32 num_groups, const DOM_GID *gids,
1393                          uint32 user_flgs, uchar user_session_key[16],
1394                          uchar lm_session_key[16],
1395                          const char *logon_srv, const char *logon_dom,
1396                          const DOM_SID *dom_sid, const char *other_sids)
1397 {
1398         /* only cope with one "other" sid, right now. */
1399         /* need to count the number of space-delimited sids */
1400         unsigned int i;
1401         int num_other_sids = 0;
1402         
1403         NTTIME          logon_time, logoff_time, kickoff_time,
1404                         pass_last_set_time, pass_can_change_time,
1405                         pass_must_change_time;
1406
1407         ZERO_STRUCTP(usr);
1408
1409         usr->ptr_user_info = 1; /* yes, we're bothering to put USER_INFO data here */
1410
1411         /* Create NTTIME structs */
1412         unix_to_nt_time (&logon_time,            unix_logon_time);
1413         unix_to_nt_time (&logoff_time,           unix_logoff_time);
1414         unix_to_nt_time (&kickoff_time,          unix_kickoff_time);
1415         unix_to_nt_time (&pass_last_set_time,    unix_pass_last_set_time);
1416         unix_to_nt_time (&pass_can_change_time,  unix_pass_can_change_time);
1417         unix_to_nt_time (&pass_must_change_time, unix_pass_must_change_time);
1418
1419         usr->logon_time            = logon_time;
1420         usr->logoff_time           = logoff_time;
1421         usr->kickoff_time          = kickoff_time;
1422         usr->pass_last_set_time    = pass_last_set_time;
1423         usr->pass_can_change_time  = pass_can_change_time;
1424         usr->pass_must_change_time = pass_must_change_time;
1425
1426         usr->logon_count = logon_count;
1427         usr->bad_pw_count = bad_pw_count;
1428
1429         usr->user_rid = user_rid;
1430         usr->group_rid = group_rid;
1431         usr->num_groups = num_groups;
1432
1433         usr->buffer_groups = 1; /* indicates fill in groups, below, even if there are none */
1434         usr->user_flgs = user_flgs;
1435
1436         if (user_session_key != NULL)
1437                 memcpy(usr->user_sess_key, user_session_key, sizeof(usr->user_sess_key));
1438         else
1439                 memset((char *)usr->user_sess_key, '\0', sizeof(usr->user_sess_key));
1440
1441         usr->buffer_dom_id = dom_sid ? 1 : 0; /* yes, we're bothering to put a domain SID in */
1442
1443         memset((char *)usr->lm_sess_key, '\0', sizeof(usr->lm_sess_key));
1444         memset(&usr->acct_flags, '\0', sizeof(usr->acct_flags));
1445
1446         for (i=0; i<7; i++) {
1447                 memset(&usr->unknown[i], '\0', sizeof(usr->unknown));
1448         }
1449
1450         if (lm_session_key != NULL) {
1451                 memcpy(usr->lm_sess_key, lm_session_key, sizeof(usr->lm_sess_key));
1452         }
1453
1454         num_other_sids = init_dom_sid2s(ctx, other_sids, &usr->other_sids);
1455
1456         usr->num_other_sids = num_other_sids;
1457         usr->buffer_other_sids = (num_other_sids != 0) ? 1 : 0; 
1458         
1459         init_unistr2(&usr->uni_user_name, user_name, UNI_FLAGS_NONE);
1460         init_uni_hdr(&usr->hdr_user_name, &usr->uni_user_name);
1461         init_unistr2(&usr->uni_full_name, full_name, UNI_FLAGS_NONE);
1462         init_uni_hdr(&usr->hdr_full_name, &usr->uni_full_name);
1463         init_unistr2(&usr->uni_logon_script, logon_script, UNI_FLAGS_NONE);
1464         init_uni_hdr(&usr->hdr_logon_script, &usr->uni_logon_script);
1465         init_unistr2(&usr->uni_profile_path, profile_path, UNI_FLAGS_NONE);
1466         init_uni_hdr(&usr->hdr_profile_path, &usr->uni_profile_path);
1467         init_unistr2(&usr->uni_home_dir, home_dir, UNI_FLAGS_NONE);
1468         init_uni_hdr(&usr->hdr_home_dir, &usr->uni_home_dir);
1469         init_unistr2(&usr->uni_dir_drive, dir_drive, UNI_FLAGS_NONE);
1470         init_uni_hdr(&usr->hdr_dir_drive, &usr->uni_dir_drive);
1471
1472         usr->num_groups2 = num_groups;
1473
1474         usr->gids = TALLOC_ZERO_ARRAY(ctx,DOM_GID,num_groups);
1475         if (usr->gids == NULL && num_groups>0)
1476                 return;
1477
1478         for (i = 0; i < num_groups; i++) 
1479                 usr->gids[i] = gids[i]; 
1480                 
1481         init_unistr2(&usr->uni_logon_srv, logon_srv, UNI_FLAGS_NONE);
1482         init_uni_hdr(&usr->hdr_logon_srv, &usr->uni_logon_srv);
1483         init_unistr2(&usr->uni_logon_dom, logon_dom, UNI_FLAGS_NONE);
1484         init_uni_hdr(&usr->hdr_logon_dom, &usr->uni_logon_dom);
1485
1486         init_dom_sid2(&usr->dom_sid, dom_sid);
1487         /* "other" sids are set up above */
1488 }
1489
1490 /*******************************************************************
1491  This code has been modified to cope with a NET_USER_INFO_2 - which is
1492  exactly the same as a NET_USER_INFO_3, minus the other sids parameters.
1493  We use validation level to determine if we're marshalling a info 2 or
1494  INFO_3 - be we always return an INFO_3. Based on code donated by Marc
1495  Jacobsen at HP. JRA.
1496 ********************************************************************/
1497
1498 BOOL net_io_user_info3(const char *desc, NET_USER_INFO_3 *usr, prs_struct *ps, 
1499                        int depth, uint16 validation_level, BOOL kerb_validation_level)
1500 {
1501         unsigned int i;
1502
1503         if (usr == NULL)
1504                 return False;
1505
1506         prs_debug(ps, depth, desc, "net_io_user_info3");
1507         depth++;
1508
1509         if (UNMARSHALLING(ps))
1510                 ZERO_STRUCTP(usr);
1511
1512         if(!prs_align(ps))
1513                 return False;
1514         
1515         if(!prs_uint32("ptr_user_info ", ps, depth, &usr->ptr_user_info))
1516                 return False;
1517
1518         if (usr->ptr_user_info == 0)
1519                 return True;
1520
1521         if(!smb_io_time("logon time", &usr->logon_time, ps, depth)) /* logon time */
1522                 return False;
1523         if(!smb_io_time("logoff time", &usr->logoff_time, ps, depth)) /* logoff time */
1524                 return False;
1525         if(!smb_io_time("kickoff time", &usr->kickoff_time, ps, depth)) /* kickoff time */
1526                 return False;
1527         if(!smb_io_time("last set time", &usr->pass_last_set_time, ps, depth)) /* password last set time */
1528                 return False;
1529         if(!smb_io_time("can change time", &usr->pass_can_change_time , ps, depth)) /* password can change time */
1530                 return False;
1531         if(!smb_io_time("must change time", &usr->pass_must_change_time, ps, depth)) /* password must change time */
1532                 return False;
1533
1534         if(!smb_io_unihdr("hdr_user_name", &usr->hdr_user_name, ps, depth)) /* username unicode string header */
1535                 return False;
1536         if(!smb_io_unihdr("hdr_full_name", &usr->hdr_full_name, ps, depth)) /* user's full name unicode string header */
1537                 return False;
1538         if(!smb_io_unihdr("hdr_logon_script", &usr->hdr_logon_script, ps, depth)) /* logon script unicode string header */
1539                 return False;
1540         if(!smb_io_unihdr("hdr_profile_path", &usr->hdr_profile_path, ps, depth)) /* profile path unicode string header */
1541                 return False;
1542         if(!smb_io_unihdr("hdr_home_dir", &usr->hdr_home_dir, ps, depth)) /* home directory unicode string header */
1543                 return False;
1544         if(!smb_io_unihdr("hdr_dir_drive", &usr->hdr_dir_drive, ps, depth)) /* home directory drive unicode string header */
1545                 return False;
1546
1547         if(!prs_uint16("logon_count   ", ps, depth, &usr->logon_count))  /* logon count */
1548                 return False;
1549         if(!prs_uint16("bad_pw_count  ", ps, depth, &usr->bad_pw_count)) /* bad password count */
1550                 return False;
1551
1552         if(!prs_uint32("user_rid      ", ps, depth, &usr->user_rid))       /* User RID */
1553                 return False;
1554         if(!prs_uint32("group_rid     ", ps, depth, &usr->group_rid))      /* Group RID */
1555                 return False;
1556         if(!prs_uint32("num_groups    ", ps, depth, &usr->num_groups))    /* num groups */
1557                 return False;
1558         if(!prs_uint32("buffer_groups ", ps, depth, &usr->buffer_groups)) /* undocumented buffer pointer to groups. */
1559                 return False;
1560         if(!prs_uint32("user_flgs     ", ps, depth, &usr->user_flgs))     /* user flags */
1561                 return False;
1562
1563         if(!prs_uint8s(False, "user_sess_key", ps, depth, usr->user_sess_key, 16)) /* user session key */
1564                 return False;
1565
1566         if(!smb_io_unihdr("hdr_logon_srv", &usr->hdr_logon_srv, ps, depth)) /* logon server unicode string header */
1567                 return False;
1568         if(!smb_io_unihdr("hdr_logon_dom", &usr->hdr_logon_dom, ps, depth)) /* logon domain unicode string header */
1569                 return False;
1570
1571         if(!prs_uint32("buffer_dom_id ", ps, depth, &usr->buffer_dom_id)) /* undocumented logon domain id pointer */
1572                 return False;
1573
1574         if(!prs_uint8s(False, "lm_sess_key", ps, depth, usr->lm_sess_key, 8)) /* lm session key */
1575                 return False;
1576
1577         if(!prs_uint32("acct_flags ", ps, depth, &usr->acct_flags)) /* Account flags  */
1578                 return False;
1579
1580         for (i = 0; i < 7; i++)
1581         {
1582                 if (!prs_uint32("unkown", ps, depth, &usr->unknown[i])) /* unknown */
1583                         return False;
1584         }
1585
1586         if (validation_level == 3) {
1587                 if(!prs_uint32("num_other_sids", ps, depth, &usr->num_other_sids)) /* 0 - num_sids */
1588                         return False;
1589                 if(!prs_uint32("buffer_other_sids", ps, depth, &usr->buffer_other_sids)) /* NULL - undocumented pointer to SIDs. */
1590                         return False;
1591         } else {
1592                 if (UNMARSHALLING(ps)) {
1593                         usr->num_other_sids = 0;
1594                         usr->buffer_other_sids = 0;
1595                 }
1596         }
1597                 
1598         /* get kerb validation info (not really part of user_info_3) - Guenther */
1599
1600         if (kerb_validation_level) {
1601
1602                 if(!prs_uint32("ptr_res_group_dom_sid", ps, depth, &usr->ptr_res_group_dom_sid))
1603                         return False;
1604                 if(!prs_uint32("res_group_count", ps, depth, &usr->res_group_count))
1605                         return False;
1606                 if(!prs_uint32("ptr_res_groups", ps, depth, &usr->ptr_res_groups))
1607                         return False;
1608         }
1609
1610         if(!smb_io_unistr2("uni_user_name", &usr->uni_user_name, usr->hdr_user_name.buffer, ps, depth)) /* username unicode string */
1611                 return False;
1612         if(!smb_io_unistr2("uni_full_name", &usr->uni_full_name, usr->hdr_full_name.buffer, ps, depth)) /* user's full name unicode string */
1613                 return False;
1614         if(!smb_io_unistr2("uni_logon_script", &usr->uni_logon_script, usr->hdr_logon_script.buffer, ps, depth)) /* logon script unicode string */
1615                 return False;
1616         if(!smb_io_unistr2("uni_profile_path", &usr->uni_profile_path, usr->hdr_profile_path.buffer, ps, depth)) /* profile path unicode string */
1617                 return False;
1618         if(!smb_io_unistr2("uni_home_dir", &usr->uni_home_dir, usr->hdr_home_dir.buffer, ps, depth)) /* home directory unicode string */
1619                 return False;
1620         if(!smb_io_unistr2("uni_dir_drive", &usr->uni_dir_drive, usr->hdr_dir_drive.buffer, ps, depth)) /* home directory drive unicode string */
1621                 return False;
1622
1623         if(!prs_align(ps))
1624                 return False;
1625
1626         if (usr->num_groups > 0) {
1627
1628                 if(!prs_uint32("num_groups2   ", ps, depth, &usr->num_groups2))        /* num groups2 */
1629                         return False;
1630
1631                 if (usr->num_groups != usr->num_groups2) {
1632                         DEBUG(3,("net_io_user_info3: num_groups mismatch! (%d != %d)\n", 
1633                         usr->num_groups, usr->num_groups2));
1634                         return False;
1635                 }
1636
1637
1638                 if (UNMARSHALLING(ps)) {
1639                         usr->gids = PRS_ALLOC_MEM(ps, DOM_GID, usr->num_groups);
1640                         if (usr->gids == NULL)
1641                                 return False;
1642                 }
1643
1644                 for (i = 0; i < usr->num_groups; i++) {
1645                         if(!smb_io_gid("", &usr->gids[i], ps, depth)) /* group info */
1646                                 return False;
1647                 }
1648                 
1649         }
1650
1651         if(!smb_io_unistr2("uni_logon_srv", &usr->uni_logon_srv, usr->hdr_logon_srv.buffer, ps, depth)) /* logon server unicode string */
1652                 return False;
1653         if(!smb_io_unistr2("uni_logon_dom", &usr->uni_logon_dom, usr->hdr_logon_dom.buffer, ps, depth)) /* logon domain unicode string */
1654                 return False;
1655
1656         if(!smb_io_dom_sid2("", &usr->dom_sid, ps, depth))           /* domain SID */
1657                 return False;
1658
1659         if (usr->buffer_other_sids) {
1660
1661                 uint32 num_other_sids = usr->num_other_sids;
1662
1663                 if (!(usr->user_flgs & LOGON_EXTRA_SIDS)) {
1664                         DEBUG(10,("net_io_user_info3: user_flgs attribute does not have LOGON_EXTRA_SIDS\n"));
1665                         /* return False; */
1666                 }
1667
1668                 if (!prs_uint32("num_other_sids", ps, depth,
1669                                 &num_other_sids))
1670                         return False;
1671
1672                 if (num_other_sids != usr->num_other_sids)
1673                         return False;
1674
1675                 if (UNMARSHALLING(ps)) {
1676                         usr->other_sids = PRS_ALLOC_MEM(ps, DOM_SID2, usr->num_other_sids);
1677                         usr->other_sids_attrib =
1678                                 PRS_ALLOC_MEM(ps, uint32, usr->num_other_sids);
1679                                                                
1680                         if ((num_other_sids != 0) &&
1681                             ((usr->other_sids == NULL) ||
1682                              (usr->other_sids_attrib == NULL)))
1683                                 return False;
1684                 }
1685
1686                 /* First the pointers to the SIDS and attributes */
1687
1688                 depth++;
1689
1690                 for (i=0; i<usr->num_other_sids; i++) {
1691                         uint32 ptr = 1;
1692
1693                         if (!prs_uint32("sid_ptr", ps, depth, &ptr))
1694                                 return False;
1695
1696                         if (UNMARSHALLING(ps) && (ptr == 0))
1697                                 return False;
1698
1699                         if (!prs_uint32("attribute", ps, depth,
1700                                         &usr->other_sids_attrib[i]))
1701                                 return False;
1702                 }
1703         
1704                 for (i = 0; i < usr->num_other_sids; i++) {
1705                         if(!smb_io_dom_sid2("", &usr->other_sids[i], ps, depth)) /* other domain SIDs */
1706                                 return False;
1707                 }
1708
1709                 depth--;
1710         }
1711
1712         return True;
1713 }
1714
1715 /*******************************************************************
1716  Reads or writes a structure.
1717 ********************************************************************/
1718
1719 BOOL net_io_q_sam_logon(const char *desc, NET_Q_SAM_LOGON *q_l, prs_struct *ps, int depth)
1720 {
1721         if (q_l == NULL)
1722                 return False;
1723
1724         prs_debug(ps, depth, desc, "net_io_q_sam_logon");
1725         depth++;
1726
1727         if(!prs_align(ps))
1728                 return False;
1729         
1730         if(!smb_io_sam_info("", &q_l->sam_id, ps, depth))
1731                 return False;
1732
1733         if(!prs_align_uint16(ps))
1734                 return False;
1735         
1736         if(!prs_uint16("validation_level", ps, depth, &q_l->validation_level))
1737                 return False;
1738
1739         return True;
1740 }
1741
1742 /*******************************************************************
1743  Reads or writes a structure.
1744 ********************************************************************/
1745
1746 BOOL net_io_r_sam_logon(const char *desc, NET_R_SAM_LOGON *r_l, prs_struct *ps, int depth)
1747 {
1748         if (r_l == NULL)
1749                 return False;
1750
1751         prs_debug(ps, depth, desc, "net_io_r_sam_logon");
1752         depth++;
1753
1754         if(!prs_uint32("buffer_creds", ps, depth, &r_l->buffer_creds)) /* undocumented buffer pointer */
1755                 return False;
1756         if (&r_l->buffer_creds) {
1757                 if(!smb_io_cred("", &r_l->srv_creds, ps, depth)) /* server credentials.  server time stamp appears to be ignored. */
1758                         return False;
1759         }
1760
1761         if(!prs_uint16("switch_value", ps, depth, &r_l->switch_value))
1762                 return False;
1763         if(!prs_align(ps))
1764                 return False;
1765
1766 #if 1 /* W2k always needs this - even for bad passwd. JRA */
1767         if(!net_io_user_info3("", r_l->user, ps, depth, r_l->switch_value, False))
1768                 return False;
1769 #else
1770         if (r_l->switch_value != 0) {
1771                 if(!net_io_user_info3("", r_l->user, ps, depth, r_l->switch_value, False))
1772                         return False;
1773         }
1774 #endif
1775
1776         if(!prs_uint32("auth_resp   ", ps, depth, &r_l->auth_resp)) /* 1 - Authoritative response; 0 - Non-Auth? */
1777                 return False;
1778
1779         if(!prs_ntstatus("status      ", ps, depth, &r_l->status))
1780                 return False;
1781
1782         if(!prs_align(ps))
1783                 return False;
1784
1785         return True;
1786 }
1787
1788 /*******************************************************************
1789  Reads or writes a structure.
1790 ********************************************************************/
1791
1792 BOOL net_io_q_sam_logoff(const char *desc,  NET_Q_SAM_LOGOFF *q_l, prs_struct *ps, int depth)
1793 {
1794         if (q_l == NULL)
1795                 return False;
1796
1797         prs_debug(ps, depth, desc, "net_io_q_sam_logoff");
1798         depth++;
1799
1800         if(!prs_align(ps))
1801                 return False;
1802         
1803         if(!smb_io_sam_info("", &q_l->sam_id, ps, depth))           /* domain SID */
1804                 return False;
1805
1806         return True;
1807 }
1808
1809 /*******************************************************************
1810  Reads or writes a structure.
1811 ********************************************************************/
1812
1813 BOOL net_io_r_sam_logoff(const char *desc, NET_R_SAM_LOGOFF *r_l, prs_struct *ps, int depth)
1814 {
1815         if (r_l == NULL)
1816                 return False;
1817
1818         prs_debug(ps, depth, desc, "net_io_r_sam_logoff");
1819         depth++;
1820
1821         if(!prs_align(ps))
1822                 return False;
1823         
1824         if(!prs_uint32("buffer_creds", ps, depth, &r_l->buffer_creds)) /* undocumented buffer pointer */
1825                 return False;
1826         if(!smb_io_cred("", &r_l->srv_creds, ps, depth)) /* server credentials.  server time stamp appears to be ignored. */
1827                 return False;
1828
1829         if(!prs_ntstatus("status      ", ps, depth, &r_l->status))
1830                 return False;
1831
1832         return True;
1833 }
1834
1835 /*******************************************************************
1836 makes a NET_Q_SAM_SYNC structure.
1837 ********************************************************************/
1838 BOOL init_net_q_sam_sync(NET_Q_SAM_SYNC * q_s, const char *srv_name,
1839                          const char *cli_name, DOM_CRED *cli_creds, 
1840                          DOM_CRED *ret_creds, uint32 database_id, 
1841                          uint32 next_rid)
1842 {
1843         DEBUG(5, ("init_q_sam_sync\n"));
1844
1845         init_unistr2(&q_s->uni_srv_name, srv_name, UNI_STR_TERMINATE);
1846         init_unistr2(&q_s->uni_cli_name, cli_name, UNI_STR_TERMINATE);
1847
1848         if (cli_creds)
1849                 memcpy(&q_s->cli_creds, cli_creds, sizeof(q_s->cli_creds));
1850
1851         if (cli_creds)
1852                 memcpy(&q_s->ret_creds, ret_creds, sizeof(q_s->ret_creds));
1853         else
1854                 memset(&q_s->ret_creds, 0, sizeof(q_s->ret_creds));
1855
1856         q_s->database_id = database_id;
1857         q_s->restart_state = 0;
1858         q_s->sync_context = next_rid;
1859         q_s->max_size = 0xffff;
1860
1861         return True;
1862 }
1863
1864 /*******************************************************************
1865 reads or writes a structure.
1866 ********************************************************************/
1867 BOOL net_io_q_sam_sync(const char *desc, NET_Q_SAM_SYNC * q_s, prs_struct *ps,
1868                        int depth)
1869 {
1870         prs_debug(ps, depth, desc, "net_io_q_sam_sync");
1871         depth++;
1872
1873         if (!smb_io_unistr2("", &q_s->uni_srv_name, True, ps, depth))
1874                 return False;
1875         if (!smb_io_unistr2("", &q_s->uni_cli_name, True, ps, depth))
1876                 return False;
1877
1878         if (!smb_io_cred("", &q_s->cli_creds, ps, depth))
1879                 return False;
1880         if (!smb_io_cred("", &q_s->ret_creds, ps, depth))
1881                 return False;
1882
1883         if (!prs_uint32("database_id  ", ps, depth, &q_s->database_id))
1884                 return False;
1885         if (!prs_uint32("restart_state", ps, depth, &q_s->restart_state))
1886                 return False;
1887         if (!prs_uint32("sync_context ", ps, depth, &q_s->sync_context))
1888                 return False;
1889
1890         if (!prs_uint32("max_size", ps, depth, &q_s->max_size))
1891                 return False;
1892
1893         return True;
1894 }
1895
1896 /*******************************************************************
1897 reads or writes a structure.
1898 ********************************************************************/
1899 static BOOL net_io_sam_delta_hdr(const char *desc, SAM_DELTA_HDR * delta,
1900                                  prs_struct *ps, int depth)
1901 {
1902         prs_debug(ps, depth, desc, "net_io_sam_delta_hdr");
1903         depth++;
1904
1905         if (!prs_uint16("type", ps, depth, &delta->type))
1906                 return False;
1907         if (!prs_uint16("type2", ps, depth, &delta->type2))
1908                 return False;
1909         if (!prs_uint32("target_rid", ps, depth, &delta->target_rid))
1910                 return False;
1911
1912         if (!prs_uint32("type3", ps, depth, &delta->type3))
1913                 return False;
1914
1915         /* Not sure why we need this but it seems to be necessary to get
1916            sam deltas working. */
1917
1918         if (delta->type != 0x16) {
1919                 if (!prs_uint32("ptr_delta", ps, depth, &delta->ptr_delta))
1920                         return False;
1921         }
1922
1923         return True;
1924 }
1925
1926 /*******************************************************************
1927 reads or writes a structure.
1928 ********************************************************************/
1929 static BOOL net_io_sam_delta_mod_count(const char *desc, SAM_DELTA_MOD_COUNT *info,
1930                                    prs_struct *ps, int depth)
1931 {
1932         prs_debug(ps, depth, desc, "net_io_sam_delta_stamp");
1933         depth++;
1934
1935         if (!prs_uint32("seqnum", ps, depth, &info->seqnum))
1936                 return False;
1937         if (!prs_uint32("dom_mod_count_ptr", ps, depth, 
1938                         &info->dom_mod_count_ptr))
1939                 return False;
1940
1941         if (info->dom_mod_count_ptr) {
1942                 if (!prs_uint64("dom_mod_count", ps, depth,
1943                                 &info->dom_mod_count))
1944                         return False;
1945         }
1946
1947         return True;
1948 }
1949
1950 /*******************************************************************
1951 reads or writes a structure.
1952 ********************************************************************/
1953 static BOOL net_io_sam_domain_info(const char *desc, SAM_DOMAIN_INFO * info,
1954                                    prs_struct *ps, int depth)
1955 {
1956         prs_debug(ps, depth, desc, "net_io_sam_domain_info");
1957         depth++;
1958
1959         if (!smb_io_unihdr("hdr_dom_name", &info->hdr_dom_name, ps, depth))
1960                 return False;
1961         if (!smb_io_unihdr("hdr_oem_info", &info->hdr_oem_info, ps, depth))
1962                 return False;
1963
1964         if (!prs_uint64("force_logoff", ps, depth, &info->force_logoff))
1965                 return False;
1966         if (!prs_uint16("min_pwd_len", ps, depth, &info->min_pwd_len))
1967                 return False;
1968         if (!prs_uint16("pwd_history_len", ps, depth, &info->pwd_history_len))
1969                 return False;
1970         if (!prs_uint64("max_pwd_age", ps, depth, &info->max_pwd_age))
1971                 return False;
1972         if (!prs_uint64("min_pwd_age", ps, depth, &info->min_pwd_age))
1973                 return False;
1974         if (!prs_uint64("dom_mod_count", ps, depth, &info->dom_mod_count))
1975                 return False;
1976         if (!smb_io_time("creation_time", &info->creation_time, ps, depth))
1977                 return False;
1978         if (!prs_uint32("security_information", ps, depth, &info->security_information))
1979                 return False;
1980         if (!smb_io_bufhdr4("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
1981                 return False;
1982         if (!smb_io_lockout_string_hdr("hdr_account_lockout_string", &info->hdr_account_lockout, ps, depth))
1983                 return False;
1984         if (!smb_io_unihdr("hdr_unknown2", &info->hdr_unknown2, ps, depth))
1985                 return False;
1986         if (!smb_io_unihdr("hdr_unknown3", &info->hdr_unknown3, ps, depth))
1987                 return False;
1988         if (!smb_io_unihdr("hdr_unknown4", &info->hdr_unknown4, ps, depth))
1989                 return False;
1990         if (!prs_uint32("logon_chgpass", ps, depth, &info->logon_chgpass))
1991                 return False;
1992         if (!prs_uint32("unknown6", ps, depth, &info->unknown6))
1993                 return False;
1994         if (!prs_uint32("unknown7", ps, depth, &info->unknown7))
1995                 return False;
1996         if (!prs_uint32("unknown8", ps, depth, &info->unknown8))
1997                 return False;
1998
1999         if (!smb_io_unistr2("uni_dom_name", &info->uni_dom_name,
2000                             info->hdr_dom_name.buffer, ps, depth))
2001                 return False;
2002         if (!smb_io_unistr2("buf_oem_info", &info->buf_oem_info,
2003                             info->hdr_oem_info.buffer, ps, depth))
2004                 return False;
2005
2006         if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth))
2007                 return False;
2008
2009         if (!smb_io_account_lockout_str("account_lockout", &info->account_lockout, 
2010                                         info->hdr_account_lockout.buffer, ps, depth))
2011                 return False;
2012
2013         if (!smb_io_unistr2("buf_unknown2", &info->buf_unknown2, 
2014                             info->hdr_unknown2.buffer, ps, depth))
2015                 return False;
2016         if (!smb_io_unistr2("buf_unknown3", &info->buf_unknown3, 
2017                             info->hdr_unknown3.buffer, ps, depth))
2018                 return False;
2019         if (!smb_io_unistr2("buf_unknown4", &info->buf_unknown4, 
2020                             info->hdr_unknown4.buffer, ps, depth))
2021                 return False;
2022
2023         return True;
2024 }
2025
2026 /*******************************************************************
2027 reads or writes a structure.
2028 ********************************************************************/
2029 static BOOL net_io_sam_group_info(const char *desc, SAM_GROUP_INFO * info,
2030                                   prs_struct *ps, int depth)
2031 {
2032         prs_debug(ps, depth, desc, "net_io_sam_group_info");
2033         depth++;
2034
2035         if (!smb_io_unihdr("hdr_grp_name", &info->hdr_grp_name, ps, depth))
2036                 return False;
2037         if (!smb_io_gid("gid", &info->gid, ps, depth))
2038                 return False;
2039         if (!smb_io_unihdr("hdr_grp_desc", &info->hdr_grp_desc, ps, depth))
2040                 return False;
2041         if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
2042                 return False;
2043
2044         if (ps->data_offset + 48 > ps->buffer_size)
2045                 return False;
2046         ps->data_offset += 48;
2047
2048         if (!smb_io_unistr2("uni_grp_name", &info->uni_grp_name,
2049                             info->hdr_grp_name.buffer, ps, depth))
2050                 return False;
2051         if (!smb_io_unistr2("uni_grp_desc", &info->uni_grp_desc,
2052                             info->hdr_grp_desc.buffer, ps, depth))
2053                 return False;
2054         if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth))
2055                 return False;
2056
2057         return True;
2058 }
2059
2060 /*******************************************************************
2061 reads or writes a structure.
2062 ********************************************************************/
2063 static BOOL net_io_sam_passwd_info(const char *desc, SAM_PWD * pwd,
2064                                    prs_struct *ps, int depth)
2065 {
2066         prs_debug(ps, depth, desc, "net_io_sam_passwd_info");
2067         depth++;
2068
2069         if (!prs_uint32("unk_0 ", ps, depth, &pwd->unk_0))
2070                 return False;
2071
2072         if (!smb_io_unihdr("hdr_lm_pwd", &pwd->hdr_lm_pwd, ps, depth))
2073                 return False;
2074         if (!prs_uint8s(False, "buf_lm_pwd", ps, depth, pwd->buf_lm_pwd, 16))
2075                 return False;
2076
2077         if (!smb_io_unihdr("hdr_nt_pwd", &pwd->hdr_nt_pwd, ps, depth))
2078                 return False;
2079         if (!prs_uint8s(False, "buf_nt_pwd", ps, depth, pwd->buf_nt_pwd, 16))
2080                 return False;
2081
2082         if (!smb_io_unihdr("", &pwd->hdr_empty_lm, ps, depth))
2083                 return False;
2084         if (!smb_io_unihdr("", &pwd->hdr_empty_nt, ps, depth))
2085                 return False;
2086
2087         return True;
2088 }
2089
2090 /*******************************************************************
2091 makes a SAM_ACCOUNT_INFO structure.
2092 ********************************************************************/
2093 BOOL make_sam_account_info(SAM_ACCOUNT_INFO * info,
2094                            const UNISTR2 *user_name,
2095                            const UNISTR2 *full_name,
2096                            uint32 user_rid, uint32 group_rid,
2097                            const UNISTR2 *home_dir,
2098                            const UNISTR2 *dir_drive,
2099                            const UNISTR2 *log_scr,
2100                            const UNISTR2 *desc,
2101                            uint32 acb_info,
2102                            const UNISTR2 *prof_path,
2103                            const UNISTR2 *wkstas,
2104                            const UNISTR2 *unk_str, const UNISTR2 *mung_dial)
2105 {
2106         int len_user_name = user_name != NULL ? user_name->uni_str_len : 0;
2107         int len_full_name = full_name != NULL ? full_name->uni_str_len : 0;
2108         int len_home_dir = home_dir != NULL ? home_dir->uni_str_len : 0;
2109         int len_dir_drive = dir_drive != NULL ? dir_drive->uni_str_len : 0;
2110         int len_logon_script = log_scr != NULL ? log_scr->uni_str_len : 0;
2111         int len_profile_path = prof_path != NULL ? prof_path->uni_str_len : 0;
2112         int len_description = desc != NULL ? desc->uni_str_len : 0;
2113         int len_workstations = wkstas != NULL ? wkstas->uni_str_len : 0;
2114         int len_unknown_str = unk_str != NULL ? unk_str->uni_str_len : 0;
2115         int len_munged_dial = mung_dial != NULL ? mung_dial->uni_str_len : 0;
2116
2117         DEBUG(5, ("make_sam_account_info\n"));
2118
2119         make_uni_hdr(&info->hdr_acct_name, len_user_name);
2120         make_uni_hdr(&info->hdr_full_name, len_full_name);
2121         make_uni_hdr(&info->hdr_home_dir, len_home_dir);
2122         make_uni_hdr(&info->hdr_dir_drive, len_dir_drive);
2123         make_uni_hdr(&info->hdr_logon_script, len_logon_script);
2124         make_uni_hdr(&info->hdr_profile, len_profile_path);
2125         make_uni_hdr(&info->hdr_acct_desc, len_description);
2126         make_uni_hdr(&info->hdr_workstations, len_workstations);
2127         make_uni_hdr(&info->hdr_comment, len_unknown_str);
2128         make_uni_hdr(&info->hdr_parameters, len_munged_dial);
2129
2130         /* not present */
2131         make_bufhdr2(&info->hdr_sec_desc, 0, 0, 0);
2132
2133         info->user_rid = user_rid;
2134         info->group_rid = group_rid;
2135
2136         init_nt_time(&info->logon_time);
2137         init_nt_time(&info->logoff_time);
2138         init_nt_time(&info->pwd_last_set_time);
2139         init_nt_time(&info->acct_expiry_time);
2140
2141         info->logon_divs = 0xA8;
2142         info->ptr_logon_hrs = 0;        /* Don't care right now */
2143
2144         info->bad_pwd_count = 0;
2145         info->logon_count = 0;
2146         info->acb_info = acb_info;
2147         info->nt_pwd_present = 0;
2148         info->lm_pwd_present = 0;
2149         info->pwd_expired = 0;
2150         info->country = 0;
2151         info->codepage = 0;
2152
2153         info->unknown1 = 0x4EC;
2154         info->unknown2 = 0;
2155
2156         copy_unistr2(&info->uni_acct_name, user_name);
2157         copy_unistr2(&info->uni_full_name, full_name);
2158         copy_unistr2(&info->uni_home_dir, home_dir);
2159         copy_unistr2(&info->uni_dir_drive, dir_drive);
2160         copy_unistr2(&info->uni_logon_script, log_scr);
2161         copy_unistr2(&info->uni_profile, prof_path);
2162         copy_unistr2(&info->uni_acct_desc, desc);
2163         copy_unistr2(&info->uni_workstations, wkstas);
2164         copy_unistr2(&info->uni_comment, unk_str);
2165         copy_unistr2(&info->uni_parameters, mung_dial);
2166
2167         return True;
2168 }
2169
2170 /*******************************************************************
2171 reads or writes a structure.
2172 ********************************************************************/
2173 static BOOL net_io_sam_account_info(const char *desc, SAM_ACCOUNT_INFO *info,
2174                                 prs_struct *ps, int depth)
2175 {
2176         BUFHDR2 hdr_priv_data;
2177         uint32 i;
2178
2179         prs_debug(ps, depth, desc, "net_io_sam_account_info");
2180         depth++;
2181
2182         if (!smb_io_unihdr("hdr_acct_name", &info->hdr_acct_name, ps, depth))
2183                 return False;
2184         if (!smb_io_unihdr("hdr_full_name", &info->hdr_full_name, ps, depth))
2185                 return False;
2186
2187         if (!prs_uint32("user_rid ", ps, depth, &info->user_rid))
2188                 return False;
2189         if (!prs_uint32("group_rid", ps, depth, &info->group_rid))
2190                 return False;
2191
2192         if (!smb_io_unihdr("hdr_home_dir ", &info->hdr_home_dir, ps, depth))
2193                 return False;
2194         if (!smb_io_unihdr("hdr_dir_drive", &info->hdr_dir_drive, ps, depth))
2195                 return False;
2196         if (!smb_io_unihdr("hdr_logon_script", &info->hdr_logon_script, ps,
2197                            depth))
2198                 return False;
2199
2200         if (!smb_io_unihdr("hdr_acct_desc", &info->hdr_acct_desc, ps, depth))
2201                 return False;
2202         if (!smb_io_unihdr("hdr_workstations", &info->hdr_workstations, ps,
2203                            depth))
2204                 return False;
2205
2206         if (!smb_io_time("logon_time", &info->logon_time, ps, depth))
2207                 return False;
2208         if (!smb_io_time("logoff_time", &info->logoff_time, ps, depth))
2209                 return False;
2210
2211         if (!prs_uint32("logon_divs   ", ps, depth, &info->logon_divs))
2212                 return False;
2213         if (!prs_uint32("ptr_logon_hrs", ps, depth, &info->ptr_logon_hrs))
2214                 return False;
2215
2216         if (!prs_uint16("bad_pwd_count", ps, depth, &info->bad_pwd_count))
2217                 return False;
2218         if (!prs_uint16("logon_count", ps, depth, &info->logon_count))
2219                 return False;
2220         if (!smb_io_time("pwd_last_set_time", &info->pwd_last_set_time, ps,
2221                          depth))
2222                 return False;
2223         if (!smb_io_time("acct_expiry_time", &info->acct_expiry_time, ps, 
2224                          depth))
2225                 return False;
2226
2227         if (!prs_uint32("acb_info", ps, depth, &info->acb_info))
2228                 return False;
2229         if (!prs_uint8s(False, "nt_pwd", ps, depth, info->nt_pwd, 16))
2230                 return False;
2231         if (!prs_uint8s(False, "lm_pwd", ps, depth, info->lm_pwd, 16))
2232                 return False;
2233         if (!prs_uint8("lm_pwd_present", ps, depth, &info->lm_pwd_present))
2234                 return False;
2235         if (!prs_uint8("nt_pwd_present", ps, depth, &info->nt_pwd_present))
2236                 return False;
2237         if (!prs_uint8("pwd_expired", ps, depth, &info->pwd_expired))
2238                 return False;
2239
2240         if (!smb_io_unihdr("hdr_comment", &info->hdr_comment, ps, depth))
2241                 return False;
2242         if (!smb_io_unihdr("hdr_parameters", &info->hdr_parameters, ps, 
2243                            depth))
2244                 return False;
2245         if (!prs_uint16("country", ps, depth, &info->country))
2246                 return False;
2247         if (!prs_uint16("codepage", ps, depth, &info->codepage))
2248                 return False;
2249
2250         if (!smb_io_bufhdr2("hdr_priv_data", &hdr_priv_data, ps, depth))
2251                 return False;
2252         if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
2253                 return False;
2254         if (!smb_io_unihdr("hdr_profile", &info->hdr_profile, ps, depth))
2255                 return False;
2256
2257         for (i = 0; i < 3; i++)
2258         {
2259                 if (!smb_io_unihdr("hdr_reserved", &info->hdr_reserved[i], 
2260                                    ps, depth))
2261                         return False;                                          
2262         }
2263
2264         for (i = 0; i < 4; i++)
2265         {
2266                 if (!prs_uint32("dw_reserved", ps, depth, 
2267                                 &info->dw_reserved[i]))
2268                         return False;
2269         }
2270
2271         if (!smb_io_unistr2("uni_acct_name", &info->uni_acct_name,
2272                             info->hdr_acct_name.buffer, ps, depth))
2273                 return False;
2274         prs_align(ps);
2275         if (!smb_io_unistr2("uni_full_name", &info->uni_full_name,
2276                             info->hdr_full_name.buffer, ps, depth))
2277                 return False;
2278         prs_align(ps);
2279         if (!smb_io_unistr2("uni_home_dir ", &info->uni_home_dir,
2280                             info->hdr_home_dir.buffer, ps, depth))
2281                 return False;
2282         prs_align(ps);
2283         if (!smb_io_unistr2("uni_dir_drive", &info->uni_dir_drive,
2284                             info->hdr_dir_drive.buffer, ps, depth))
2285                 return False;
2286         prs_align(ps);
2287         if (!smb_io_unistr2("uni_logon_script", &info->uni_logon_script,
2288                             info->hdr_logon_script.buffer, ps, depth))
2289                 return False;
2290         prs_align(ps);
2291         if (!smb_io_unistr2("uni_acct_desc", &info->uni_acct_desc,
2292                             info->hdr_acct_desc.buffer, ps, depth))
2293                 return False;
2294         prs_align(ps);
2295         if (!smb_io_unistr2("uni_workstations", &info->uni_workstations,
2296                             info->hdr_workstations.buffer, ps, depth))
2297                 return False;
2298         prs_align(ps);
2299
2300         if (!prs_uint32("unknown1", ps, depth, &info->unknown1))
2301                 return False;
2302         if (!prs_uint32("unknown2", ps, depth, &info->unknown2))
2303                 return False;
2304
2305         if (!smb_io_rpc_blob("buf_logon_hrs", &info->buf_logon_hrs, ps, depth))
2306                 return False;
2307         prs_align(ps);
2308         if (!smb_io_unistr2("uni_comment", &info->uni_comment,
2309                             info->hdr_comment.buffer, ps, depth))
2310                 return False;
2311         prs_align(ps);
2312         if (!smb_io_unistr2("uni_parameters", &info->uni_parameters,
2313                             info->hdr_parameters.buffer, ps, depth))
2314                 return False;
2315         prs_align(ps);
2316         if (hdr_priv_data.buffer != 0)
2317         {
2318                 int old_offset = 0;
2319                 uint32 len = 0x44;
2320                 if (!prs_uint32("pwd_len", ps, depth, &len))
2321                         return False;
2322                 old_offset = ps->data_offset;
2323                 if (len > 0)
2324                 {
2325                         if (ps->io)
2326                         {
2327                                 /* reading */
2328                                 if (!prs_hash1(ps, ps->data_offset, len))
2329                                         return False;
2330                         }
2331                         if (!net_io_sam_passwd_info("pass", &info->pass, 
2332                                                     ps, depth))
2333                                 return False;
2334
2335                         if (!ps->io)
2336                         {
2337                                 /* writing */
2338                                 if (!prs_hash1(ps, old_offset, len))
2339                                         return False;
2340                         }
2341                 }
2342                 if (old_offset + len > ps->buffer_size)
2343                         return False;
2344                 ps->data_offset = old_offset + len;
2345         }
2346         if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth))
2347                 return False;
2348         prs_align(ps);
2349         if (!smb_io_unistr2("uni_profile", &info->uni_profile,
2350                             info->hdr_profile.buffer, ps, depth))
2351                 return False;
2352
2353         prs_align(ps);
2354
2355         return True;
2356 }
2357
2358 /*******************************************************************
2359 reads or writes a structure.
2360 ********************************************************************/
2361 static BOOL net_io_sam_group_mem_info(const char *desc, SAM_GROUP_MEM_INFO * info,
2362                                       prs_struct *ps, int depth)
2363 {
2364         uint32 i;
2365         fstring tmp;
2366
2367         prs_debug(ps, depth, desc, "net_io_sam_group_mem_info");
2368         depth++;
2369
2370         prs_align(ps);
2371         if (!prs_uint32("ptr_rids   ", ps, depth, &info->ptr_rids))
2372                 return False;
2373         if (!prs_uint32("ptr_attribs", ps, depth, &info->ptr_attribs))
2374                 return False;
2375         if (!prs_uint32("num_members", ps, depth, &info->num_members))
2376                 return False;
2377
2378         if (ps->data_offset + 16 > ps->buffer_size)
2379                 return False;
2380         ps->data_offset += 16;
2381
2382         if (info->ptr_rids != 0)
2383         {
2384                 if (!prs_uint32("num_members2", ps, depth, 
2385                                 &info->num_members2))
2386                         return False;
2387
2388                 if (info->num_members2 != info->num_members)
2389                 {
2390                         /* RPC fault */
2391                         return False;
2392                 }
2393
2394                 info->rids = TALLOC_ARRAY(ps->mem_ctx, uint32, info->num_members2);
2395
2396                 if (info->rids == NULL) {
2397                         DEBUG(0, ("out of memory allocating %d rids\n",
2398                                   info->num_members2));
2399                         return False;
2400                 }
2401
2402                 for (i = 0; i < info->num_members2; i++)
2403                 {
2404                         slprintf(tmp, sizeof(tmp) - 1, "rids[%02d]", i);
2405                         if (!prs_uint32(tmp, ps, depth, &info->rids[i]))
2406                                 return False;
2407                 }
2408         }
2409
2410         if (info->ptr_attribs != 0)
2411         {
2412                 if (!prs_uint32("num_members3", ps, depth, 
2413                                 &info->num_members3))
2414                         return False;
2415                 if (info->num_members3 != info->num_members)
2416                 {
2417                         /* RPC fault */
2418                         return False;
2419                 }
2420
2421                 info->attribs = TALLOC_ARRAY(ps->mem_ctx, uint32, info->num_members3);
2422
2423                 if (info->attribs == NULL) {
2424                         DEBUG(0, ("out of memory allocating %d attribs\n",
2425                                   info->num_members3));
2426                         return False;
2427                 }
2428
2429                 for (i = 0; i < info->num_members3; i++)
2430                 {
2431                         slprintf(tmp, sizeof(tmp) - 1, "attribs[%02d]", i);
2432                         if (!prs_uint32(tmp, ps, depth, &info->attribs[i]))
2433                                 return False;
2434                 }
2435         }
2436
2437         return True;
2438 }
2439
2440 /*******************************************************************
2441 reads or writes a structure.
2442 ********************************************************************/
2443 static BOOL net_io_sam_alias_info(const char *desc, SAM_ALIAS_INFO * info,
2444                                   prs_struct *ps, int depth)
2445 {
2446         prs_debug(ps, depth, desc, "net_io_sam_alias_info");
2447         depth++;
2448
2449         if (!smb_io_unihdr("hdr_als_name", &info->hdr_als_name, ps, depth))
2450                 return False;
2451         if (!prs_uint32("als_rid", ps, depth, &info->als_rid))
2452                 return False;
2453         if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
2454                 return False;
2455         if (!smb_io_unihdr("hdr_als_desc", &info->hdr_als_desc, ps, depth))
2456                 return False;
2457
2458         if (ps->data_offset + 40 > ps->buffer_size)
2459                 return False;
2460         ps->data_offset += 40;
2461
2462         if (!smb_io_unistr2("uni_als_name", &info->uni_als_name,
2463                             info->hdr_als_name.buffer, ps, depth))
2464                 return False;
2465         if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth))
2466                 return False;
2467
2468         if (!smb_io_unistr2("uni_als_desc", &info->uni_als_desc,
2469                             info->hdr_als_desc.buffer, ps, depth))
2470                 return False;
2471
2472         return True;
2473 }
2474
2475 /*******************************************************************
2476 reads or writes a structure.
2477 ********************************************************************/
2478 static BOOL net_io_sam_alias_mem_info(const char *desc, SAM_ALIAS_MEM_INFO * info,
2479                                       prs_struct *ps, int depth)
2480 {
2481         uint32 i;
2482         fstring tmp;
2483
2484         prs_debug(ps, depth, desc, "net_io_sam_alias_mem_info");
2485         depth++;
2486
2487         prs_align(ps);
2488         if (!prs_uint32("num_members", ps, depth, &info->num_members))
2489                 return False;
2490         if (!prs_uint32("ptr_members", ps, depth, &info->ptr_members))
2491                 return False;
2492
2493         if (ps->data_offset + 16 > ps->buffer_size)
2494                 return False;
2495         ps->data_offset += 16;
2496
2497         if (info->ptr_members != 0)
2498         {
2499                 if (!prs_uint32("num_sids", ps, depth, &info->num_sids))
2500                         return False;
2501                 if (info->num_sids != info->num_members)
2502                 {
2503                         /* RPC fault */
2504                         return False;
2505                 }
2506
2507                 info->ptr_sids = TALLOC_ARRAY(ps->mem_ctx, uint32, info->num_sids);
2508                 
2509                 if (info->ptr_sids == NULL) {
2510                         DEBUG(0, ("out of memory allocating %d ptr_sids\n",
2511                                   info->num_sids));
2512                         return False;
2513                 }
2514
2515                 for (i = 0; i < info->num_sids; i++)
2516                 {
2517                         slprintf(tmp, sizeof(tmp) - 1, "ptr_sids[%02d]", i);
2518                         if (!prs_uint32(tmp, ps, depth, &info->ptr_sids[i]))
2519                                 return False;
2520                 }
2521
2522                 info->sids = TALLOC_ARRAY(ps->mem_ctx, DOM_SID2, info->num_sids);
2523
2524                 if (info->sids == NULL) {
2525                         DEBUG(0, ("error allocating %d sids\n",
2526                                   info->num_sids));
2527                         return False;
2528                 }
2529
2530                 for (i = 0; i < info->num_sids; i++)
2531                 {
2532                         if (info->ptr_sids[i] != 0)
2533                         {
2534                                 slprintf(tmp, sizeof(tmp) - 1, "sids[%02d]",
2535                                          i);
2536                                 if (!smb_io_dom_sid2(tmp, &info->sids[i], 
2537                                                      ps, depth))
2538                                         return False;
2539                         }
2540                 }
2541         }
2542
2543         return True;
2544 }
2545
2546 /*******************************************************************
2547 reads or writes a structure.
2548 ********************************************************************/
2549 static BOOL net_io_sam_policy_info(const char *desc, SAM_DELTA_POLICY *info,
2550                                       prs_struct *ps, int depth)
2551 {
2552         unsigned int i;
2553         prs_debug(ps, depth, desc, "net_io_sam_policy_info");
2554         depth++;
2555
2556         if(!prs_align(ps))
2557                 return False;
2558
2559         if (!prs_uint32("max_log_size", ps, depth, &info->max_log_size))
2560                 return False;
2561         if (!prs_uint64("audit_retention_period", ps, depth,
2562                         &info->audit_retention_period))
2563                 return False;
2564         if (!prs_uint32("auditing_mode", ps, depth, &info->auditing_mode))
2565                 return False;
2566         if (!prs_uint32("num_events", ps, depth, &info->num_events))
2567                 return False;
2568         if (!prs_uint32("ptr_events", ps, depth, &info->ptr_events))
2569                 return False;
2570
2571         if (!smb_io_unihdr("hdr_dom_name", &info->hdr_dom_name, ps, depth))
2572                 return False;
2573
2574         if (!prs_uint32("sid_ptr", ps, depth, &info->sid_ptr))
2575                 return False;
2576
2577         if (!prs_uint32("paged_pool_limit", ps, depth, &info->paged_pool_limit))
2578                 return False;
2579         if (!prs_uint32("non_paged_pool_limit", ps, depth,
2580                         &info->non_paged_pool_limit))
2581                 return False;
2582         if (!prs_uint32("min_workset_size", ps, depth, &info->min_workset_size))
2583                 return False;
2584         if (!prs_uint32("max_workset_size", ps, depth, &info->max_workset_size))
2585                 return False;
2586         if (!prs_uint32("page_file_limit", ps, depth, &info->page_file_limit))
2587                 return False;
2588         if (!prs_uint64("time_limit", ps, depth, &info->time_limit))
2589                 return False;
2590         if (!smb_io_time("modify_time", &info->modify_time, ps, depth))
2591                 return False;
2592         if (!smb_io_time("create_time", &info->create_time, ps, depth))
2593                 return False;
2594         if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
2595                 return False;
2596
2597         for (i=0; i<4; i++) {
2598                 UNIHDR dummy;
2599                 if (!smb_io_unihdr("dummy", &dummy, ps, depth))
2600                         return False;
2601         }
2602
2603         for (i=0; i<4; i++) {
2604                 uint32 reserved;
2605                 if (!prs_uint32("reserved", ps, depth, &reserved))
2606                         return False;
2607         }
2608
2609         if (!prs_uint32("num_event_audit_options", ps, depth,
2610                         &info->num_event_audit_options))
2611                 return False;
2612
2613         for (i=0; i<info->num_event_audit_options; i++)
2614                 if (!prs_uint32("event_audit_option", ps, depth,
2615                                 &info->event_audit_option))
2616                         return False;
2617
2618         if (!smb_io_unistr2("domain_name", &info->domain_name, True, ps, depth))
2619                 return False;
2620
2621         if(!smb_io_dom_sid2("domain_sid", &info->domain_sid, ps, depth))
2622                 return False;
2623
2624         if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth))
2625
2626                 return False;
2627
2628         return True;
2629 }
2630
2631 #if 0
2632
2633 /* This function is pretty broken - see bug #334 */
2634
2635 /*******************************************************************
2636 reads or writes a structure.
2637 ********************************************************************/
2638 static BOOL net_io_sam_trustdoms_info(const char *desc, SAM_DELTA_TRUSTDOMS *info,
2639                                       prs_struct *ps, int depth)
2640 {
2641         int i;
2642
2643         prs_debug(ps, depth, desc, "net_io_sam_trustdoms_info");
2644         depth++;
2645
2646         if(!prs_align(ps))
2647                 return False;
2648
2649         if(!prs_uint32("buf_size", ps, depth, &info->buf_size))
2650                 return False;
2651
2652         if(!sec_io_desc("sec_desc", &info->sec_desc, ps, depth))
2653                 return False;
2654
2655         if(!smb_io_dom_sid2("sid", &info->sid, ps, depth))
2656                 return False;
2657
2658         if(!smb_io_unihdr("hdr_domain", &info->hdr_domain, ps, depth))
2659                 return False;
2660
2661         if(!prs_uint32("unknown0", ps, depth, &info->unknown0))
2662                 return False;
2663         if(!prs_uint32("unknown1", ps, depth, &info->unknown1))
2664                 return False;
2665         if(!prs_uint32("unknown2", ps, depth, &info->unknown2))
2666                 return False;
2667
2668         if(!prs_uint32("buf_size2", ps, depth, &info->buf_size2))
2669                 return False;
2670         if(!prs_uint32("ptr", ps, depth, &info->ptr))
2671                 return False;
2672
2673         for (i=0; i<12; i++)
2674                 if(!prs_uint32("unknown3", ps, depth, &info->unknown3))
2675                         return False;
2676
2677         if (!smb_io_unistr2("domain", &info->domain, True, ps, depth))
2678                 return False;
2679
2680         return True;
2681 }
2682
2683 #endif
2684
2685 #if 0
2686
2687 /* This function doesn't work - see bug #334 */
2688
2689 /*******************************************************************
2690 reads or writes a structure.
2691 ********************************************************************/
2692 static BOOL net_io_sam_secret_info(const char *desc, SAM_DELTA_SECRET *info,
2693                                    prs_struct *ps, int depth)
2694 {
2695         int i;
2696
2697         prs_debug(ps, depth, desc, "net_io_sam_secret_info");
2698         depth++;
2699
2700         if(!prs_align(ps))
2701                 return False;
2702
2703         if(!prs_uint32("buf_size", ps, depth, &info->buf_size))
2704                 return False;
2705
2706         if(!sec_io_desc("sec_desc", &info->sec_desc, ps, depth))
2707                 return False;
2708
2709         if (!smb_io_unistr2("secret", &info->secret, True, ps, depth))
2710                 return False;
2711
2712         if(!prs_align(ps))
2713                 return False;
2714
2715         if(!prs_uint32("count1", ps, depth, &info->count1))
2716                 return False;
2717         if(!prs_uint32("count2", ps, depth, &info->count2))
2718                 return False;
2719         if(!prs_uint32("ptr", ps, depth, &info->ptr))
2720                 return False;
2721
2722
2723         if(!smb_io_time("time1", &info->time1, ps, depth)) /* logon time */
2724                 return False;
2725         if(!prs_uint32("count3", ps, depth, &info->count3))
2726                 return False;
2727         if(!prs_uint32("count4", ps, depth, &info->count4))
2728                 return False;
2729         if(!prs_uint32("ptr2", ps, depth, &info->ptr2))
2730                 return False;
2731         if(!smb_io_time("time2", &info->time2, ps, depth)) /* logon time */
2732                 return False;
2733         if(!prs_uint32("unknow1", ps, depth, &info->unknow1))
2734                 return False;
2735
2736
2737         if(!prs_uint32("buf_size2", ps, depth, &info->buf_size2))
2738                 return False;
2739         if(!prs_uint32("ptr3", ps, depth, &info->ptr3))
2740                 return False;
2741         for(i=0; i<12; i++)
2742                 if(!prs_uint32("unknow2", ps, depth, &info->unknow2))
2743                         return False;
2744
2745         if(!prs_uint32("chal_len", ps, depth, &info->chal_len))
2746                 return False;
2747         if(!prs_uint32("reserved1", ps, depth, &info->reserved1))
2748                 return False;
2749         if(!prs_uint32("chal_len2", ps, depth, &info->chal_len2))
2750                 return False;
2751
2752         if(!prs_uint8s (False, "chal", ps, depth, info->chal, info->chal_len2))
2753                 return False;
2754
2755         if(!prs_uint32("key_len", ps, depth, &info->key_len))
2756                 return False;
2757         if(!prs_uint32("reserved2", ps, depth, &info->reserved2))
2758                 return False;
2759         if(!prs_uint32("key_len2", ps, depth, &info->key_len2))
2760                 return False;
2761
2762         if(!prs_uint8s (False, "key", ps, depth, info->key, info->key_len2))
2763                 return False;
2764
2765
2766         if(!prs_uint32("buf_size3", ps, depth, &info->buf_size3))
2767                 return False;
2768
2769         if(!sec_io_desc("sec_desc2", &info->sec_desc2, ps, depth))
2770                 return False;
2771
2772
2773         return True;
2774 }
2775
2776 #endif
2777
2778 /*******************************************************************
2779 reads or writes a structure.
2780 ********************************************************************/
2781 static BOOL net_io_sam_privs_info(const char *desc, SAM_DELTA_PRIVS *info,
2782                                       prs_struct *ps, int depth)
2783 {
2784         unsigned int i;
2785
2786         prs_debug(ps, depth, desc, "net_io_sam_privs_info");
2787         depth++;
2788
2789         if(!prs_align(ps))
2790                 return False;
2791
2792         if(!smb_io_dom_sid2("sid", &info->sid, ps, depth))
2793                 return False;
2794
2795         if(!prs_uint32("priv_count", ps, depth, &info->priv_count))
2796                 return False;
2797         if(!prs_uint32("priv_control", ps, depth, &info->priv_control))
2798                 return False;
2799
2800         if(!prs_uint32("priv_attr_ptr", ps, depth, &info->priv_attr_ptr))
2801                 return False;
2802         if(!prs_uint32("priv_name_ptr", ps, depth, &info->priv_name_ptr))
2803                 return False;
2804
2805         if (!prs_uint32("paged_pool_limit", ps, depth, &info->paged_pool_limit))
2806                 return False;
2807         if (!prs_uint32("non_paged_pool_limit", ps, depth,
2808                         &info->non_paged_pool_limit))
2809                 return False;
2810         if (!prs_uint32("min_workset_size", ps, depth, &info->min_workset_size))
2811                 return False;
2812         if (!prs_uint32("max_workset_size", ps, depth, &info->max_workset_size))
2813                 return False;
2814         if (!prs_uint32("page_file_limit", ps, depth, &info->page_file_limit))
2815                 return False;
2816         if (!prs_uint64("time_limit", ps, depth, &info->time_limit))
2817                 return False;
2818         if (!prs_uint32("system_flags", ps, depth, &info->system_flags))
2819                 return False;
2820         if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
2821                 return False;
2822
2823         for (i=0; i<4; i++) {
2824                 UNIHDR dummy;
2825                 if (!smb_io_unihdr("dummy", &dummy, ps, depth))
2826                         return False;
2827         }
2828
2829         for (i=0; i<4; i++) {
2830                 uint32 reserved;
2831                 if (!prs_uint32("reserved", ps, depth, &reserved))
2832                         return False;
2833         }
2834
2835         if(!prs_uint32("attribute_count", ps, depth, &info->attribute_count))
2836                 return False;
2837
2838         info->attributes = TALLOC_ARRAY(ps->mem_ctx, uint32, info->attribute_count);
2839
2840         for (i=0; i<info->attribute_count; i++)
2841                 if(!prs_uint32("attributes", ps, depth, &info->attributes[i]))
2842                         return False;
2843
2844         if(!prs_uint32("privlist_count", ps, depth, &info->privlist_count))
2845                 return False;
2846
2847         info->hdr_privslist = TALLOC_ARRAY(ps->mem_ctx, UNIHDR, info->privlist_count);
2848         info->uni_privslist = TALLOC_ARRAY(ps->mem_ctx, UNISTR2, info->privlist_count);
2849
2850         for (i=0; i<info->privlist_count; i++)
2851                 if(!smb_io_unihdr("hdr_privslist", &info->hdr_privslist[i], ps, depth))
2852                         return False;
2853
2854         for (i=0; i<info->privlist_count; i++)
2855                 if (!smb_io_unistr2("uni_privslist", &info->uni_privslist[i], True, ps, depth))
2856                         return False;
2857
2858         if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth))
2859                 return False;
2860
2861         return True;
2862 }
2863
2864 /*******************************************************************
2865 reads or writes a structure.
2866 ********************************************************************/
2867 static BOOL net_io_sam_delta_ctr(const char *desc,
2868                                  SAM_DELTA_CTR * delta, uint16 type,
2869                                  prs_struct *ps, int depth)
2870 {
2871         prs_debug(ps, depth, desc, "net_io_sam_delta_ctr");
2872         depth++;
2873
2874         switch (type) {
2875                 /* Seen in sam deltas */
2876                 case SAM_DELTA_MODIFIED_COUNT:
2877                         if (!net_io_sam_delta_mod_count("", &delta->mod_count, ps, depth))
2878                                 return False;
2879                         break;
2880
2881                 case SAM_DELTA_DOMAIN_INFO:
2882                         if (!net_io_sam_domain_info("", &delta->domain_info, ps, depth))
2883                                 return False;
2884                         break;
2885
2886                 case SAM_DELTA_GROUP_INFO:
2887                         if (!net_io_sam_group_info("", &delta->group_info, ps, depth))
2888                                 return False;
2889                         break;
2890
2891                 case SAM_DELTA_ACCOUNT_INFO:
2892                         if (!net_io_sam_account_info("", &delta->account_info, ps, depth))
2893                                 return False;
2894                         break;
2895
2896                 case SAM_DELTA_GROUP_MEM:
2897                         if (!net_io_sam_group_mem_info("", &delta->grp_mem_info, ps, depth))
2898                                 return False;
2899                         break;
2900
2901                 case SAM_DELTA_ALIAS_INFO:
2902                         if (!net_io_sam_alias_info("", &delta->alias_info, ps, depth))
2903                                 return False;
2904                         break;
2905
2906                 case SAM_DELTA_POLICY_INFO:
2907                         if (!net_io_sam_policy_info("", &delta->policy_info, ps, depth))
2908                                 return False;
2909                         break;
2910
2911                 case SAM_DELTA_ALIAS_MEM:
2912                         if (!net_io_sam_alias_mem_info("", &delta->als_mem_info, ps, depth))
2913                                 return False;
2914                         break;
2915
2916                 case SAM_DELTA_PRIVS_INFO:
2917                         if (!net_io_sam_privs_info("", &delta->privs_info, ps, depth))
2918                                 return False;
2919                         break;
2920
2921                         /* These guys are implemented but broken */
2922
2923                 case SAM_DELTA_TRUST_DOMS:
2924                 case SAM_DELTA_SECRET_INFO:
2925                         break;
2926
2927                         /* These guys are not implemented yet */
2928
2929                 case SAM_DELTA_RENAME_GROUP:
2930                 case SAM_DELTA_RENAME_USER:
2931                 case SAM_DELTA_RENAME_ALIAS:
2932                 case SAM_DELTA_DELETE_GROUP:
2933                 case SAM_DELTA_DELETE_USER:
2934                 default:
2935                         DEBUG(0, ("Replication error: Unknown delta type 0x%x\n", type));
2936                         break;
2937         }
2938
2939         return True;
2940 }
2941
2942 /*******************************************************************
2943 reads or writes a structure.
2944 ********************************************************************/
2945 BOOL net_io_r_sam_sync(const char *desc,
2946                        NET_R_SAM_SYNC * r_s, prs_struct *ps, int depth)
2947 {
2948         uint32 i;
2949
2950         prs_debug(ps, depth, desc, "net_io_r_sam_sync");
2951         depth++;
2952
2953         if (!smb_io_cred("srv_creds", &r_s->srv_creds, ps, depth))
2954                 return False;
2955         if (!prs_uint32("sync_context", ps, depth, &r_s->sync_context))
2956                 return False;
2957
2958         if (!prs_uint32("ptr_deltas", ps, depth, &r_s->ptr_deltas))
2959                 return False;
2960         if (r_s->ptr_deltas != 0)
2961         {
2962                 if (!prs_uint32("num_deltas ", ps, depth, &r_s->num_deltas))
2963                         return False;
2964                 if (!prs_uint32("ptr_deltas2", ps, depth, &r_s->ptr_deltas2))
2965                         return False;
2966                 if (r_s->ptr_deltas2 != 0)
2967                 {
2968                         if (!prs_uint32("num_deltas2", ps, depth,
2969                                         &r_s->num_deltas2))
2970                                 return False;
2971
2972                         if (r_s->num_deltas2 != r_s->num_deltas)
2973                         {
2974                                 /* RPC fault */
2975                                 return False;
2976                         }
2977
2978                         if (r_s->num_deltas2 > 0) {
2979                                 r_s->hdr_deltas = TALLOC_ARRAY(ps->mem_ctx, SAM_DELTA_HDR, r_s->num_deltas2);
2980                                 if (r_s->hdr_deltas == NULL) {
2981                                         DEBUG(0, ("error tallocating memory "
2982                                                   "for %d delta headers\n", 
2983                                                   r_s->num_deltas2));
2984                                         return False;
2985                                 }
2986                         }
2987
2988                         for (i = 0; i < r_s->num_deltas2; i++)
2989                         {
2990                                 if (!net_io_sam_delta_hdr("", 
2991                                                           &r_s->hdr_deltas[i],
2992                                                           ps, depth))
2993                                         return False;
2994                         }
2995
2996                         if (r_s->num_deltas2 > 0) {
2997                                 r_s->deltas = TALLOC_ARRAY(ps->mem_ctx, SAM_DELTA_CTR, r_s->num_deltas2);
2998                                 if (r_s->deltas == NULL) {
2999                                         DEBUG(0, ("error tallocating memory "
3000                                                   "for %d deltas\n", 
3001                                                   r_s->num_deltas2));
3002                                         return False;
3003                                 }
3004                         }
3005
3006                         for (i = 0; i < r_s->num_deltas2; i++)
3007                         {
3008                                 if (!net_io_sam_delta_ctr(
3009                                         "", &r_s->deltas[i],
3010                                         r_s->hdr_deltas[i].type3,
3011                                         ps, depth)) {
3012                                         DEBUG(0, ("hmm, failed on i=%d\n", i));
3013                                         return False;
3014                                 }
3015                         }
3016                 }
3017         }
3018
3019         prs_align(ps);
3020         if (!prs_ntstatus("status", ps, depth, &(r_s->status)))
3021                 return False;
3022
3023         return True;
3024 }
3025
3026 /*******************************************************************
3027 makes a NET_Q_SAM_DELTAS structure.
3028 ********************************************************************/
3029 BOOL init_net_q_sam_deltas(NET_Q_SAM_DELTAS *q_s, const char *srv_name, 
3030                            const char *cli_name, DOM_CRED *cli_creds, 
3031                            uint32 database_id, UINT64_S dom_mod_count)
3032 {
3033         DEBUG(5, ("init_net_q_sam_deltas\n"));
3034
3035         init_unistr2(&q_s->uni_srv_name, srv_name, UNI_STR_TERMINATE);
3036         init_unistr2(&q_s->uni_cli_name, cli_name, UNI_STR_TERMINATE);
3037
3038         memcpy(&q_s->cli_creds, cli_creds, sizeof(q_s->cli_creds));
3039         memset(&q_s->ret_creds, 0, sizeof(q_s->ret_creds));
3040
3041         q_s->database_id = database_id;
3042         q_s->dom_mod_count.low = dom_mod_count.low;
3043         q_s->dom_mod_count.high = dom_mod_count.high;
3044         q_s->max_size = 0xffff;
3045
3046         return True;
3047 }
3048
3049 /*******************************************************************
3050 reads or writes a structure.
3051 ********************************************************************/
3052 BOOL net_io_q_sam_deltas(const char *desc, NET_Q_SAM_DELTAS *q_s, prs_struct *ps,
3053                          int depth)
3054 {
3055         prs_debug(ps, depth, desc, "net_io_q_sam_deltas");
3056         depth++;
3057
3058         if (!smb_io_unistr2("", &q_s->uni_srv_name, True, ps, depth))
3059                 return False;
3060         if (!smb_io_unistr2("", &q_s->uni_cli_name, True, ps, depth))
3061                 return False;
3062
3063         if (!smb_io_cred("", &q_s->cli_creds, ps, depth))
3064                 return False;
3065         if (!smb_io_cred("", &q_s->ret_creds, ps, depth))
3066                 return False;
3067
3068         if (!prs_uint32("database_id  ", ps, depth, &q_s->database_id))
3069                 return False;
3070         if (!prs_uint64("dom_mod_count", ps, depth, &q_s->dom_mod_count))
3071                 return False;
3072         if (!prs_uint32("max_size", ps, depth, &q_s->max_size))
3073                 return False;
3074
3075         return True;
3076 }
3077
3078 /*******************************************************************
3079 reads or writes a structure.
3080 ********************************************************************/
3081 BOOL net_io_r_sam_deltas(const char *desc,
3082                          NET_R_SAM_DELTAS *r_s, prs_struct *ps, int depth)
3083 {
3084         unsigned int i;
3085
3086         prs_debug(ps, depth, desc, "net_io_r_sam_deltas");
3087         depth++;
3088
3089         if (!smb_io_cred("srv_creds", &r_s->srv_creds, ps, depth))
3090                 return False;
3091         if (!prs_uint64("dom_mod_count", ps, depth, &r_s->dom_mod_count))
3092                 return False;
3093
3094         if (!prs_uint32("ptr_deltas", ps, depth, &r_s->ptr_deltas))
3095                 return False;
3096         if (!prs_uint32("num_deltas", ps, depth, &r_s->num_deltas))
3097                 return False;
3098         if (!prs_uint32("ptr_deltas2", ps, depth, &r_s->num_deltas2))
3099                 return False;
3100
3101         if (r_s->num_deltas2 != 0)
3102         {
3103                 if (!prs_uint32("num_deltas2 ", ps, depth, &r_s->num_deltas2))
3104                         return False;
3105
3106                 if (r_s->ptr_deltas != 0)
3107                 {
3108                         if (r_s->num_deltas > 0) {
3109                                 r_s->hdr_deltas = TALLOC_ARRAY(ps->mem_ctx, SAM_DELTA_HDR, r_s->num_deltas);
3110                                 if (r_s->hdr_deltas == NULL) {
3111                                         DEBUG(0, ("error tallocating memory "
3112                                                   "for %d delta headers\n", 
3113                                                   r_s->num_deltas));
3114                                         return False;
3115                                 }
3116                         }
3117
3118                         for (i = 0; i < r_s->num_deltas; i++)
3119                         {
3120                                 net_io_sam_delta_hdr("", &r_s->hdr_deltas[i],
3121                                                       ps, depth);
3122                         }
3123                         
3124                         if (r_s->num_deltas > 0) {
3125                                 r_s->deltas = TALLOC_ARRAY(ps->mem_ctx, SAM_DELTA_CTR, r_s->num_deltas);
3126                                 if (r_s->deltas == NULL) {
3127                                         DEBUG(0, ("error tallocating memory "
3128                                                   "for %d deltas\n", 
3129                                                   r_s->num_deltas));
3130                                         return False;
3131                                 }
3132                         }
3133
3134                         for (i = 0; i < r_s->num_deltas; i++)
3135                         {
3136                                 if (!net_io_sam_delta_ctr(
3137                                         "",
3138                                         &r_s->deltas[i],
3139                                         r_s->hdr_deltas[i].type2,
3140                                         ps, depth))
3141                                         
3142                                         return False;
3143                         }
3144                 }
3145         }
3146
3147         prs_align(ps);
3148         if (!prs_ntstatus("status", ps, depth, &r_s->status))
3149                 return False;
3150
3151         return True;
3152 }