r10656: BIG merge from trunk. Features not copied over
[samba.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         if(!prs_uint32("num_groups2   ", ps, depth, &usr->num_groups2))        /* num groups */
1626                 return False;
1627
1628         if (UNMARSHALLING(ps) && usr->num_groups2 > 0) {
1629                 usr->gids = PRS_ALLOC_MEM(ps, DOM_GID, usr->num_groups2);
1630                 if (usr->gids == NULL)
1631                         return False;
1632         }
1633
1634         for (i = 0; i < usr->num_groups2; i++) {
1635                 if(!smb_io_gid("", &usr->gids[i], ps, depth)) /* group info */
1636                         return False;
1637         }
1638
1639         if(!smb_io_unistr2("uni_logon_srv", &usr->uni_logon_srv, usr->hdr_logon_srv.buffer, ps, depth)) /* logon server unicode string */
1640                 return False;
1641         if(!smb_io_unistr2("uni_logon_dom", &usr->uni_logon_dom, usr->hdr_logon_dom.buffer, ps, depth)) /* logon domain unicode string */
1642                 return False;
1643
1644         if(!smb_io_dom_sid2("", &usr->dom_sid, ps, depth))           /* domain SID */
1645                 return False;
1646
1647         if (usr->buffer_other_sids) {
1648
1649                 uint32 num_other_sids = usr->num_other_sids;
1650
1651                 if (!(usr->user_flgs & LOGON_EXTRA_SIDS)) {
1652                         DEBUG(10,("net_io_user_info3: user_flgs attribute does not have LOGON_EXTRA_SIDS\n"));
1653                         /* return False; */
1654                 }
1655
1656                 if (!prs_uint32("num_other_sids", ps, depth,
1657                                 &num_other_sids))
1658                         return False;
1659
1660                 if (num_other_sids != usr->num_other_sids)
1661                         return False;
1662
1663                 if (UNMARSHALLING(ps)) {
1664                         usr->other_sids = PRS_ALLOC_MEM(ps, DOM_SID2, usr->num_other_sids);
1665                         usr->other_sids_attrib =
1666                                 PRS_ALLOC_MEM(ps, uint32, usr->num_other_sids);
1667                                                                
1668                         if ((num_other_sids != 0) &&
1669                             ((usr->other_sids == NULL) ||
1670                              (usr->other_sids_attrib == NULL)))
1671                                 return False;
1672                 }
1673
1674                 /* First the pointers to the SIDS and attributes */
1675
1676                 depth++;
1677
1678                 for (i=0; i<usr->num_other_sids; i++) {
1679                         uint32 ptr = 1;
1680
1681                         if (!prs_uint32("sid_ptr", ps, depth, &ptr))
1682                                 return False;
1683
1684                         if (UNMARSHALLING(ps) && (ptr == 0))
1685                                 return False;
1686
1687                         if (!prs_uint32("attribute", ps, depth,
1688                                         &usr->other_sids_attrib[i]))
1689                                 return False;
1690                 }
1691         
1692                 for (i = 0; i < usr->num_other_sids; i++) {
1693                         if(!smb_io_dom_sid2("", &usr->other_sids[i], ps, depth)) /* other domain SIDs */
1694                                 return False;
1695                 }
1696
1697                 depth--;
1698         }
1699
1700         return True;
1701 }
1702
1703 /*******************************************************************
1704  Reads or writes a structure.
1705 ********************************************************************/
1706
1707 BOOL net_io_q_sam_logon(const char *desc, NET_Q_SAM_LOGON *q_l, prs_struct *ps, int depth)
1708 {
1709         if (q_l == NULL)
1710                 return False;
1711
1712         prs_debug(ps, depth, desc, "net_io_q_sam_logon");
1713         depth++;
1714
1715         if(!prs_align(ps))
1716                 return False;
1717         
1718         if(!smb_io_sam_info("", &q_l->sam_id, ps, depth))
1719                 return False;
1720
1721         if(!prs_align_uint16(ps))
1722                 return False;
1723         
1724         if(!prs_uint16("validation_level", ps, depth, &q_l->validation_level))
1725                 return False;
1726
1727         return True;
1728 }
1729
1730 /*******************************************************************
1731  Reads or writes a structure.
1732 ********************************************************************/
1733
1734 BOOL net_io_r_sam_logon(const char *desc, NET_R_SAM_LOGON *r_l, prs_struct *ps, int depth)
1735 {
1736         if (r_l == NULL)
1737                 return False;
1738
1739         prs_debug(ps, depth, desc, "net_io_r_sam_logon");
1740         depth++;
1741
1742         if(!prs_uint32("buffer_creds", ps, depth, &r_l->buffer_creds)) /* undocumented buffer pointer */
1743                 return False;
1744         if (&r_l->buffer_creds) {
1745                 if(!smb_io_cred("", &r_l->srv_creds, ps, depth)) /* server credentials.  server time stamp appears to be ignored. */
1746                         return False;
1747         }
1748
1749         if(!prs_uint16("switch_value", ps, depth, &r_l->switch_value))
1750                 return False;
1751         if(!prs_align(ps))
1752                 return False;
1753
1754 #if 1 /* W2k always needs this - even for bad passwd. JRA */
1755         if(!net_io_user_info3("", r_l->user, ps, depth, r_l->switch_value, False))
1756                 return False;
1757 #else
1758         if (r_l->switch_value != 0) {
1759                 if(!net_io_user_info3("", r_l->user, ps, depth, r_l->switch_value, False))
1760                         return False;
1761         }
1762 #endif
1763
1764         if(!prs_uint32("auth_resp   ", ps, depth, &r_l->auth_resp)) /* 1 - Authoritative response; 0 - Non-Auth? */
1765                 return False;
1766
1767         if(!prs_ntstatus("status      ", ps, depth, &r_l->status))
1768                 return False;
1769
1770         if(!prs_align(ps))
1771                 return False;
1772
1773         return True;
1774 }
1775
1776 /*******************************************************************
1777  Reads or writes a structure.
1778 ********************************************************************/
1779
1780 BOOL net_io_q_sam_logoff(const char *desc,  NET_Q_SAM_LOGOFF *q_l, prs_struct *ps, int depth)
1781 {
1782         if (q_l == NULL)
1783                 return False;
1784
1785         prs_debug(ps, depth, desc, "net_io_q_sam_logoff");
1786         depth++;
1787
1788         if(!prs_align(ps))
1789                 return False;
1790         
1791         if(!smb_io_sam_info("", &q_l->sam_id, ps, depth))           /* domain SID */
1792                 return False;
1793
1794         return True;
1795 }
1796
1797 /*******************************************************************
1798  Reads or writes a structure.
1799 ********************************************************************/
1800
1801 BOOL net_io_r_sam_logoff(const char *desc, NET_R_SAM_LOGOFF *r_l, prs_struct *ps, int depth)
1802 {
1803         if (r_l == NULL)
1804                 return False;
1805
1806         prs_debug(ps, depth, desc, "net_io_r_sam_logoff");
1807         depth++;
1808
1809         if(!prs_align(ps))
1810                 return False;
1811         
1812         if(!prs_uint32("buffer_creds", ps, depth, &r_l->buffer_creds)) /* undocumented buffer pointer */
1813                 return False;
1814         if(!smb_io_cred("", &r_l->srv_creds, ps, depth)) /* server credentials.  server time stamp appears to be ignored. */
1815                 return False;
1816
1817         if(!prs_ntstatus("status      ", ps, depth, &r_l->status))
1818                 return False;
1819
1820         return True;
1821 }
1822
1823 /*******************************************************************
1824 makes a NET_Q_SAM_SYNC structure.
1825 ********************************************************************/
1826 BOOL init_net_q_sam_sync(NET_Q_SAM_SYNC * q_s, const char *srv_name,
1827                          const char *cli_name, DOM_CRED *cli_creds, 
1828                          DOM_CRED *ret_creds, uint32 database_id, 
1829                          uint32 next_rid)
1830 {
1831         DEBUG(5, ("init_q_sam_sync\n"));
1832
1833         init_unistr2(&q_s->uni_srv_name, srv_name, UNI_STR_TERMINATE);
1834         init_unistr2(&q_s->uni_cli_name, cli_name, UNI_STR_TERMINATE);
1835
1836         if (cli_creds)
1837                 memcpy(&q_s->cli_creds, cli_creds, sizeof(q_s->cli_creds));
1838
1839         if (cli_creds)
1840                 memcpy(&q_s->ret_creds, ret_creds, sizeof(q_s->ret_creds));
1841         else
1842                 memset(&q_s->ret_creds, 0, sizeof(q_s->ret_creds));
1843
1844         q_s->database_id = database_id;
1845         q_s->restart_state = 0;
1846         q_s->sync_context = next_rid;
1847         q_s->max_size = 0xffff;
1848
1849         return True;
1850 }
1851
1852 /*******************************************************************
1853 reads or writes a structure.
1854 ********************************************************************/
1855 BOOL net_io_q_sam_sync(const char *desc, NET_Q_SAM_SYNC * q_s, prs_struct *ps,
1856                        int depth)
1857 {
1858         prs_debug(ps, depth, desc, "net_io_q_sam_sync");
1859         depth++;
1860
1861         if (!smb_io_unistr2("", &q_s->uni_srv_name, True, ps, depth))
1862                 return False;
1863         if (!smb_io_unistr2("", &q_s->uni_cli_name, True, ps, depth))
1864                 return False;
1865
1866         if (!smb_io_cred("", &q_s->cli_creds, ps, depth))
1867                 return False;
1868         if (!smb_io_cred("", &q_s->ret_creds, ps, depth))
1869                 return False;
1870
1871         if (!prs_uint32("database_id  ", ps, depth, &q_s->database_id))
1872                 return False;
1873         if (!prs_uint32("restart_state", ps, depth, &q_s->restart_state))
1874                 return False;
1875         if (!prs_uint32("sync_context ", ps, depth, &q_s->sync_context))
1876                 return False;
1877
1878         if (!prs_uint32("max_size", ps, depth, &q_s->max_size))
1879                 return False;
1880
1881         return True;
1882 }
1883
1884 /*******************************************************************
1885 reads or writes a structure.
1886 ********************************************************************/
1887 static BOOL net_io_sam_delta_hdr(const char *desc, SAM_DELTA_HDR * delta,
1888                                  prs_struct *ps, int depth)
1889 {
1890         prs_debug(ps, depth, desc, "net_io_sam_delta_hdr");
1891         depth++;
1892
1893         if (!prs_uint16("type", ps, depth, &delta->type))
1894                 return False;
1895         if (!prs_uint16("type2", ps, depth, &delta->type2))
1896                 return False;
1897         if (!prs_uint32("target_rid", ps, depth, &delta->target_rid))
1898                 return False;
1899
1900         if (!prs_uint32("type3", ps, depth, &delta->type3))
1901                 return False;
1902
1903         /* Not sure why we need this but it seems to be necessary to get
1904            sam deltas working. */
1905
1906         if (delta->type != 0x16) {
1907                 if (!prs_uint32("ptr_delta", ps, depth, &delta->ptr_delta))
1908                         return False;
1909         }
1910
1911         return True;
1912 }
1913
1914 /*******************************************************************
1915 reads or writes a structure.
1916 ********************************************************************/
1917 static BOOL net_io_sam_delta_mod_count(const char *desc, SAM_DELTA_MOD_COUNT *info,
1918                                    prs_struct *ps, int depth)
1919 {
1920         prs_debug(ps, depth, desc, "net_io_sam_delta_stamp");
1921         depth++;
1922
1923         if (!prs_uint32("seqnum", ps, depth, &info->seqnum))
1924                 return False;
1925         if (!prs_uint32("dom_mod_count_ptr", ps, depth, 
1926                         &info->dom_mod_count_ptr))
1927                 return False;
1928
1929         if (info->dom_mod_count_ptr) {
1930                 if (!prs_uint64("dom_mod_count", ps, depth,
1931                                 &info->dom_mod_count))
1932                         return False;
1933         }
1934
1935         return True;
1936 }
1937
1938 /*******************************************************************
1939 reads or writes a structure.
1940 ********************************************************************/
1941 static BOOL net_io_sam_domain_info(const char *desc, SAM_DOMAIN_INFO * info,
1942                                    prs_struct *ps, int depth)
1943 {
1944         prs_debug(ps, depth, desc, "net_io_sam_domain_info");
1945         depth++;
1946
1947         if (!smb_io_unihdr("hdr_dom_name", &info->hdr_dom_name, ps, depth))
1948                 return False;
1949         if (!smb_io_unihdr("hdr_oem_info", &info->hdr_oem_info, ps, depth))
1950                 return False;
1951
1952         if (!prs_uint64("force_logoff", ps, depth, &info->force_logoff))
1953                 return False;
1954         if (!prs_uint16("min_pwd_len", ps, depth, &info->min_pwd_len))
1955                 return False;
1956         if (!prs_uint16("pwd_history_len", ps, depth, &info->pwd_history_len))
1957                 return False;
1958         if (!prs_uint64("max_pwd_age", ps, depth, &info->max_pwd_age))
1959                 return False;
1960         if (!prs_uint64("min_pwd_age", ps, depth, &info->min_pwd_age))
1961                 return False;
1962         if (!prs_uint64("dom_mod_count", ps, depth, &info->dom_mod_count))
1963                 return False;
1964         if (!smb_io_time("creation_time", &info->creation_time, ps, depth))
1965                 return False;
1966         if (!prs_uint32("security_information", ps, depth, &info->security_information))
1967                 return False;
1968         if (!smb_io_bufhdr4("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
1969                 return False;
1970         if (!smb_io_lockout_string_hdr("hdr_account_lockout_string", &info->hdr_account_lockout, ps, depth))
1971                 return False;
1972         if (!smb_io_unihdr("hdr_unknown2", &info->hdr_unknown2, ps, depth))
1973                 return False;
1974         if (!smb_io_unihdr("hdr_unknown3", &info->hdr_unknown3, ps, depth))
1975                 return False;
1976         if (!smb_io_unihdr("hdr_unknown4", &info->hdr_unknown4, ps, depth))
1977                 return False;
1978         if (!prs_uint32("logon_chgpass", ps, depth, &info->logon_chgpass))
1979                 return False;
1980         if (!prs_uint32("unknown6", ps, depth, &info->unknown6))
1981                 return False;
1982         if (!prs_uint32("unknown7", ps, depth, &info->unknown7))
1983                 return False;
1984         if (!prs_uint32("unknown8", ps, depth, &info->unknown8))
1985                 return False;
1986
1987         if (!smb_io_unistr2("uni_dom_name", &info->uni_dom_name,
1988                             info->hdr_dom_name.buffer, ps, depth))
1989                 return False;
1990         if (!smb_io_unistr2("buf_oem_info", &info->buf_oem_info,
1991                             info->hdr_oem_info.buffer, ps, depth))
1992                 return False;
1993
1994         if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth))
1995                 return False;
1996
1997         if (!smb_io_account_lockout_str("account_lockout", &info->account_lockout, 
1998                                         info->hdr_account_lockout.buffer, ps, depth))
1999                 return False;
2000
2001         if (!smb_io_unistr2("buf_unknown2", &info->buf_unknown2, 
2002                             info->hdr_unknown2.buffer, ps, depth))
2003                 return False;
2004         if (!smb_io_unistr2("buf_unknown3", &info->buf_unknown3, 
2005                             info->hdr_unknown3.buffer, ps, depth))
2006                 return False;
2007         if (!smb_io_unistr2("buf_unknown4", &info->buf_unknown4, 
2008                             info->hdr_unknown4.buffer, ps, depth))
2009                 return False;
2010
2011         return True;
2012 }
2013
2014 /*******************************************************************
2015 reads or writes a structure.
2016 ********************************************************************/
2017 static BOOL net_io_sam_group_info(const char *desc, SAM_GROUP_INFO * info,
2018                                   prs_struct *ps, int depth)
2019 {
2020         prs_debug(ps, depth, desc, "net_io_sam_group_info");
2021         depth++;
2022
2023         if (!smb_io_unihdr("hdr_grp_name", &info->hdr_grp_name, ps, depth))
2024                 return False;
2025         if (!smb_io_gid("gid", &info->gid, ps, depth))
2026                 return False;
2027         if (!smb_io_unihdr("hdr_grp_desc", &info->hdr_grp_desc, ps, depth))
2028                 return False;
2029         if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
2030                 return False;
2031
2032         if (ps->data_offset + 48 > ps->buffer_size)
2033                 return False;
2034         ps->data_offset += 48;
2035
2036         if (!smb_io_unistr2("uni_grp_name", &info->uni_grp_name,
2037                             info->hdr_grp_name.buffer, ps, depth))
2038                 return False;
2039         if (!smb_io_unistr2("uni_grp_desc", &info->uni_grp_desc,
2040                             info->hdr_grp_desc.buffer, ps, depth))
2041                 return False;
2042         if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth))
2043                 return False;
2044
2045         return True;
2046 }
2047
2048 /*******************************************************************
2049 reads or writes a structure.
2050 ********************************************************************/
2051 static BOOL net_io_sam_passwd_info(const char *desc, SAM_PWD * pwd,
2052                                    prs_struct *ps, int depth)
2053 {
2054         prs_debug(ps, depth, desc, "net_io_sam_passwd_info");
2055         depth++;
2056
2057         if (!prs_uint32("unk_0 ", ps, depth, &pwd->unk_0))
2058                 return False;
2059
2060         if (!smb_io_unihdr("hdr_lm_pwd", &pwd->hdr_lm_pwd, ps, depth))
2061                 return False;
2062         if (!prs_uint8s(False, "buf_lm_pwd", ps, depth, pwd->buf_lm_pwd, 16))
2063                 return False;
2064
2065         if (!smb_io_unihdr("hdr_nt_pwd", &pwd->hdr_nt_pwd, ps, depth))
2066                 return False;
2067         if (!prs_uint8s(False, "buf_nt_pwd", ps, depth, pwd->buf_nt_pwd, 16))
2068                 return False;
2069
2070         if (!smb_io_unihdr("", &pwd->hdr_empty_lm, ps, depth))
2071                 return False;
2072         if (!smb_io_unihdr("", &pwd->hdr_empty_nt, ps, depth))
2073                 return False;
2074
2075         return True;
2076 }
2077
2078 /*******************************************************************
2079 makes a SAM_ACCOUNT_INFO structure.
2080 ********************************************************************/
2081 BOOL make_sam_account_info(SAM_ACCOUNT_INFO * info,
2082                            const UNISTR2 *user_name,
2083                            const UNISTR2 *full_name,
2084                            uint32 user_rid, uint32 group_rid,
2085                            const UNISTR2 *home_dir,
2086                            const UNISTR2 *dir_drive,
2087                            const UNISTR2 *log_scr,
2088                            const UNISTR2 *desc,
2089                            uint32 acb_info,
2090                            const UNISTR2 *prof_path,
2091                            const UNISTR2 *wkstas,
2092                            const UNISTR2 *unk_str, const UNISTR2 *mung_dial)
2093 {
2094         int len_user_name = user_name != NULL ? user_name->uni_str_len : 0;
2095         int len_full_name = full_name != NULL ? full_name->uni_str_len : 0;
2096         int len_home_dir = home_dir != NULL ? home_dir->uni_str_len : 0;
2097         int len_dir_drive = dir_drive != NULL ? dir_drive->uni_str_len : 0;
2098         int len_logon_script = log_scr != NULL ? log_scr->uni_str_len : 0;
2099         int len_profile_path = prof_path != NULL ? prof_path->uni_str_len : 0;
2100         int len_description = desc != NULL ? desc->uni_str_len : 0;
2101         int len_workstations = wkstas != NULL ? wkstas->uni_str_len : 0;
2102         int len_unknown_str = unk_str != NULL ? unk_str->uni_str_len : 0;
2103         int len_munged_dial = mung_dial != NULL ? mung_dial->uni_str_len : 0;
2104
2105         DEBUG(5, ("make_sam_account_info\n"));
2106
2107         make_uni_hdr(&info->hdr_acct_name, len_user_name);
2108         make_uni_hdr(&info->hdr_full_name, len_full_name);
2109         make_uni_hdr(&info->hdr_home_dir, len_home_dir);
2110         make_uni_hdr(&info->hdr_dir_drive, len_dir_drive);
2111         make_uni_hdr(&info->hdr_logon_script, len_logon_script);
2112         make_uni_hdr(&info->hdr_profile, len_profile_path);
2113         make_uni_hdr(&info->hdr_acct_desc, len_description);
2114         make_uni_hdr(&info->hdr_workstations, len_workstations);
2115         make_uni_hdr(&info->hdr_comment, len_unknown_str);
2116         make_uni_hdr(&info->hdr_parameters, len_munged_dial);
2117
2118         /* not present */
2119         make_bufhdr2(&info->hdr_sec_desc, 0, 0, 0);
2120
2121         info->user_rid = user_rid;
2122         info->group_rid = group_rid;
2123
2124         init_nt_time(&info->logon_time);
2125         init_nt_time(&info->logoff_time);
2126         init_nt_time(&info->pwd_last_set_time);
2127         init_nt_time(&info->acct_expiry_time);
2128
2129         info->logon_divs = 0xA8;
2130         info->ptr_logon_hrs = 0;        /* Don't care right now */
2131
2132         info->bad_pwd_count = 0;
2133         info->logon_count = 0;
2134         info->acb_info = acb_info;
2135         info->nt_pwd_present = 0;
2136         info->lm_pwd_present = 0;
2137         info->pwd_expired = 0;
2138         info->country = 0;
2139         info->codepage = 0;
2140
2141         info->unknown1 = 0x4EC;
2142         info->unknown2 = 0;
2143
2144         copy_unistr2(&info->uni_acct_name, user_name);
2145         copy_unistr2(&info->uni_full_name, full_name);
2146         copy_unistr2(&info->uni_home_dir, home_dir);
2147         copy_unistr2(&info->uni_dir_drive, dir_drive);
2148         copy_unistr2(&info->uni_logon_script, log_scr);
2149         copy_unistr2(&info->uni_profile, prof_path);
2150         copy_unistr2(&info->uni_acct_desc, desc);
2151         copy_unistr2(&info->uni_workstations, wkstas);
2152         copy_unistr2(&info->uni_comment, unk_str);
2153         copy_unistr2(&info->uni_parameters, mung_dial);
2154
2155         return True;
2156 }
2157
2158 /*******************************************************************
2159 reads or writes a structure.
2160 ********************************************************************/
2161 static BOOL net_io_sam_account_info(const char *desc, SAM_ACCOUNT_INFO *info,
2162                                 prs_struct *ps, int depth)
2163 {
2164         BUFHDR2 hdr_priv_data;
2165         uint32 i;
2166
2167         prs_debug(ps, depth, desc, "net_io_sam_account_info");
2168         depth++;
2169
2170         if (!smb_io_unihdr("hdr_acct_name", &info->hdr_acct_name, ps, depth))
2171                 return False;
2172         if (!smb_io_unihdr("hdr_full_name", &info->hdr_full_name, ps, depth))
2173                 return False;
2174
2175         if (!prs_uint32("user_rid ", ps, depth, &info->user_rid))
2176                 return False;
2177         if (!prs_uint32("group_rid", ps, depth, &info->group_rid))
2178                 return False;
2179
2180         if (!smb_io_unihdr("hdr_home_dir ", &info->hdr_home_dir, ps, depth))
2181                 return False;
2182         if (!smb_io_unihdr("hdr_dir_drive", &info->hdr_dir_drive, ps, depth))
2183                 return False;
2184         if (!smb_io_unihdr("hdr_logon_script", &info->hdr_logon_script, ps,
2185                            depth))
2186                 return False;
2187
2188         if (!smb_io_unihdr("hdr_acct_desc", &info->hdr_acct_desc, ps, depth))
2189                 return False;
2190         if (!smb_io_unihdr("hdr_workstations", &info->hdr_workstations, ps,
2191                            depth))
2192                 return False;
2193
2194         if (!smb_io_time("logon_time", &info->logon_time, ps, depth))
2195                 return False;
2196         if (!smb_io_time("logoff_time", &info->logoff_time, ps, depth))
2197                 return False;
2198
2199         if (!prs_uint32("logon_divs   ", ps, depth, &info->logon_divs))
2200                 return False;
2201         if (!prs_uint32("ptr_logon_hrs", ps, depth, &info->ptr_logon_hrs))
2202                 return False;
2203
2204         if (!prs_uint16("bad_pwd_count", ps, depth, &info->bad_pwd_count))
2205                 return False;
2206         if (!prs_uint16("logon_count", ps, depth, &info->logon_count))
2207                 return False;
2208         if (!smb_io_time("pwd_last_set_time", &info->pwd_last_set_time, ps,
2209                          depth))
2210                 return False;
2211         if (!smb_io_time("acct_expiry_time", &info->acct_expiry_time, ps, 
2212                          depth))
2213                 return False;
2214
2215         if (!prs_uint32("acb_info", ps, depth, &info->acb_info))
2216                 return False;
2217         if (!prs_uint8s(False, "nt_pwd", ps, depth, info->nt_pwd, 16))
2218                 return False;
2219         if (!prs_uint8s(False, "lm_pwd", ps, depth, info->lm_pwd, 16))
2220                 return False;
2221         if (!prs_uint8("lm_pwd_present", ps, depth, &info->lm_pwd_present))
2222                 return False;
2223         if (!prs_uint8("nt_pwd_present", ps, depth, &info->nt_pwd_present))
2224                 return False;
2225         if (!prs_uint8("pwd_expired", ps, depth, &info->pwd_expired))
2226                 return False;
2227
2228         if (!smb_io_unihdr("hdr_comment", &info->hdr_comment, ps, depth))
2229                 return False;
2230         if (!smb_io_unihdr("hdr_parameters", &info->hdr_parameters, ps, 
2231                            depth))
2232                 return False;
2233         if (!prs_uint16("country", ps, depth, &info->country))
2234                 return False;
2235         if (!prs_uint16("codepage", ps, depth, &info->codepage))
2236                 return False;
2237
2238         if (!smb_io_bufhdr2("hdr_priv_data", &hdr_priv_data, ps, depth))
2239                 return False;
2240         if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
2241                 return False;
2242         if (!smb_io_unihdr("hdr_profile", &info->hdr_profile, ps, depth))
2243                 return False;
2244
2245         for (i = 0; i < 3; i++)
2246         {
2247                 if (!smb_io_unihdr("hdr_reserved", &info->hdr_reserved[i], 
2248                                    ps, depth))
2249                         return False;                                          
2250         }
2251
2252         for (i = 0; i < 4; i++)
2253         {
2254                 if (!prs_uint32("dw_reserved", ps, depth, 
2255                                 &info->dw_reserved[i]))
2256                         return False;
2257         }
2258
2259         if (!smb_io_unistr2("uni_acct_name", &info->uni_acct_name,
2260                             info->hdr_acct_name.buffer, ps, depth))
2261                 return False;
2262         prs_align(ps);
2263         if (!smb_io_unistr2("uni_full_name", &info->uni_full_name,
2264                             info->hdr_full_name.buffer, ps, depth))
2265                 return False;
2266         prs_align(ps);
2267         if (!smb_io_unistr2("uni_home_dir ", &info->uni_home_dir,
2268                             info->hdr_home_dir.buffer, ps, depth))
2269                 return False;
2270         prs_align(ps);
2271         if (!smb_io_unistr2("uni_dir_drive", &info->uni_dir_drive,
2272                             info->hdr_dir_drive.buffer, ps, depth))
2273                 return False;
2274         prs_align(ps);
2275         if (!smb_io_unistr2("uni_logon_script", &info->uni_logon_script,
2276                             info->hdr_logon_script.buffer, ps, depth))
2277                 return False;
2278         prs_align(ps);
2279         if (!smb_io_unistr2("uni_acct_desc", &info->uni_acct_desc,
2280                             info->hdr_acct_desc.buffer, ps, depth))
2281                 return False;
2282         prs_align(ps);
2283         if (!smb_io_unistr2("uni_workstations", &info->uni_workstations,
2284                             info->hdr_workstations.buffer, ps, depth))
2285                 return False;
2286         prs_align(ps);
2287
2288         if (!prs_uint32("unknown1", ps, depth, &info->unknown1))
2289                 return False;
2290         if (!prs_uint32("unknown2", ps, depth, &info->unknown2))
2291                 return False;
2292
2293         if (!smb_io_rpc_blob("buf_logon_hrs", &info->buf_logon_hrs, ps, depth))
2294                 return False;
2295         prs_align(ps);
2296         if (!smb_io_unistr2("uni_comment", &info->uni_comment,
2297                             info->hdr_comment.buffer, ps, depth))
2298                 return False;
2299         prs_align(ps);
2300         if (!smb_io_unistr2("uni_parameters", &info->uni_parameters,
2301                             info->hdr_parameters.buffer, ps, depth))
2302                 return False;
2303         prs_align(ps);
2304         if (hdr_priv_data.buffer != 0)
2305         {
2306                 int old_offset = 0;
2307                 uint32 len = 0x44;
2308                 if (!prs_uint32("pwd_len", ps, depth, &len))
2309                         return False;
2310                 old_offset = ps->data_offset;
2311                 if (len > 0)
2312                 {
2313                         if (ps->io)
2314                         {
2315                                 /* reading */
2316                                 if (!prs_hash1(ps, ps->data_offset, len))
2317                                         return False;
2318                         }
2319                         if (!net_io_sam_passwd_info("pass", &info->pass, 
2320                                                     ps, depth))
2321                                 return False;
2322
2323                         if (!ps->io)
2324                         {
2325                                 /* writing */
2326                                 if (!prs_hash1(ps, old_offset, len))
2327                                         return False;
2328                         }
2329                 }
2330                 if (old_offset + len > ps->buffer_size)
2331                         return False;
2332                 ps->data_offset = old_offset + len;
2333         }
2334         if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth))
2335                 return False;
2336         prs_align(ps);
2337         if (!smb_io_unistr2("uni_profile", &info->uni_profile,
2338                             info->hdr_profile.buffer, ps, depth))
2339                 return False;
2340
2341         prs_align(ps);
2342
2343         return True;
2344 }
2345
2346 /*******************************************************************
2347 reads or writes a structure.
2348 ********************************************************************/
2349 static BOOL net_io_sam_group_mem_info(const char *desc, SAM_GROUP_MEM_INFO * info,
2350                                       prs_struct *ps, int depth)
2351 {
2352         uint32 i;
2353         fstring tmp;
2354
2355         prs_debug(ps, depth, desc, "net_io_sam_group_mem_info");
2356         depth++;
2357
2358         prs_align(ps);
2359         if (!prs_uint32("ptr_rids   ", ps, depth, &info->ptr_rids))
2360                 return False;
2361         if (!prs_uint32("ptr_attribs", ps, depth, &info->ptr_attribs))
2362                 return False;
2363         if (!prs_uint32("num_members", ps, depth, &info->num_members))
2364                 return False;
2365
2366         if (ps->data_offset + 16 > ps->buffer_size)
2367                 return False;
2368         ps->data_offset += 16;
2369
2370         if (info->ptr_rids != 0)
2371         {
2372                 if (!prs_uint32("num_members2", ps, depth, 
2373                                 &info->num_members2))
2374                         return False;
2375
2376                 if (info->num_members2 != info->num_members)
2377                 {
2378                         /* RPC fault */
2379                         return False;
2380                 }
2381
2382                 info->rids = TALLOC_ARRAY(ps->mem_ctx, uint32, info->num_members2);
2383
2384                 if (info->rids == NULL) {
2385                         DEBUG(0, ("out of memory allocating %d rids\n",
2386                                   info->num_members2));
2387                         return False;
2388                 }
2389
2390                 for (i = 0; i < info->num_members2; i++)
2391                 {
2392                         slprintf(tmp, sizeof(tmp) - 1, "rids[%02d]", i);
2393                         if (!prs_uint32(tmp, ps, depth, &info->rids[i]))
2394                                 return False;
2395                 }
2396         }
2397
2398         if (info->ptr_attribs != 0)
2399         {
2400                 if (!prs_uint32("num_members3", ps, depth, 
2401                                 &info->num_members3))
2402                         return False;
2403                 if (info->num_members3 != info->num_members)
2404                 {
2405                         /* RPC fault */
2406                         return False;
2407                 }
2408
2409                 info->attribs = TALLOC_ARRAY(ps->mem_ctx, uint32, info->num_members3);
2410
2411                 if (info->attribs == NULL) {
2412                         DEBUG(0, ("out of memory allocating %d attribs\n",
2413                                   info->num_members3));
2414                         return False;
2415                 }
2416
2417                 for (i = 0; i < info->num_members3; i++)
2418                 {
2419                         slprintf(tmp, sizeof(tmp) - 1, "attribs[%02d]", i);
2420                         if (!prs_uint32(tmp, ps, depth, &info->attribs[i]))
2421                                 return False;
2422                 }
2423         }
2424
2425         return True;
2426 }
2427
2428 /*******************************************************************
2429 reads or writes a structure.
2430 ********************************************************************/
2431 static BOOL net_io_sam_alias_info(const char *desc, SAM_ALIAS_INFO * info,
2432                                   prs_struct *ps, int depth)
2433 {
2434         prs_debug(ps, depth, desc, "net_io_sam_alias_info");
2435         depth++;
2436
2437         if (!smb_io_unihdr("hdr_als_name", &info->hdr_als_name, ps, depth))
2438                 return False;
2439         if (!prs_uint32("als_rid", ps, depth, &info->als_rid))
2440                 return False;
2441         if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
2442                 return False;
2443         if (!smb_io_unihdr("hdr_als_desc", &info->hdr_als_desc, ps, depth))
2444                 return False;
2445
2446         if (ps->data_offset + 40 > ps->buffer_size)
2447                 return False;
2448         ps->data_offset += 40;
2449
2450         if (!smb_io_unistr2("uni_als_name", &info->uni_als_name,
2451                             info->hdr_als_name.buffer, ps, depth))
2452                 return False;
2453         if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth))
2454                 return False;
2455
2456         if (!smb_io_unistr2("uni_als_desc", &info->uni_als_desc,
2457                             info->hdr_als_desc.buffer, ps, depth))
2458                 return False;
2459
2460         return True;
2461 }
2462
2463 /*******************************************************************
2464 reads or writes a structure.
2465 ********************************************************************/
2466 static BOOL net_io_sam_alias_mem_info(const char *desc, SAM_ALIAS_MEM_INFO * info,
2467                                       prs_struct *ps, int depth)
2468 {
2469         uint32 i;
2470         fstring tmp;
2471
2472         prs_debug(ps, depth, desc, "net_io_sam_alias_mem_info");
2473         depth++;
2474
2475         prs_align(ps);
2476         if (!prs_uint32("num_members", ps, depth, &info->num_members))
2477                 return False;
2478         if (!prs_uint32("ptr_members", ps, depth, &info->ptr_members))
2479                 return False;
2480
2481         if (ps->data_offset + 16 > ps->buffer_size)
2482                 return False;
2483         ps->data_offset += 16;
2484
2485         if (info->ptr_members != 0)
2486         {
2487                 if (!prs_uint32("num_sids", ps, depth, &info->num_sids))
2488                         return False;
2489                 if (info->num_sids != info->num_members)
2490                 {
2491                         /* RPC fault */
2492                         return False;
2493                 }
2494
2495                 info->ptr_sids = TALLOC_ARRAY(ps->mem_ctx, uint32, info->num_sids);
2496                 
2497                 if (info->ptr_sids == NULL) {
2498                         DEBUG(0, ("out of memory allocating %d ptr_sids\n",
2499                                   info->num_sids));
2500                         return False;
2501                 }
2502
2503                 for (i = 0; i < info->num_sids; i++)
2504                 {
2505                         slprintf(tmp, sizeof(tmp) - 1, "ptr_sids[%02d]", i);
2506                         if (!prs_uint32(tmp, ps, depth, &info->ptr_sids[i]))
2507                                 return False;
2508                 }
2509
2510                 info->sids = TALLOC_ARRAY(ps->mem_ctx, DOM_SID2, info->num_sids);
2511
2512                 if (info->sids == NULL) {
2513                         DEBUG(0, ("error allocating %d sids\n",
2514                                   info->num_sids));
2515                         return False;
2516                 }
2517
2518                 for (i = 0; i < info->num_sids; i++)
2519                 {
2520                         if (info->ptr_sids[i] != 0)
2521                         {
2522                                 slprintf(tmp, sizeof(tmp) - 1, "sids[%02d]",
2523                                          i);
2524                                 if (!smb_io_dom_sid2(tmp, &info->sids[i], 
2525                                                      ps, depth))
2526                                         return False;
2527                         }
2528                 }
2529         }
2530
2531         return True;
2532 }
2533
2534 /*******************************************************************
2535 reads or writes a structure.
2536 ********************************************************************/
2537 static BOOL net_io_sam_policy_info(const char *desc, SAM_DELTA_POLICY *info,
2538                                       prs_struct *ps, int depth)
2539 {
2540         unsigned int i;
2541         prs_debug(ps, depth, desc, "net_io_sam_policy_info");
2542         depth++;
2543
2544         if(!prs_align(ps))
2545                 return False;
2546
2547         if (!prs_uint32("max_log_size", ps, depth, &info->max_log_size))
2548                 return False;
2549         if (!prs_uint64("audit_retention_period", ps, depth,
2550                         &info->audit_retention_period))
2551                 return False;
2552         if (!prs_uint32("auditing_mode", ps, depth, &info->auditing_mode))
2553                 return False;
2554         if (!prs_uint32("num_events", ps, depth, &info->num_events))
2555                 return False;
2556         if (!prs_uint32("ptr_events", ps, depth, &info->ptr_events))
2557                 return False;
2558
2559         if (!smb_io_unihdr("hdr_dom_name", &info->hdr_dom_name, ps, depth))
2560                 return False;
2561
2562         if (!prs_uint32("sid_ptr", ps, depth, &info->sid_ptr))
2563                 return False;
2564
2565         if (!prs_uint32("paged_pool_limit", ps, depth, &info->paged_pool_limit))
2566                 return False;
2567         if (!prs_uint32("non_paged_pool_limit", ps, depth,
2568                         &info->non_paged_pool_limit))
2569                 return False;
2570         if (!prs_uint32("min_workset_size", ps, depth, &info->min_workset_size))
2571                 return False;
2572         if (!prs_uint32("max_workset_size", ps, depth, &info->max_workset_size))
2573                 return False;
2574         if (!prs_uint32("page_file_limit", ps, depth, &info->page_file_limit))
2575                 return False;
2576         if (!prs_uint64("time_limit", ps, depth, &info->time_limit))
2577                 return False;
2578         if (!smb_io_time("modify_time", &info->modify_time, ps, depth))
2579                 return False;
2580         if (!smb_io_time("create_time", &info->create_time, ps, depth))
2581                 return False;
2582         if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
2583                 return False;
2584
2585         for (i=0; i<4; i++) {
2586                 UNIHDR dummy;
2587                 if (!smb_io_unihdr("dummy", &dummy, ps, depth))
2588                         return False;
2589         }
2590
2591         for (i=0; i<4; i++) {
2592                 uint32 reserved;
2593                 if (!prs_uint32("reserved", ps, depth, &reserved))
2594                         return False;
2595         }
2596
2597         if (!prs_uint32("num_event_audit_options", ps, depth,
2598                         &info->num_event_audit_options))
2599                 return False;
2600
2601         for (i=0; i<info->num_event_audit_options; i++)
2602                 if (!prs_uint32("event_audit_option", ps, depth,
2603                                 &info->event_audit_option))
2604                         return False;
2605
2606         if (!smb_io_unistr2("domain_name", &info->domain_name, True, ps, depth))
2607                 return False;
2608
2609         if(!smb_io_dom_sid2("domain_sid", &info->domain_sid, ps, depth))
2610                 return False;
2611
2612         if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth))
2613
2614                 return False;
2615
2616         return True;
2617 }
2618
2619 #if 0
2620
2621 /* This function is pretty broken - see bug #334 */
2622
2623 /*******************************************************************
2624 reads or writes a structure.
2625 ********************************************************************/
2626 static BOOL net_io_sam_trustdoms_info(const char *desc, SAM_DELTA_TRUSTDOMS *info,
2627                                       prs_struct *ps, int depth)
2628 {
2629         int i;
2630
2631         prs_debug(ps, depth, desc, "net_io_sam_trustdoms_info");
2632         depth++;
2633
2634         if(!prs_align(ps))
2635                 return False;
2636
2637         if(!prs_uint32("buf_size", ps, depth, &info->buf_size))
2638                 return False;
2639
2640         if(!sec_io_desc("sec_desc", &info->sec_desc, ps, depth))
2641                 return False;
2642
2643         if(!smb_io_dom_sid2("sid", &info->sid, ps, depth))
2644                 return False;
2645
2646         if(!smb_io_unihdr("hdr_domain", &info->hdr_domain, ps, depth))
2647                 return False;
2648
2649         if(!prs_uint32("unknown0", ps, depth, &info->unknown0))
2650                 return False;
2651         if(!prs_uint32("unknown1", ps, depth, &info->unknown1))
2652                 return False;
2653         if(!prs_uint32("unknown2", ps, depth, &info->unknown2))
2654                 return False;
2655
2656         if(!prs_uint32("buf_size2", ps, depth, &info->buf_size2))
2657                 return False;
2658         if(!prs_uint32("ptr", ps, depth, &info->ptr))
2659                 return False;
2660
2661         for (i=0; i<12; i++)
2662                 if(!prs_uint32("unknown3", ps, depth, &info->unknown3))
2663                         return False;
2664
2665         if (!smb_io_unistr2("domain", &info->domain, True, ps, depth))
2666                 return False;
2667
2668         return True;
2669 }
2670
2671 #endif
2672
2673 #if 0
2674
2675 /* This function doesn't work - see bug #334 */
2676
2677 /*******************************************************************
2678 reads or writes a structure.
2679 ********************************************************************/
2680 static BOOL net_io_sam_secret_info(const char *desc, SAM_DELTA_SECRET *info,
2681                                    prs_struct *ps, int depth)
2682 {
2683         int i;
2684
2685         prs_debug(ps, depth, desc, "net_io_sam_secret_info");
2686         depth++;
2687
2688         if(!prs_align(ps))
2689                 return False;
2690
2691         if(!prs_uint32("buf_size", ps, depth, &info->buf_size))
2692                 return False;
2693
2694         if(!sec_io_desc("sec_desc", &info->sec_desc, ps, depth))
2695                 return False;
2696
2697         if (!smb_io_unistr2("secret", &info->secret, True, ps, depth))
2698                 return False;
2699
2700         if(!prs_align(ps))
2701                 return False;
2702
2703         if(!prs_uint32("count1", ps, depth, &info->count1))
2704                 return False;
2705         if(!prs_uint32("count2", ps, depth, &info->count2))
2706                 return False;
2707         if(!prs_uint32("ptr", ps, depth, &info->ptr))
2708                 return False;
2709
2710
2711         if(!smb_io_time("time1", &info->time1, ps, depth)) /* logon time */
2712                 return False;
2713         if(!prs_uint32("count3", ps, depth, &info->count3))
2714                 return False;
2715         if(!prs_uint32("count4", ps, depth, &info->count4))
2716                 return False;
2717         if(!prs_uint32("ptr2", ps, depth, &info->ptr2))
2718                 return False;
2719         if(!smb_io_time("time2", &info->time2, ps, depth)) /* logon time */
2720                 return False;
2721         if(!prs_uint32("unknow1", ps, depth, &info->unknow1))
2722                 return False;
2723
2724
2725         if(!prs_uint32("buf_size2", ps, depth, &info->buf_size2))
2726                 return False;
2727         if(!prs_uint32("ptr3", ps, depth, &info->ptr3))
2728                 return False;
2729         for(i=0; i<12; i++)
2730                 if(!prs_uint32("unknow2", ps, depth, &info->unknow2))
2731                         return False;
2732
2733         if(!prs_uint32("chal_len", ps, depth, &info->chal_len))
2734                 return False;
2735         if(!prs_uint32("reserved1", ps, depth, &info->reserved1))
2736                 return False;
2737         if(!prs_uint32("chal_len2", ps, depth, &info->chal_len2))
2738                 return False;
2739
2740         if(!prs_uint8s (False, "chal", ps, depth, info->chal, info->chal_len2))
2741                 return False;
2742
2743         if(!prs_uint32("key_len", ps, depth, &info->key_len))
2744                 return False;
2745         if(!prs_uint32("reserved2", ps, depth, &info->reserved2))
2746                 return False;
2747         if(!prs_uint32("key_len2", ps, depth, &info->key_len2))
2748                 return False;
2749
2750         if(!prs_uint8s (False, "key", ps, depth, info->key, info->key_len2))
2751                 return False;
2752
2753
2754         if(!prs_uint32("buf_size3", ps, depth, &info->buf_size3))
2755                 return False;
2756
2757         if(!sec_io_desc("sec_desc2", &info->sec_desc2, ps, depth))
2758                 return False;
2759
2760
2761         return True;
2762 }
2763
2764 #endif
2765
2766 /*******************************************************************
2767 reads or writes a structure.
2768 ********************************************************************/
2769 static BOOL net_io_sam_privs_info(const char *desc, SAM_DELTA_PRIVS *info,
2770                                       prs_struct *ps, int depth)
2771 {
2772         unsigned int i;
2773
2774         prs_debug(ps, depth, desc, "net_io_sam_privs_info");
2775         depth++;
2776
2777         if(!prs_align(ps))
2778                 return False;
2779
2780         if(!smb_io_dom_sid2("sid", &info->sid, ps, depth))
2781                 return False;
2782
2783         if(!prs_uint32("priv_count", ps, depth, &info->priv_count))
2784                 return False;
2785         if(!prs_uint32("priv_control", ps, depth, &info->priv_control))
2786                 return False;
2787
2788         if(!prs_uint32("priv_attr_ptr", ps, depth, &info->priv_attr_ptr))
2789                 return False;
2790         if(!prs_uint32("priv_name_ptr", ps, depth, &info->priv_name_ptr))
2791                 return False;
2792
2793         if (!prs_uint32("paged_pool_limit", ps, depth, &info->paged_pool_limit))
2794                 return False;
2795         if (!prs_uint32("non_paged_pool_limit", ps, depth,
2796                         &info->non_paged_pool_limit))
2797                 return False;
2798         if (!prs_uint32("min_workset_size", ps, depth, &info->min_workset_size))
2799                 return False;
2800         if (!prs_uint32("max_workset_size", ps, depth, &info->max_workset_size))
2801                 return False;
2802         if (!prs_uint32("page_file_limit", ps, depth, &info->page_file_limit))
2803                 return False;
2804         if (!prs_uint64("time_limit", ps, depth, &info->time_limit))
2805                 return False;
2806         if (!prs_uint32("system_flags", ps, depth, &info->system_flags))
2807                 return False;
2808         if (!smb_io_bufhdr2("hdr_sec_desc", &info->hdr_sec_desc, ps, depth))
2809                 return False;
2810
2811         for (i=0; i<4; i++) {
2812                 UNIHDR dummy;
2813                 if (!smb_io_unihdr("dummy", &dummy, ps, depth))
2814                         return False;
2815         }
2816
2817         for (i=0; i<4; i++) {
2818                 uint32 reserved;
2819                 if (!prs_uint32("reserved", ps, depth, &reserved))
2820                         return False;
2821         }
2822
2823         if(!prs_uint32("attribute_count", ps, depth, &info->attribute_count))
2824                 return False;
2825
2826         info->attributes = TALLOC_ARRAY(ps->mem_ctx, uint32, info->attribute_count);
2827
2828         for (i=0; i<info->attribute_count; i++)
2829                 if(!prs_uint32("attributes", ps, depth, &info->attributes[i]))
2830                         return False;
2831
2832         if(!prs_uint32("privlist_count", ps, depth, &info->privlist_count))
2833                 return False;
2834
2835         info->hdr_privslist = TALLOC_ARRAY(ps->mem_ctx, UNIHDR, info->privlist_count);
2836         info->uni_privslist = TALLOC_ARRAY(ps->mem_ctx, UNISTR2, info->privlist_count);
2837
2838         for (i=0; i<info->privlist_count; i++)
2839                 if(!smb_io_unihdr("hdr_privslist", &info->hdr_privslist[i], ps, depth))
2840                         return False;
2841
2842         for (i=0; i<info->privlist_count; i++)
2843                 if (!smb_io_unistr2("uni_privslist", &info->uni_privslist[i], True, ps, depth))
2844                         return False;
2845
2846         if (!smb_io_rpc_blob("buf_sec_desc", &info->buf_sec_desc, ps, depth))
2847                 return False;
2848
2849         return True;
2850 }
2851
2852 /*******************************************************************
2853 reads or writes a structure.
2854 ********************************************************************/
2855 static BOOL net_io_sam_delta_ctr(const char *desc,
2856                                  SAM_DELTA_CTR * delta, uint16 type,
2857                                  prs_struct *ps, int depth)
2858 {
2859         prs_debug(ps, depth, desc, "net_io_sam_delta_ctr");
2860         depth++;
2861
2862         switch (type) {
2863                 /* Seen in sam deltas */
2864                 case SAM_DELTA_MODIFIED_COUNT:
2865                         if (!net_io_sam_delta_mod_count("", &delta->mod_count, ps, depth))
2866                                 return False;
2867                         break;
2868
2869                 case SAM_DELTA_DOMAIN_INFO:
2870                         if (!net_io_sam_domain_info("", &delta->domain_info, ps, depth))
2871                                 return False;
2872                         break;
2873
2874                 case SAM_DELTA_GROUP_INFO:
2875                         if (!net_io_sam_group_info("", &delta->group_info, ps, depth))
2876                                 return False;
2877                         break;
2878
2879                 case SAM_DELTA_ACCOUNT_INFO:
2880                         if (!net_io_sam_account_info("", &delta->account_info, ps, depth))
2881                                 return False;
2882                         break;
2883
2884                 case SAM_DELTA_GROUP_MEM:
2885                         if (!net_io_sam_group_mem_info("", &delta->grp_mem_info, ps, depth))
2886                                 return False;
2887                         break;
2888
2889                 case SAM_DELTA_ALIAS_INFO:
2890                         if (!net_io_sam_alias_info("", &delta->alias_info, ps, depth))
2891                                 return False;
2892                         break;
2893
2894                 case SAM_DELTA_POLICY_INFO:
2895                         if (!net_io_sam_policy_info("", &delta->policy_info, ps, depth))
2896                                 return False;
2897                         break;
2898
2899                 case SAM_DELTA_ALIAS_MEM:
2900                         if (!net_io_sam_alias_mem_info("", &delta->als_mem_info, ps, depth))
2901                                 return False;
2902                         break;
2903
2904                 case SAM_DELTA_PRIVS_INFO:
2905                         if (!net_io_sam_privs_info("", &delta->privs_info, ps, depth))
2906                                 return False;
2907                         break;
2908
2909                         /* These guys are implemented but broken */
2910
2911                 case SAM_DELTA_TRUST_DOMS:
2912                 case SAM_DELTA_SECRET_INFO:
2913                         break;
2914
2915                         /* These guys are not implemented yet */
2916
2917                 case SAM_DELTA_RENAME_GROUP:
2918                 case SAM_DELTA_RENAME_USER:
2919                 case SAM_DELTA_RENAME_ALIAS:
2920                 case SAM_DELTA_DELETE_GROUP:
2921                 case SAM_DELTA_DELETE_USER:
2922                 default:
2923                         DEBUG(0, ("Replication error: Unknown delta type 0x%x\n", type));
2924                         break;
2925         }
2926
2927         return True;
2928 }
2929
2930 /*******************************************************************
2931 reads or writes a structure.
2932 ********************************************************************/
2933 BOOL net_io_r_sam_sync(const char *desc,
2934                        NET_R_SAM_SYNC * r_s, prs_struct *ps, int depth)
2935 {
2936         uint32 i;
2937
2938         prs_debug(ps, depth, desc, "net_io_r_sam_sync");
2939         depth++;
2940
2941         if (!smb_io_cred("srv_creds", &r_s->srv_creds, ps, depth))
2942                 return False;
2943         if (!prs_uint32("sync_context", ps, depth, &r_s->sync_context))
2944                 return False;
2945
2946         if (!prs_uint32("ptr_deltas", ps, depth, &r_s->ptr_deltas))
2947                 return False;
2948         if (r_s->ptr_deltas != 0)
2949         {
2950                 if (!prs_uint32("num_deltas ", ps, depth, &r_s->num_deltas))
2951                         return False;
2952                 if (!prs_uint32("ptr_deltas2", ps, depth, &r_s->ptr_deltas2))
2953                         return False;
2954                 if (r_s->ptr_deltas2 != 0)
2955                 {
2956                         if (!prs_uint32("num_deltas2", ps, depth,
2957                                         &r_s->num_deltas2))
2958                                 return False;
2959
2960                         if (r_s->num_deltas2 != r_s->num_deltas)
2961                         {
2962                                 /* RPC fault */
2963                                 return False;
2964                         }
2965
2966                         if (r_s->num_deltas2 > 0) {
2967                                 r_s->hdr_deltas = TALLOC_ARRAY(ps->mem_ctx, SAM_DELTA_HDR, r_s->num_deltas2);
2968                                 if (r_s->hdr_deltas == NULL) {
2969                                         DEBUG(0, ("error tallocating memory "
2970                                                   "for %d delta headers\n", 
2971                                                   r_s->num_deltas2));
2972                                         return False;
2973                                 }
2974                         }
2975
2976                         for (i = 0; i < r_s->num_deltas2; i++)
2977                         {
2978                                 if (!net_io_sam_delta_hdr("", 
2979                                                           &r_s->hdr_deltas[i],
2980                                                           ps, depth))
2981                                         return False;
2982                         }
2983
2984                         if (r_s->num_deltas2 > 0) {
2985                                 r_s->deltas = TALLOC_ARRAY(ps->mem_ctx, SAM_DELTA_CTR, r_s->num_deltas2);
2986                                 if (r_s->deltas == NULL) {
2987                                         DEBUG(0, ("error tallocating memory "
2988                                                   "for %d deltas\n", 
2989                                                   r_s->num_deltas2));
2990                                         return False;
2991                                 }
2992                         }
2993
2994                         for (i = 0; i < r_s->num_deltas2; i++)
2995                         {
2996                                 if (!net_io_sam_delta_ctr(
2997                                         "", &r_s->deltas[i],
2998                                         r_s->hdr_deltas[i].type3,
2999                                         ps, depth)) {
3000                                         DEBUG(0, ("hmm, failed on i=%d\n", i));
3001                                         return False;
3002                                 }
3003                         }
3004                 }
3005         }
3006
3007         prs_align(ps);
3008         if (!prs_ntstatus("status", ps, depth, &(r_s->status)))
3009                 return False;
3010
3011         return True;
3012 }
3013
3014 /*******************************************************************
3015 makes a NET_Q_SAM_DELTAS structure.
3016 ********************************************************************/
3017 BOOL init_net_q_sam_deltas(NET_Q_SAM_DELTAS *q_s, const char *srv_name, 
3018                            const char *cli_name, DOM_CRED *cli_creds, 
3019                            uint32 database_id, UINT64_S dom_mod_count)
3020 {
3021         DEBUG(5, ("init_net_q_sam_deltas\n"));
3022
3023         init_unistr2(&q_s->uni_srv_name, srv_name, UNI_STR_TERMINATE);
3024         init_unistr2(&q_s->uni_cli_name, cli_name, UNI_STR_TERMINATE);
3025
3026         memcpy(&q_s->cli_creds, cli_creds, sizeof(q_s->cli_creds));
3027         memset(&q_s->ret_creds, 0, sizeof(q_s->ret_creds));
3028
3029         q_s->database_id = database_id;
3030         q_s->dom_mod_count.low = dom_mod_count.low;
3031         q_s->dom_mod_count.high = dom_mod_count.high;
3032         q_s->max_size = 0xffff;
3033
3034         return True;
3035 }
3036
3037 /*******************************************************************
3038 reads or writes a structure.
3039 ********************************************************************/
3040 BOOL net_io_q_sam_deltas(const char *desc, NET_Q_SAM_DELTAS *q_s, prs_struct *ps,
3041                          int depth)
3042 {
3043         prs_debug(ps, depth, desc, "net_io_q_sam_deltas");
3044         depth++;
3045
3046         if (!smb_io_unistr2("", &q_s->uni_srv_name, True, ps, depth))
3047                 return False;
3048         if (!smb_io_unistr2("", &q_s->uni_cli_name, True, ps, depth))
3049                 return False;
3050
3051         if (!smb_io_cred("", &q_s->cli_creds, ps, depth))
3052                 return False;
3053         if (!smb_io_cred("", &q_s->ret_creds, ps, depth))
3054                 return False;
3055
3056         if (!prs_uint32("database_id  ", ps, depth, &q_s->database_id))
3057                 return False;
3058         if (!prs_uint64("dom_mod_count", ps, depth, &q_s->dom_mod_count))
3059                 return False;
3060         if (!prs_uint32("max_size", ps, depth, &q_s->max_size))
3061                 return False;
3062
3063         return True;
3064 }
3065
3066 /*******************************************************************
3067 reads or writes a structure.
3068 ********************************************************************/
3069 BOOL net_io_r_sam_deltas(const char *desc,
3070                          NET_R_SAM_DELTAS *r_s, prs_struct *ps, int depth)
3071 {
3072         unsigned int i;
3073
3074         prs_debug(ps, depth, desc, "net_io_r_sam_deltas");
3075         depth++;
3076
3077         if (!smb_io_cred("srv_creds", &r_s->srv_creds, ps, depth))
3078                 return False;
3079         if (!prs_uint64("dom_mod_count", ps, depth, &r_s->dom_mod_count))
3080                 return False;
3081
3082         if (!prs_uint32("ptr_deltas", ps, depth, &r_s->ptr_deltas))
3083                 return False;
3084         if (!prs_uint32("num_deltas", ps, depth, &r_s->num_deltas))
3085                 return False;
3086         if (!prs_uint32("ptr_deltas2", ps, depth, &r_s->num_deltas2))
3087                 return False;
3088
3089         if (r_s->num_deltas2 != 0)
3090         {
3091                 if (!prs_uint32("num_deltas2 ", ps, depth, &r_s->num_deltas2))
3092                         return False;
3093
3094                 if (r_s->ptr_deltas != 0)
3095                 {
3096                         if (r_s->num_deltas > 0) {
3097                                 r_s->hdr_deltas = TALLOC_ARRAY(ps->mem_ctx, SAM_DELTA_HDR, r_s->num_deltas);
3098                                 if (r_s->hdr_deltas == NULL) {
3099                                         DEBUG(0, ("error tallocating memory "
3100                                                   "for %d delta headers\n", 
3101                                                   r_s->num_deltas));
3102                                         return False;
3103                                 }
3104                         }
3105
3106                         for (i = 0; i < r_s->num_deltas; i++)
3107                         {
3108                                 net_io_sam_delta_hdr("", &r_s->hdr_deltas[i],
3109                                                       ps, depth);
3110                         }
3111                         
3112                         if (r_s->num_deltas > 0) {
3113                                 r_s->deltas = TALLOC_ARRAY(ps->mem_ctx, SAM_DELTA_CTR, r_s->num_deltas);
3114                                 if (r_s->deltas == NULL) {
3115                                         DEBUG(0, ("error tallocating memory "
3116                                                   "for %d deltas\n", 
3117                                                   r_s->num_deltas));
3118                                         return False;
3119                                 }
3120                         }
3121
3122                         for (i = 0; i < r_s->num_deltas; i++)
3123                         {
3124                                 if (!net_io_sam_delta_ctr(
3125                                         "",
3126                                         &r_s->deltas[i],
3127                                         r_s->hdr_deltas[i].type2,
3128                                         ps, depth))
3129                                         
3130                                         return False;
3131                         }
3132                 }
3133         }
3134
3135         prs_align(ps);
3136         if (!prs_ntstatus("status", ps, depth, &r_s->status))
3137                 return False;
3138
3139         return True;
3140 }