return results on prs_xxxxx() and all xxx_io_xxx() routines.
[ambi/samba-autobuild/.git] / source3 / rpc_parse / parse_net.c
1 /* 
2  *  Unix SMB/Netbios implementation.
3  *  Version 1.9.
4  *  RPC Pipe client / server routines
5  *  Copyright (C) Andrew Tridgell              1992-1997,
6  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
7  *  Copyright (C) Paul Ashton                       1997.
8  *  
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2 of the License, or
12  *  (at your option) any later version.
13  *  
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *  
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; if not, write to the Free Software
21  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22  */
23
24 #include "includes.h"
25 #include "nterr.h"
26
27 extern int DEBUGLEVEL;
28
29 /*******************************************************************
30 reads or writes a structure.
31 ********************************************************************/
32 static BOOL net_io_neg_flags(char *desc,  NEG_FLAGS *neg, prs_struct *ps, int depth)
33 {
34         if (neg == NULL) return False;
35
36         prs_debug(ps, depth, desc, "net_io_neg_flags");
37         depth++;
38
39         prs_align(ps);
40         
41         prs_uint32("neg_flags", ps, depth, &(neg->neg_flags));
42
43         return True;
44 }
45
46 /*******************************************************************
47 creates a NETLOGON_INFO_3 structure.
48 ********************************************************************/
49 static BOOL make_netinfo_3(NETLOGON_INFO_3 *info, uint32 flags, uint32 logon_attempts)
50 {
51         info->flags          = flags;
52         info->logon_attempts = logon_attempts;
53         info->reserved_1     = 0x0;
54         info->reserved_2     = 0x0;
55         info->reserved_3     = 0x0;
56         info->reserved_4     = 0x0;
57         info->reserved_5     = 0x0;
58
59         return True;
60 }
61
62 /*******************************************************************
63 reads or writes a NETLOGON_INFO_3 structure.
64 ********************************************************************/
65 static BOOL net_io_netinfo_3(char *desc,  NETLOGON_INFO_3 *info, prs_struct *ps, int depth)
66 {
67         if (info == NULL) return False;
68
69         prs_debug(ps, depth, desc, "net_io_netinfo_3");
70         depth++;
71
72         prs_align(ps);
73         
74         prs_uint32("flags         ", ps, depth, &(info->flags         ));
75         prs_uint32("logon_attempts", ps, depth, &(info->logon_attempts));
76         prs_uint32("reserved_1    ", ps, depth, &(info->reserved_1    ));
77         prs_uint32("reserved_2    ", ps, depth, &(info->reserved_2    ));
78         prs_uint32("reserved_3    ", ps, depth, &(info->reserved_3    ));
79         prs_uint32("reserved_4    ", ps, depth, &(info->reserved_4    ));
80         prs_uint32("reserved_5    ", ps, depth, &(info->reserved_5    ));
81
82         return True;
83 }
84
85
86 /*******************************************************************
87 creates a NETLOGON_INFO_1 structure.
88 ********************************************************************/
89 static BOOL make_netinfo_1(NETLOGON_INFO_1 *info, uint32 flags, uint32 pdc_status)
90 {
91         info->flags      = flags;
92         info->pdc_status = pdc_status;
93
94         return True;
95 }
96
97 /*******************************************************************
98 reads or writes a NETLOGON_INFO_1 structure.
99 ********************************************************************/
100 static BOOL net_io_netinfo_1(char *desc,  NETLOGON_INFO_1 *info, prs_struct *ps, int depth)
101 {
102         if (info == NULL) return False;
103
104         prs_debug(ps, depth, desc, "net_io_netinfo_1");
105         depth++;
106
107         prs_align(ps);
108         
109         prs_uint32("flags     ", ps, depth, &(info->flags     ));
110         prs_uint32("pdc_status", ps, depth, &(info->pdc_status));
111
112         return True;
113 }
114
115 /*******************************************************************
116 creates a NETLOGON_INFO_2 structure.
117 ********************************************************************/
118 static BOOL make_netinfo_2(NETLOGON_INFO_2 *info, uint32 flags, uint32 pdc_status,
119                                 uint32 tc_status, char *trusted_dc_name)
120 {
121         int len_dc_name = strlen(trusted_dc_name);
122         info->flags      = flags;
123         info->pdc_status = pdc_status;
124         info->ptr_trusted_dc_name = 1;
125         info->tc_status  = tc_status;
126
127         if (trusted_dc_name != NULL)
128         {
129                 make_unistr2(&(info->uni_trusted_dc_name), trusted_dc_name, len_dc_name+1);
130         }
131         else
132         {
133                 make_unistr2(&(info->uni_trusted_dc_name), "", 1);
134         }
135
136         return True;
137 }
138
139 /*******************************************************************
140 reads or writes a NETLOGON_INFO_2 structure.
141 ********************************************************************/
142 static BOOL net_io_netinfo_2(char *desc,  NETLOGON_INFO_2 *info, prs_struct *ps, int depth)
143 {
144         if (info == NULL) return False;
145
146         prs_debug(ps, depth, desc, "net_io_netinfo_2");
147         depth++;
148
149         prs_align(ps);
150         
151         prs_uint32("flags              ", ps, depth, &(info->flags              ));
152         prs_uint32("pdc_status         ", ps, depth, &(info->pdc_status         ));
153         prs_uint32("ptr_trusted_dc_name", ps, depth, &(info->ptr_trusted_dc_name));
154         prs_uint32("tc_status          ", ps, depth, &(info->tc_status          ));
155
156         if (info->ptr_trusted_dc_name != 0)
157         {
158                 smb_io_unistr2("unistr2", &(info->uni_trusted_dc_name), info->ptr_trusted_dc_name, ps, depth);
159         }
160
161         prs_align(ps);
162
163         return True;
164 }
165
166 /*******************************************************************
167 reads or writes an NET_Q_LOGON_CTRL2 structure.
168 ********************************************************************/
169 BOOL net_io_q_logon_ctrl2(char *desc,  NET_Q_LOGON_CTRL2 *q_l, prs_struct *ps, int depth)
170 {
171         if (q_l == NULL) return False;
172
173         prs_debug(ps, depth, desc, "net_io_q_logon_ctrl2");
174         depth++;
175
176         prs_align(ps);
177
178         prs_uint32("ptr          ", ps, depth, &(q_l->ptr          ));
179
180         smb_io_unistr2 ("", &(q_l->uni_server_name), q_l->ptr, ps, depth);
181
182         prs_align(ps);
183
184         prs_uint32("function_code", ps, depth, &(q_l->function_code));
185         prs_uint32("query_level  ", ps, depth, &(q_l->query_level  ));
186         prs_uint32("switch_value ", ps, depth, &(q_l->switch_value ));
187
188         return True;
189 }
190
191 /*******************************************************************
192 makes an NET_R_LOGON_CTRL2 structure.
193 ********************************************************************/
194 BOOL make_r_logon_ctrl2(NET_R_LOGON_CTRL2 *r_l, uint32 query_level,
195                                 uint32 flags, uint32 pdc_status, uint32 logon_attempts,
196                                 uint32 tc_status, char *trusted_domain_name)
197 {
198         if (r_l == NULL) return False;
199
200         DEBUG(5,("make_r_logon_ctrl2\n"));
201
202         r_l->switch_value  = query_level; /* should only be 0x1 */
203
204         switch (query_level)
205         {
206                 case 1:
207                 {
208                         r_l->ptr = 1; /* undocumented pointer */
209                         make_netinfo_1(&(r_l->logon.info1), flags, pdc_status); 
210                         r_l->status = 0;
211
212                         break;
213                 }
214                 case 2:
215                 {
216                         r_l->ptr = 1; /* undocumented pointer */
217                         make_netinfo_2(&(r_l->logon.info2), flags, pdc_status,
218                                        tc_status, trusted_domain_name); 
219                         r_l->status = 0;
220
221                         break;
222                 }
223                 case 3:
224                 {
225                         r_l->ptr = 1; /* undocumented pointer */
226                         make_netinfo_3(&(r_l->logon.info3), flags, logon_attempts);     
227                         r_l->status = 0;
228
229                         break;
230                 }
231                 default:
232                 {
233                         DEBUG(2,("make_r_logon_ctrl2: unsupported switch value %d\n",
234                                 r_l->switch_value));
235                         r_l->ptr = 0; /* undocumented pointer */
236
237                         /* take a guess at an error code... */
238                         r_l->status = NT_STATUS_INVALID_INFO_CLASS;
239
240                         break;
241                 }
242         }
243
244         return True;
245 }
246
247 /*******************************************************************
248 reads or writes an NET_R_LOGON_CTRL2 structure.
249 ********************************************************************/
250 BOOL net_io_r_logon_ctrl2(char *desc,  NET_R_LOGON_CTRL2 *r_l, prs_struct *ps, int depth)
251 {
252         if (r_l == NULL) return False;
253
254         prs_debug(ps, depth, desc, "net_io_r_logon_ctrl2");
255         depth++;
256
257         prs_uint32("switch_value ", ps, depth, &(r_l->switch_value ));
258         prs_uint32("ptr          ", ps, depth, &(r_l->ptr          ));
259
260         if (r_l->ptr != 0)
261         {
262                 switch (r_l->switch_value)
263                 {
264                         case 1:
265                         {
266                                 net_io_netinfo_1("", &(r_l->logon.info1), ps, depth);
267                                 break;
268                         }
269                         case 2:
270                         {
271                                 net_io_netinfo_2("", &(r_l->logon.info2), ps, depth);
272                                 break;
273                         }
274                         case 3:
275                         {
276                                 net_io_netinfo_3("", &(r_l->logon.info3), ps, depth);
277                                 break;
278                         }
279                         default:
280                         {
281                                 DEBUG(2,("net_io_r_logon_ctrl2: unsupported switch value %d\n",
282                                         r_l->switch_value));
283                                 break;
284                         }
285                 }
286         }
287
288         prs_uint32("status       ", ps, depth, &(r_l->status       ));
289
290         return True;
291 }
292
293 /*******************************************************************
294 makes an NET_R_TRUST_DOM_LIST structure.
295 ********************************************************************/
296 BOOL make_r_trust_dom(NET_R_TRUST_DOM_LIST *r_t,
297                         uint32 num_doms, char *dom_name)
298 {
299         int i = 0;
300
301         if (r_t == NULL) return False;
302
303         DEBUG(5,("make_r_trust_dom\n"));
304
305         for (i = 0; i < MAX_TRUST_DOMS; i++)
306         {
307                 r_t->uni_trust_dom_name[i].uni_str_len = 0;
308                 r_t->uni_trust_dom_name[i].uni_max_len = 0;
309         }
310         if (num_doms > MAX_TRUST_DOMS) num_doms = MAX_TRUST_DOMS;
311
312         for (i = 0; i < num_doms; i++)
313         {
314                 fstring domain_name;
315                 fstrcpy(domain_name, dom_name);
316                 strupper(domain_name);
317                 make_unistr2(&(r_t->uni_trust_dom_name[i]), domain_name, strlen(domain_name)+1);
318                 /* the use of UNISTR2 here is non-standard. */
319                 r_t->uni_trust_dom_name[i].undoc = 0x1;
320         }
321         
322         r_t->status = 0;
323
324         return True;
325 }
326
327 /*******************************************************************
328 reads or writes an NET_R_TRUST_DOM_LIST structure.
329 ********************************************************************/
330 BOOL net_io_r_trust_dom(char *desc,  NET_R_TRUST_DOM_LIST *r_t, prs_struct *ps, int depth)
331 {
332         int i;
333         if (r_t == NULL) return False;
334
335         prs_debug(ps, depth, desc, "net_io_r_trust_dom");
336         depth++;
337
338         for (i = 0; i < MAX_TRUST_DOMS; i++)
339         {
340                 if (r_t->uni_trust_dom_name[i].uni_str_len == 0) break;
341                 smb_io_unistr2("", &(r_t->uni_trust_dom_name[i]), True, ps, depth);
342         }
343
344         prs_uint32("status", ps, depth, &(r_t->status));
345
346         return True;
347 }
348
349
350 /*******************************************************************
351 reads or writes an NET_Q_TRUST_DOM_LIST structure.
352 ********************************************************************/
353 BOOL net_io_q_trust_dom(char *desc,  NET_Q_TRUST_DOM_LIST *q_l, prs_struct *ps, int depth)
354 {
355         if (q_l == NULL) return False;
356
357         prs_debug(ps, depth, desc, "net_io_q_trust_dom");
358         depth++;
359
360         prs_uint32("ptr          ", ps, depth, &(q_l->ptr          ));
361         smb_io_unistr2 ("", &(q_l->uni_server_name), q_l->ptr, ps, depth);
362
363         prs_align(ps);
364
365         prs_uint32("function_code", ps, depth, &(q_l->function_code));
366
367         return True;
368 }
369
370 /*******************************************************************
371 makes an NET_Q_REQ_CHAL structure.
372 ********************************************************************/
373 BOOL make_q_req_chal(NET_Q_REQ_CHAL *q_c,
374                                 char *logon_srv, char *logon_clnt,
375                                 DOM_CHAL *clnt_chal)
376 {
377         if (q_c == NULL) return False;
378
379         DEBUG(5,("make_q_req_chal: %d\n", __LINE__));
380
381         q_c->undoc_buffer = 1; /* don't know what this buffer is */
382
383         make_unistr2(&(q_c->uni_logon_srv ), logon_srv , strlen(logon_srv )+1);
384         make_unistr2(&(q_c->uni_logon_clnt), logon_clnt, strlen(logon_clnt)+1);
385
386         memcpy(q_c->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data));
387
388         DEBUG(5,("make_q_req_chal: %d\n", __LINE__));
389
390         return True;
391 }
392
393 /*******************************************************************
394 reads or writes an NET_Q_REQ_CHAL structure.
395 ********************************************************************/
396 BOOL net_io_q_req_chal(char *desc,  NET_Q_REQ_CHAL *q_c, prs_struct *ps, int depth)
397 {
398         int old_align;
399         if (q_c == NULL) return False;
400
401         prs_debug(ps, depth, desc, "net_io_q_req_chal");
402         depth++;
403
404         prs_align(ps);
405     
406         prs_uint32("undoc_buffer", ps, depth, &(q_c->undoc_buffer));
407
408         smb_io_unistr2("", &(q_c->uni_logon_srv ), True, ps, depth); /* logon server unicode string */
409         smb_io_unistr2("", &(q_c->uni_logon_clnt), True, ps, depth); /* logon client unicode string */
410
411         old_align = ps->align;
412         ps->align = 0;
413         /* client challenge is _not_ aligned after the unicode strings */
414         smb_io_chal("", &(q_c->clnt_chal), ps, depth); /* client challenge */
415         ps->align = old_align;
416
417         return True;
418 }
419
420 /*******************************************************************
421 reads or writes a structure.
422 ********************************************************************/
423 BOOL net_io_r_req_chal(char *desc,  NET_R_REQ_CHAL *r_c, prs_struct *ps, int depth)
424 {
425         if (r_c == NULL) return False;
426
427         prs_debug(ps, depth, desc, "net_io_r_req_chal");
428         depth++;
429
430         prs_align(ps);
431     
432         smb_io_chal("", &(r_c->srv_chal), ps, depth); /* server challenge */
433
434         prs_uint32("status", ps, depth, &(r_c->status));
435
436         return True;
437 }
438
439
440 /*******************************************************************
441 reads or writes a structure.
442 ********************************************************************/
443 BOOL make_q_auth_2(NET_Q_AUTH_2 *q_a,
444                 const char *logon_srv, const char *acct_name,
445                 uint16 sec_chan, const char *comp_name,
446                 DOM_CHAL *clnt_chal, uint32 clnt_flgs)
447 {
448         if (q_a == NULL) return False;
449
450         DEBUG(5,("make_q_auth_2: %d\n", __LINE__));
451
452         make_log_info(&(q_a->clnt_id), logon_srv, acct_name, sec_chan, comp_name);
453         memcpy(q_a->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data));
454         q_a->clnt_flgs.neg_flags = clnt_flgs;
455
456         DEBUG(5,("make_q_auth_2: %d\n", __LINE__));
457
458         return True;
459 }
460
461 /*******************************************************************
462 reads or writes a structure.
463 ********************************************************************/
464 BOOL net_io_q_auth_2(char *desc,  NET_Q_AUTH_2 *q_a, prs_struct *ps, int depth)
465 {
466         int old_align;
467         if (q_a == NULL) return False;
468
469         prs_debug(ps, depth, desc, "net_io_q_auth_2");
470         depth++;
471
472         prs_align(ps);
473     
474         smb_io_log_info ("", &(q_a->clnt_id), ps, depth); /* client identification info */
475         /* client challenge is _not_ aligned */
476         old_align = ps->align;
477         ps->align = 0;
478         smb_io_chal     ("", &(q_a->clnt_chal), ps, depth); /* client-calculated credentials */
479         ps->align = old_align;
480         net_io_neg_flags("", &(q_a->clnt_flgs), ps, depth);
481
482         return True;
483 }
484
485 /*******************************************************************
486 reads or writes a structure.
487 ********************************************************************/
488 BOOL net_io_r_auth_2(char *desc,  NET_R_AUTH_2 *r_a, prs_struct *ps, int depth)
489 {
490         if (r_a == NULL) return False;
491
492         prs_debug(ps, depth, desc, "net_io_r_auth_2");
493         depth++;
494
495         prs_align(ps);
496     
497         smb_io_chal     ("", &(r_a->srv_chal), ps, depth); /* server challenge */
498         net_io_neg_flags("", &(r_a->srv_flgs), ps, depth);
499
500         prs_uint32("status", ps, depth, &(r_a->status));
501
502         return True;
503 }
504
505
506 /*******************************************************************
507 reads or writes a structure.
508 ********************************************************************/
509 BOOL make_q_srv_pwset(NET_Q_SRV_PWSET *q_s, char *logon_srv, char *acct_name, 
510                 uint16 sec_chan, char *comp_name, DOM_CRED *cred, char nt_cypher[16])
511 {
512         if (q_s == NULL || cred == NULL) return False;
513
514         DEBUG(5,("make_q_srv_pwset\n"));
515
516         make_clnt_info(&(q_s->clnt_id), logon_srv, acct_name, sec_chan, comp_name, cred);
517
518         memcpy(q_s->pwd, nt_cypher, sizeof(q_s->pwd)); 
519
520         return True;
521 }
522
523 /*******************************************************************
524 reads or writes a structure.
525 ********************************************************************/
526 BOOL net_io_q_srv_pwset(char *desc,  NET_Q_SRV_PWSET *q_s, prs_struct *ps, int depth)
527 {
528         if (q_s == NULL) return False;
529
530         prs_debug(ps, depth, desc, "net_io_q_srv_pwset");
531         depth++;
532
533         prs_align(ps);
534     
535         smb_io_clnt_info("", &(q_s->clnt_id), ps, depth); /* client identification/authentication info */
536         prs_uint8s (False, "pwd", ps, depth, q_s->pwd, 16); /* new password - undocumented */
537
538         return True;
539 }
540
541 /*******************************************************************
542 reads or writes a structure.
543 ********************************************************************/
544 BOOL net_io_r_srv_pwset(char *desc,  NET_R_SRV_PWSET *r_s, prs_struct *ps, int depth)
545 {
546         if (r_s == NULL) return False;
547
548         prs_debug(ps, depth, desc, "net_io_r_srv_pwset");
549         depth++;
550
551         prs_align(ps);
552     
553         smb_io_cred("", &(r_s->srv_cred), ps, depth); /* server challenge */
554
555         prs_uint32("status", ps, depth, &(r_s->status));
556
557         return True;
558 }
559
560
561 /*************************************************************************
562  make DOM_SID2 array from a string containing multiple sids
563  *************************************************************************/
564 static int make_dom_sid2s(char *sids_str, DOM_SID2 *sids, int max_sids)
565 {
566         char *ptr;
567         pstring s2;
568         int count;
569
570         DEBUG(4,("make_dom_sid2s: %s\n", sids_str ? sids_str:""));
571
572         if (sids_str == NULL || *sids_str == 0) return 0;
573
574         for (count = 0, ptr = sids_str; 
575              next_token(&ptr, s2, NULL, sizeof(s2)) && count < max_sids; 
576              count++) 
577         {
578                 DOM_SID tmpsid;
579                 string_to_sid(&tmpsid, s2);
580                 make_dom_sid2(&sids[count], &tmpsid);
581         }
582
583         return count;
584
585         return True;
586 }
587
588 /*******************************************************************
589 makes a NET_ID_INFO_1 structure.
590 ********************************************************************/
591 BOOL make_id_info1(NET_ID_INFO_1 *id, char *domain_name,
592                                 uint32 param_ctrl, uint32 log_id_low, uint32 log_id_high,
593                                 char *user_name, char *wksta_name,
594                                 char sess_key[16],
595                                 unsigned char lm_cypher[16], unsigned char nt_cypher[16])
596 {
597         int len_domain_name = strlen(domain_name);
598         int len_user_name   = strlen(user_name  );
599         int len_wksta_name  = strlen(wksta_name );
600
601         unsigned char lm_owf[16];
602         unsigned char nt_owf[16];
603
604         if (id == NULL) return False;
605
606         DEBUG(5,("make_id_info1: %d\n", __LINE__));
607
608         id->ptr_id_info1 = 1;
609
610         make_uni_hdr(&(id->hdr_domain_name), len_domain_name);
611
612         id->param_ctrl = param_ctrl;
613         id->logon_id.low = log_id_low;
614         id->logon_id.high = log_id_high;
615
616         make_uni_hdr(&(id->hdr_user_name  ), len_user_name  );
617         make_uni_hdr(&(id->hdr_wksta_name ), len_wksta_name );
618
619         if (lm_cypher && nt_cypher)
620         {
621                 unsigned char key[16];
622 #ifdef DEBUG_PASSWORD
623                 DEBUG(100,("lm cypher:"));
624                 dump_data(100, lm_cypher, 16);
625
626                 DEBUG(100,("nt cypher:"));
627                 dump_data(100, nt_cypher, 16);
628 #endif
629
630                 memset(key, 0, 16);
631                 memcpy(key, sess_key, 8);
632
633                 memcpy(lm_owf, lm_cypher, 16);
634                 SamOEMhash(lm_owf, key, False);
635                 memcpy(nt_owf, nt_cypher, 16);
636                 SamOEMhash(nt_owf, key, False);
637
638 #ifdef DEBUG_PASSWORD
639                 DEBUG(100,("encrypt of lm owf password:"));
640                 dump_data(100, lm_owf, 16);
641
642                 DEBUG(100,("encrypt of nt owf password:"));
643                 dump_data(100, nt_owf, 16);
644 #endif
645                 /* set up pointers to cypher blocks */
646                 lm_cypher = lm_owf;
647                 nt_cypher = nt_owf;
648         }
649
650         make_owf_info(&(id->lm_owf), lm_cypher);
651         make_owf_info(&(id->nt_owf), nt_cypher);
652
653         make_unistr2(&(id->uni_domain_name), domain_name, len_domain_name);
654         make_unistr2(&(id->uni_user_name  ), user_name  , len_user_name  );
655         make_unistr2(&(id->uni_wksta_name ), wksta_name , len_wksta_name );
656
657         return True;
658 }
659
660 /*******************************************************************
661 reads or writes an NET_ID_INFO_1 structure.
662 ********************************************************************/
663 static BOOL net_io_id_info1(char *desc,  NET_ID_INFO_1 *id, prs_struct *ps, int depth)
664 {
665         if (id == NULL) return False;
666
667         prs_debug(ps, depth, desc, "net_io_id_info1");
668         depth++;
669
670         prs_align(ps);
671         
672         prs_uint32("ptr_id_info1", ps, depth, &(id->ptr_id_info1));
673
674         if (id->ptr_id_info1 != 0)
675         {
676                 smb_io_unihdr("unihdr", &(id->hdr_domain_name), ps, depth);
677
678                 prs_uint32("param_ctrl", ps, depth, &(id->param_ctrl));
679                 smb_io_bigint("", &(id->logon_id), ps, depth);
680
681                 smb_io_unihdr("unihdr", &(id->hdr_user_name  ), ps, depth);
682                 smb_io_unihdr("unihdr", &(id->hdr_wksta_name ), ps, depth);
683
684                 smb_io_owf_info("", &(id->lm_owf), ps, depth);
685                 smb_io_owf_info("", &(id->nt_owf), ps, depth);
686
687                 smb_io_unistr2("unistr2", &(id->uni_domain_name), id->hdr_domain_name.buffer, ps, depth);
688                 smb_io_unistr2("unistr2", &(id->uni_user_name  ), id->hdr_user_name.buffer, ps, depth);
689                 smb_io_unistr2("unistr2", &(id->uni_wksta_name ), id->hdr_wksta_name.buffer, ps, depth);
690         }
691
692         return True;
693 }
694
695 /*******************************************************************
696 makes a NET_ID_INFO_2 structure.
697
698 This is a network logon packet. The log_id parameters
699 are what an NT server would generate for LUID once the
700 user is logged on. I don't think we care about them.
701
702 Note that this has no access to the NT and LM hashed passwords,
703 so it forwards the challenge, and the NT and LM responses (24
704 bytes each) over the secure channel to the Domain controller
705 for it to say yea or nay. This is the preferred method of 
706 checking for a logon as it doesn't export the password
707 hashes to anyone who has compromised the secure channel. JRA.
708 ********************************************************************/
709
710 BOOL make_id_info2(NET_ID_INFO_2 *id, char *domain_name,
711                                 uint32 param_ctrl, uint32 log_id_low, uint32 log_id_high,
712                                 char *user_name, char *wksta_name,
713                                 unsigned char lm_challenge[8],
714                                 unsigned char lm_chal_resp[24],
715                                 unsigned char nt_chal_resp[24])
716 {
717         int len_domain_name = strlen(domain_name);
718         int len_user_name   = strlen(user_name  );
719         int len_wksta_name  = strlen(wksta_name );
720         int nt_chal_resp_len = ((nt_chal_resp != NULL) ? 24 : 0);
721         int lm_chal_resp_len = ((lm_chal_resp != NULL) ? 24 : 0);
722         unsigned char lm_owf[24];
723         unsigned char nt_owf[24];
724
725         if (id == NULL) return False;
726
727         DEBUG(5,("make_id_info2: %d\n", __LINE__));
728
729         id->ptr_id_info2 = 1;
730
731         make_uni_hdr(&(id->hdr_domain_name), len_domain_name);
732
733         id->param_ctrl = param_ctrl;
734         id->logon_id.low = log_id_low;
735         id->logon_id.high = log_id_high;
736
737         make_uni_hdr(&(id->hdr_user_name  ), len_user_name  );
738         make_uni_hdr(&(id->hdr_wksta_name ), len_wksta_name );
739
740         if (nt_chal_resp)
741         {
742                 /* oops.  can only send what-ever-it-is direct */
743                 memcpy(nt_owf, nt_chal_resp, 24);
744                 nt_chal_resp = nt_owf;
745         }
746         if (lm_chal_resp)
747         {
748                 /* oops.  can only send what-ever-it-is direct */
749                 memcpy(lm_owf, lm_chal_resp, 24);
750                 lm_chal_resp = lm_owf;
751         }
752
753         memcpy(id->lm_chal, lm_challenge, sizeof(id->lm_chal));
754         make_str_hdr(&(id->hdr_nt_chal_resp), 24, nt_chal_resp_len, nt_chal_resp != NULL ? 1 : 0);
755         make_str_hdr(&(id->hdr_lm_chal_resp), 24, lm_chal_resp_len, lm_chal_resp != NULL ? 1 : 0);
756
757         make_unistr2(&(id->uni_domain_name), domain_name, len_domain_name);
758         make_unistr2(&(id->uni_user_name  ), user_name  , len_user_name  );
759         make_unistr2(&(id->uni_wksta_name ), wksta_name , len_wksta_name );
760
761         make_string2(&(id->nt_chal_resp ), (char *)nt_chal_resp , nt_chal_resp_len);
762         make_string2(&(id->lm_chal_resp ), (char *)lm_chal_resp , lm_chal_resp_len);
763
764         return True;
765 }
766
767 /*******************************************************************
768 reads or writes an NET_ID_INFO_2 structure.
769 ********************************************************************/
770 static BOOL net_io_id_info2(char *desc,  NET_ID_INFO_2 *id, prs_struct *ps, int depth)
771 {
772         if (id == NULL) return False;
773
774         prs_debug(ps, depth, desc, "net_io_id_info2");
775         depth++;
776
777         prs_align(ps);
778         
779         prs_uint32("ptr_id_info2", ps, depth, &(id->ptr_id_info2));
780
781         if (id->ptr_id_info2 != 0)
782         {
783                 smb_io_unihdr("unihdr", &(id->hdr_domain_name), ps, depth);
784
785                 prs_uint32("param_ctrl", ps, depth, &(id->param_ctrl));
786                 smb_io_bigint("", &(id->logon_id), ps, depth);
787
788                 smb_io_unihdr("unihdr", &(id->hdr_user_name  ), ps, depth);
789                 smb_io_unihdr("unihdr", &(id->hdr_wksta_name ), ps, depth);
790
791                 prs_uint8s (False, "lm_chal", ps, depth, id->lm_chal, 8); /* lm 8 byte challenge */
792
793                 smb_io_strhdr("hdr_nt_chal_resp", &(id->hdr_nt_chal_resp ), ps, depth);
794                 smb_io_strhdr("hdr_lm_chal_resp", &(id->hdr_lm_chal_resp ), ps, depth);
795
796                 smb_io_unistr2("uni_domain_name", &(id->uni_domain_name), id->hdr_domain_name .buffer, ps, depth);
797                 smb_io_unistr2("uni_user_name  ", &(id->uni_user_name  ), id->hdr_user_name   .buffer, ps, depth);
798                 smb_io_unistr2("uni_wksta_name ", &(id->uni_wksta_name ), id->hdr_wksta_name  .buffer, ps, depth);
799                 smb_io_string2("nt_chal_resp"   , &(id->nt_chal_resp)   , id->hdr_nt_chal_resp.buffer, ps, depth);
800                 smb_io_string2("lm_chal_resp"   , &(id->lm_chal_resp)   , id->hdr_lm_chal_resp.buffer, ps, depth);
801         }
802
803         return True;
804 }
805
806
807 /*******************************************************************
808 makes a DOM_SAM_INFO structure.
809 ********************************************************************/
810 BOOL make_sam_info(DOM_SAM_INFO *sam,
811                                 char *logon_srv, char *comp_name, DOM_CRED *clnt_cred,
812                                 DOM_CRED *rtn_cred, uint16 logon_level,
813                                 NET_ID_INFO_CTR *ctr, uint16 validation_level)
814 {
815         if (sam == NULL) return False;
816
817         DEBUG(5,("make_sam_info: %d\n", __LINE__));
818
819         make_clnt_info2(&(sam->client), logon_srv, comp_name, clnt_cred);
820
821         if (rtn_cred != NULL)
822         {
823                 sam->ptr_rtn_cred = 1;
824                 memcpy(&(sam->rtn_cred), rtn_cred, sizeof(sam->rtn_cred));
825         }
826         else
827         {
828                 sam->ptr_rtn_cred = 0;
829         }
830
831         sam->logon_level  = logon_level;
832         sam->ctr          = ctr;
833         sam->validation_level = validation_level;
834
835         return True;
836 }
837
838 /*******************************************************************
839 reads or writes a DOM_SAM_INFO structure.
840 ********************************************************************/
841 static BOOL net_io_id_info_ctr(char *desc,  NET_ID_INFO_CTR *ctr, prs_struct *ps, int depth)
842 {
843         if (ctr == NULL) return False;
844
845         prs_debug(ps, depth, desc, "smb_io_sam_info");
846         depth++;
847
848         /* don't 4-byte align here! */
849
850         prs_uint16("switch_value ", ps, depth, &(ctr->switch_value));
851
852         switch (ctr->switch_value)
853         {
854                 case 1:
855                 {
856                         net_io_id_info1("", &(ctr->auth.id1), ps, depth);
857                         break;
858                 }
859                 case 2:
860                 {
861                         net_io_id_info2("", &(ctr->auth.id2), ps, depth);
862                         break;
863                 }
864                 default:
865                 {
866                         /* PANIC! */
867                         DEBUG(4,("smb_io_sam_info: unknown switch_value!\n"));
868                         break;
869                 }
870         }
871
872         return True;
873 }
874
875 /*******************************************************************
876 reads or writes a DOM_SAM_INFO structure.
877 ********************************************************************/
878 static BOOL smb_io_sam_info(char *desc,  DOM_SAM_INFO *sam, prs_struct *ps, int depth)
879 {
880         if (sam == NULL) return False;
881
882         prs_debug(ps, depth, desc, "smb_io_sam_info");
883         depth++;
884
885         prs_align(ps);
886         
887         smb_io_clnt_info2("", &(sam->client  ), ps, depth);
888
889         prs_uint32("ptr_rtn_cred ", ps, depth, &(sam->ptr_rtn_cred));
890         smb_io_cred      ("", &(sam->rtn_cred), ps, depth);
891
892         prs_uint16("logon_level  ", ps, depth, &(sam->logon_level ));
893
894         if (sam->logon_level != 0 && sam->ctr != NULL)
895         {
896                 net_io_id_info_ctr("logon_info", sam->ctr, ps, depth);
897         }
898
899         prs_uint16("validation_level", ps, depth, &(sam->validation_level));
900
901         return True;
902 }
903
904 /*************************************************************************
905  make_net_user_info3
906  *************************************************************************/
907 BOOL make_net_user_info3(NET_USER_INFO_3 *usr,
908
909         NTTIME *logon_time,
910         NTTIME *logoff_time,
911         NTTIME *kickoff_time,
912         NTTIME *pass_last_set_time,
913         NTTIME *pass_can_change_time,
914         NTTIME *pass_must_change_time,
915
916         char *user_name,
917         char *full_name,
918         char *logon_script,
919         char *profile_path,
920         char *home_dir,
921         char *dir_drive,
922
923         uint16 logon_count,
924         uint16 bad_pw_count,
925
926         uint32 user_id,
927         uint32 group_id,
928         uint32 num_groups,
929         DOM_GID *gids,
930         uint32 user_flgs,
931
932         char sess_key[16],
933
934         char *logon_srv,
935         char *logon_dom,
936
937         DOM_SID *dom_sid,
938         char *other_sids)
939 {
940         /* only cope with one "other" sid, right now. */
941         /* need to count the number of space-delimited sids */
942         int i;
943         int num_other_sids = 0;
944
945         int len_user_name    = strlen(user_name   );
946         int len_full_name    = strlen(full_name   );
947         int len_logon_script = strlen(logon_script);
948         int len_profile_path = strlen(profile_path);
949         int len_home_dir     = strlen(home_dir    );
950         int len_dir_drive    = strlen(dir_drive   );
951
952         int len_logon_srv    = strlen(logon_srv);
953         int len_logon_dom    = strlen(logon_dom);
954
955         usr->ptr_user_info = 1; /* yes, we're bothering to put USER_INFO data here */
956
957         usr->logon_time            = *logon_time;
958         usr->logoff_time           = *logoff_time;
959         usr->kickoff_time          = *kickoff_time;
960         usr->pass_last_set_time    = *pass_last_set_time;
961         usr->pass_can_change_time  = *pass_can_change_time;
962         usr->pass_must_change_time = *pass_must_change_time;
963
964         make_uni_hdr(&(usr->hdr_user_name   ), len_user_name   );
965         make_uni_hdr(&(usr->hdr_full_name   ), len_full_name   );
966         make_uni_hdr(&(usr->hdr_logon_script), len_logon_script);
967         make_uni_hdr(&(usr->hdr_profile_path), len_profile_path);
968         make_uni_hdr(&(usr->hdr_home_dir    ), len_home_dir    );
969         make_uni_hdr(&(usr->hdr_dir_drive   ), len_dir_drive   );
970
971         usr->logon_count = logon_count;
972         usr->bad_pw_count = bad_pw_count;
973
974         usr->user_id = user_id;
975         usr->group_id = group_id;
976         usr->num_groups = num_groups;
977         usr->buffer_groups = 1; /* indicates fill in groups, below, even if there are none */
978         usr->user_flgs = user_flgs;
979
980         if (sess_key != NULL)
981         {
982                 memcpy(usr->user_sess_key, sess_key, sizeof(usr->user_sess_key));
983         }
984         else
985         {
986                 bzero(usr->user_sess_key, sizeof(usr->user_sess_key));
987         }
988
989         make_uni_hdr(&(usr->hdr_logon_srv), len_logon_srv);
990         make_uni_hdr(&(usr->hdr_logon_dom), len_logon_dom);
991
992         usr->buffer_dom_id = dom_sid ? 1 : 0; /* yes, we're bothering to put a domain SID in */
993
994         bzero(usr->padding, sizeof(usr->padding));
995
996         num_other_sids = make_dom_sid2s(other_sids, usr->other_sids, LSA_MAX_SIDS);
997
998         usr->num_other_sids = num_other_sids;
999         usr->buffer_other_sids = num_other_sids != 0 ? 1 : 0; 
1000         
1001         make_unistr2(&(usr->uni_user_name   ), user_name   , len_user_name   );
1002         make_unistr2(&(usr->uni_full_name   ), full_name   , len_full_name   );
1003         make_unistr2(&(usr->uni_logon_script), logon_script, len_logon_script);
1004         make_unistr2(&(usr->uni_profile_path), profile_path, len_profile_path);
1005         make_unistr2(&(usr->uni_home_dir    ), home_dir    , len_home_dir    );
1006         make_unistr2(&(usr->uni_dir_drive   ), dir_drive   , len_dir_drive   );
1007
1008         usr->num_groups2 = num_groups;
1009
1010         SMB_ASSERT_ARRAY(usr->gids, num_groups);
1011
1012         for (i = 0; i < num_groups; i++)
1013         {
1014                 usr->gids[i] = gids[i];
1015         }
1016
1017         make_unistr2(&(usr->uni_logon_srv), logon_srv, len_logon_srv);
1018         make_unistr2(&(usr->uni_logon_dom), logon_dom, len_logon_dom);
1019
1020         make_dom_sid2(&(usr->dom_sid), dom_sid);
1021         /* "other" sids are set up above */
1022
1023         return True;
1024 }
1025
1026
1027 /*******************************************************************
1028 reads or writes a structure.
1029 ********************************************************************/
1030 static BOOL net_io_user_info3(char *desc,  NET_USER_INFO_3 *usr, prs_struct *ps, int depth)
1031 {
1032         int i;
1033
1034         if (usr == NULL) return False;
1035
1036         prs_debug(ps, depth, desc, "lsa_io_lsa_user_info");
1037         depth++;
1038
1039         prs_align(ps);
1040         
1041         prs_uint32("ptr_user_info ", ps, depth, &(usr->ptr_user_info));
1042
1043         if (usr->ptr_user_info != 0)
1044         {
1045                 smb_io_time("time", &(usr->logon_time)           , ps, depth); /* logon time */
1046                 smb_io_time("time", &(usr->logoff_time)          , ps, depth); /* logoff time */
1047                 smb_io_time("time", &(usr->kickoff_time)         , ps, depth); /* kickoff time */
1048                 smb_io_time("time", &(usr->pass_last_set_time)   , ps, depth); /* password last set time */
1049                 smb_io_time("time", &(usr->pass_can_change_time) , ps, depth); /* password can change time */
1050                 smb_io_time("time", &(usr->pass_must_change_time), ps, depth); /* password must change time */
1051
1052                 smb_io_unihdr("unihdr", &(usr->hdr_user_name)   , ps, depth); /* username unicode string header */
1053                 smb_io_unihdr("unihdr", &(usr->hdr_full_name)   , ps, depth); /* user's full name unicode string header */
1054                 smb_io_unihdr("unihdr", &(usr->hdr_logon_script), ps, depth); /* logon script unicode string header */
1055                 smb_io_unihdr("unihdr", &(usr->hdr_profile_path), ps, depth); /* profile path unicode string header */
1056                 smb_io_unihdr("unihdr", &(usr->hdr_home_dir)    , ps, depth); /* home directory unicode string header */
1057                 smb_io_unihdr("unihdr", &(usr->hdr_dir_drive)   , ps, depth); /* home directory drive unicode string header */
1058
1059                 prs_uint16("logon_count   ", ps, depth, &(usr->logon_count ));  /* logon count */
1060                 prs_uint16("bad_pw_count  ", ps, depth, &(usr->bad_pw_count)); /* bad password count */
1061
1062                 prs_uint32("user_id       ", ps, depth, &(usr->user_id      ));       /* User ID */
1063                 prs_uint32("group_id      ", ps, depth, &(usr->group_id     ));      /* Group ID */
1064                 prs_uint32("num_groups    ", ps, depth, &(usr->num_groups   ));    /* num groups */
1065                 prs_uint32("buffer_groups ", ps, depth, &(usr->buffer_groups)); /* undocumented buffer pointer to groups. */
1066                 prs_uint32("user_flgs     ", ps, depth, &(usr->user_flgs    ));     /* user flags */
1067
1068                 prs_uint8s (False, "user_sess_key", ps, depth, usr->user_sess_key, 16); /* unused user session key */
1069
1070                 smb_io_unihdr("unihdr", &(usr->hdr_logon_srv), ps, depth); /* logon server unicode string header */
1071                 smb_io_unihdr("unihdr", &(usr->hdr_logon_dom), ps, depth); /* logon domain unicode string header */
1072
1073                 prs_uint32("buffer_dom_id ", ps, depth, &(usr->buffer_dom_id)); /* undocumented logon domain id pointer */
1074                 prs_uint8s (False, "padding       ", ps, depth, usr->padding, 40); /* unused padding bytes? */
1075
1076                 prs_uint32("num_other_sids", ps, depth, &(usr->num_other_sids)); /* 0 - num_sids */
1077                 prs_uint32("buffer_other_sids", ps, depth, &(usr->buffer_other_sids)); /* NULL - undocumented pointer to SIDs. */
1078                 
1079                 smb_io_unistr2("unistr2", &(usr->uni_user_name)   , usr->hdr_user_name   .buffer, ps, depth); /* username unicode string */
1080                 smb_io_unistr2("unistr2", &(usr->uni_full_name)   , usr->hdr_full_name   .buffer, ps, depth); /* user's full name unicode string */
1081                 smb_io_unistr2("unistr2", &(usr->uni_logon_script), usr->hdr_logon_script.buffer, ps, depth); /* logon script unicode string */
1082                 smb_io_unistr2("unistr2", &(usr->uni_profile_path), usr->hdr_profile_path.buffer, ps, depth); /* profile path unicode string */
1083                 smb_io_unistr2("unistr2", &(usr->uni_home_dir)    , usr->hdr_home_dir    .buffer, ps, depth); /* home directory unicode string */
1084                 smb_io_unistr2("unistr2", &(usr->uni_dir_drive)   , usr->hdr_dir_drive   .buffer, ps, depth); /* home directory drive unicode string */
1085
1086                 prs_align(ps);
1087                 prs_uint32("num_groups2   ", ps, depth, &(usr->num_groups2));        /* num groups */
1088                 SMB_ASSERT_ARRAY(usr->gids, usr->num_groups2);
1089                 for (i = 0; i < usr->num_groups2; i++)
1090                 {
1091                         smb_io_gid("", &(usr->gids[i]), ps, depth); /* group info */
1092                 }
1093
1094                 smb_io_unistr2("unistr2", &( usr->uni_logon_srv), usr->hdr_logon_srv.buffer, ps, depth); /* logon server unicode string */
1095                 smb_io_unistr2("unistr2", &( usr->uni_logon_dom), usr->hdr_logon_srv.buffer, ps, depth); /* logon domain unicode string */
1096
1097                 smb_io_dom_sid2("", &(usr->dom_sid), ps, depth);           /* domain SID */
1098
1099                 SMB_ASSERT_ARRAY(usr->other_sids, usr->num_other_sids);
1100
1101                 for (i = 0; i < usr->num_other_sids; i++)
1102                 {
1103                         smb_io_dom_sid2("", &(usr->other_sids[i]), ps, depth); /* other domain SIDs */
1104                 }
1105         }
1106
1107         return True;
1108 }
1109
1110 /*******************************************************************
1111 reads or writes a structure.
1112 ********************************************************************/
1113 BOOL net_io_q_sam_logon(char *desc,  NET_Q_SAM_LOGON *q_l, prs_struct *ps, int depth)
1114 {
1115         if (q_l == NULL) return False;
1116
1117         prs_debug(ps, depth, desc, "net_io_q_sam_logon");
1118         depth++;
1119
1120         prs_align(ps);
1121         
1122         smb_io_sam_info("", &(q_l->sam_id), ps, depth);           /* domain SID */
1123
1124         return True;
1125 }
1126
1127 /*******************************************************************
1128 reads or writes a structure.
1129 ********************************************************************/
1130 BOOL net_io_r_sam_logon(char *desc,  NET_R_SAM_LOGON *r_l, prs_struct *ps, int depth)
1131 {
1132         if (r_l == NULL) return False;
1133
1134         prs_debug(ps, depth, desc, "net_io_r_sam_logon");
1135         depth++;
1136
1137         prs_uint32("buffer_creds", ps, depth, &(r_l->buffer_creds)); /* undocumented buffer pointer */
1138         smb_io_cred("", &(r_l->srv_creds), ps, depth); /* server credentials.  server time stamp appears to be ignored. */
1139
1140         prs_uint16("switch_value", ps, depth, &(r_l->switch_value));
1141         prs_align(ps);
1142
1143         if (r_l->switch_value != 0)
1144         {
1145                 net_io_user_info3("", r_l->user, ps, depth);
1146         }
1147
1148         prs_uint32("auth_resp   ", ps, depth, &(r_l->auth_resp)); /* 1 - Authoritative response; 0 - Non-Auth? */
1149
1150         prs_uint32("status      ", ps, depth, &(r_l->status));
1151
1152         prs_align(ps);
1153
1154         return True;
1155 }
1156
1157 /*******************************************************************
1158 reads or writes a structure.
1159 ********************************************************************/
1160 BOOL net_io_q_sam_logoff(char *desc,  NET_Q_SAM_LOGOFF *q_l, prs_struct *ps, int depth)
1161 {
1162         if (q_l == NULL) return False;
1163
1164         prs_debug(ps, depth, desc, "net_io_q_sam_logoff");
1165         depth++;
1166
1167         prs_align(ps);
1168         
1169         smb_io_sam_info("", &(q_l->sam_id), ps, depth);           /* domain SID */
1170
1171         return True;
1172 }
1173
1174 /*******************************************************************
1175 reads or writes a structure.
1176 ********************************************************************/
1177 BOOL net_io_r_sam_logoff(char *desc,  NET_R_SAM_LOGOFF *r_l, prs_struct *ps, int depth)
1178 {
1179         if (r_l == NULL) return False;
1180
1181         prs_debug(ps, depth, desc, "net_io_r_sam_logoff");
1182         depth++;
1183
1184         prs_align(ps);
1185         
1186         prs_uint32("buffer_creds", ps, depth, &(r_l->buffer_creds)); /* undocumented buffer pointer */
1187         smb_io_cred("", &(r_l->srv_creds), ps, depth); /* server credentials.  server time stamp appears to be ignored. */
1188
1189         prs_uint32("status      ", ps, depth, &(r_l->status));
1190
1191         return True;
1192 }
1193
1194 /*******************************************************************
1195 makes a NET_Q_SAM_SYNC structure.
1196 ********************************************************************/
1197 BOOL make_q_sam_sync(NET_Q_SAM_SYNC *q_s, char *srv_name, char *cli_name,
1198                      DOM_CRED *cli_creds, uint32 database_id)
1199 {
1200         if (q_s == NULL) return False;
1201
1202         DEBUG(5,("make_q_sam_sync\n"));
1203
1204         make_unistr2(&(q_s->uni_srv_name), srv_name, strlen(srv_name)+1);
1205         make_unistr2(&(q_s->uni_cli_name), cli_name, strlen(cli_name)+1);
1206
1207         memcpy(&(q_s->cli_creds), cli_creds, sizeof(q_s->cli_creds));
1208         memset(&(q_s->ret_creds), 0, sizeof(q_s->ret_creds));
1209
1210         q_s->database_id = database_id;
1211         q_s->restart_state = 0;
1212         q_s->sync_context = 0;
1213         q_s->max_size = 0xffff;
1214
1215         return True;
1216 }
1217
1218 /*******************************************************************
1219 reads or writes a structure.
1220 ********************************************************************/
1221 BOOL net_io_q_sam_sync(char *desc, NET_Q_SAM_SYNC *q_s, prs_struct *ps, int depth)
1222 {
1223         if (q_s == NULL) return False;
1224
1225         prs_debug(ps, depth, desc, "net_io_q_sam_sync");
1226         depth++;
1227
1228         smb_io_unistr2("", &(q_s->uni_srv_name), True, ps, depth);
1229         smb_io_unistr2("", &(q_s->uni_cli_name), True, ps, depth);
1230
1231         smb_io_cred("", &(q_s->cli_creds), ps, depth);
1232         smb_io_cred("", &(q_s->ret_creds), ps, depth);
1233
1234         prs_uint32("database_id  ", ps, depth, &(q_s->database_id  ));
1235         prs_uint32("restart_state", ps, depth, &(q_s->restart_state));
1236         prs_uint32("sync_context ", ps, depth, &(q_s->sync_context ));
1237
1238         prs_uint32("max_size", ps, depth, &(q_s->max_size));
1239
1240         return True;
1241 }
1242
1243 /*******************************************************************
1244 makes a SAM_DELTA_HDR structure.
1245 ********************************************************************/
1246 BOOL make_sam_delta_hdr(SAM_DELTA_HDR *delta, uint16 type, uint32 rid)
1247 {
1248         if (delta == NULL) return False;
1249
1250         DEBUG(5,("make_sam_delta_hdr\n"));
1251
1252         delta->type2 = delta->type = type;
1253         delta->target_rid = rid;
1254
1255         delta->type3 = type;
1256         delta->ptr_delta = 1;
1257
1258         return True;
1259 }
1260
1261 /*******************************************************************
1262 reads or writes a structure.
1263 ********************************************************************/
1264 static BOOL net_io_sam_delta_hdr(char *desc, SAM_DELTA_HDR *delta, prs_struct *ps, int depth)
1265 {
1266         if (delta == NULL) return False;
1267
1268         prs_debug(ps, depth, desc, "net_io_sam_delta_hdr");
1269         depth++;
1270
1271         prs_uint16("type",       ps, depth, &(delta->type      ));
1272         prs_uint16("type2",      ps, depth, &(delta->type2     ));
1273         prs_uint32("target_rid", ps, depth, &(delta->target_rid));
1274
1275         prs_uint32("type3",      ps, depth, &(delta->type3     ));
1276         prs_uint32("ptr_delta",  ps, depth, &(delta->ptr_delta ));
1277
1278         return True;
1279 }
1280
1281 /*******************************************************************
1282 reads or writes a structure.
1283 ********************************************************************/
1284 static BOOL net_io_sam_domain_info(char *desc, SAM_DOMAIN_INFO *info, prs_struct *ps, int depth)
1285 {
1286         if (info == NULL) return False;
1287
1288         prs_debug(ps, depth, desc, "net_io_sam_domain_info");
1289         depth++;
1290
1291         smb_io_unihdr("hdr_dom_name" , &(info->hdr_dom_name) , ps, depth);
1292         smb_io_unihdr("hdr_oem_info" , &(info->hdr_oem_info) , ps, depth);
1293
1294         smb_io_bigint("force_logoff" , &(info->force_logoff) , ps, depth);
1295         prs_uint16("min_pwd_len"     , ps, depth, &(info->min_pwd_len    ));
1296         prs_uint16("pwd_history_len" , ps, depth, &(info->pwd_history_len));
1297         smb_io_bigint("max_pwd_age"  , &(info->max_pwd_age)  , ps, depth);
1298         smb_io_bigint("min_pwd_age"  , &(info->min_pwd_age)  , ps, depth);
1299         smb_io_bigint("dom_mod_count", &(info->dom_mod_count), ps, depth);
1300         smb_io_time("creation_time"  , &(info->creation_time), ps, depth);
1301
1302         smb_io_bufhdr2("hdr_sec_desc", &(info->hdr_sec_desc) , ps, depth);
1303         smb_io_unihdr ("hdr_unknown" , &(info->hdr_unknown)  , ps, depth);
1304         ps->offset += 40;
1305
1306         smb_io_unistr2("uni_dom_name", &(info->uni_dom_name),
1307                        info->hdr_dom_name.buffer, ps, depth);
1308         smb_io_unistr2("buf_oem_info", &(info->buf_oem_info),
1309                        info->hdr_oem_info.buffer, ps, depth);
1310
1311         smb_io_buffer4("buf_sec_desc", &(info->buf_sec_desc),
1312                        info->hdr_sec_desc.buffer, ps, depth);
1313         smb_io_unistr2("buf_unknown" , &(info->buf_unknown ),
1314                        info->hdr_unknown .buffer, ps, depth);
1315
1316         return True;
1317 }
1318
1319 /*******************************************************************
1320 reads or writes a structure.
1321 ********************************************************************/
1322 static BOOL net_io_sam_group_info(char *desc, SAM_GROUP_INFO *info, prs_struct *ps, int depth)
1323 {
1324         if (info == NULL) return False;
1325
1326         prs_debug(ps, depth, desc, "net_io_sam_group_info");
1327         depth++;
1328
1329         smb_io_unihdr ("hdr_grp_name", &(info->hdr_grp_name), ps, depth);
1330         smb_io_gid    ("gid",          &(info->gid),          ps, depth);
1331         smb_io_unihdr ("hdr_grp_desc", &(info->hdr_grp_desc), ps, depth);
1332         smb_io_bufhdr2("hdr_sec_desc", &(info->hdr_sec_desc), ps, depth);
1333         ps->offset += 48;
1334
1335         smb_io_unistr2("uni_grp_name", &(info->uni_grp_name),
1336                        info->hdr_grp_name.buffer, ps, depth);
1337         smb_io_unistr2("uni_grp_desc", &(info->uni_grp_desc),
1338                        info->hdr_grp_desc.buffer, ps, depth);
1339         smb_io_buffer4("buf_sec_desc", &(info->buf_sec_desc),
1340                        info->hdr_sec_desc.buffer, ps, depth);
1341
1342         return True;
1343 }
1344
1345 /*******************************************************************
1346 makes a SAM_ACCOUNT_INFO structure.
1347 ********************************************************************/
1348 BOOL make_sam_account_info(SAM_ACCOUNT_INFO *info, char *user_name,
1349                            char *full_name, uint32 user_rid, uint32 group_rid,
1350                            char *home_dir, char *dir_drive, char *logon_script,
1351                            char *acct_desc, uint32 acb_info, char *profile)
1352 {
1353         int len_user_name = strlen(user_name);
1354         int len_full_name = strlen(full_name);
1355         int len_home_dir = strlen(home_dir);
1356         int len_dir_drive = strlen(dir_drive);
1357         int len_logon_script = strlen(logon_script);
1358         int len_acct_desc = strlen(acct_desc);
1359         int len_profile = strlen(profile);
1360
1361         DEBUG(5,("make_sam_account_info\n"));
1362
1363         make_uni_hdr(&(info->hdr_acct_name   ), len_user_name   );
1364         make_uni_hdr(&(info->hdr_full_name   ), len_full_name   );
1365         make_uni_hdr(&(info->hdr_home_dir    ), len_home_dir    );
1366         make_uni_hdr(&(info->hdr_dir_drive   ), len_dir_drive   );
1367         make_uni_hdr(&(info->hdr_logon_script), len_logon_script);
1368         make_uni_hdr(&(info->hdr_acct_desc   ), len_acct_desc   );
1369         make_uni_hdr(&(info->hdr_profile     ), len_profile     );
1370
1371         /* not present */
1372         make_uni_hdr(&(info->hdr_workstations), 0);
1373         make_uni_hdr(&(info->hdr_comment), 0);
1374         make_uni_hdr(&(info->hdr_parameters), 0);
1375         make_bufhdr2(&(info->hdr_sec_desc), 0, 0, 0);
1376
1377         info->user_rid = user_rid;
1378         info->group_rid = group_rid;
1379
1380         init_nt_time(&(info->logon_time));
1381         init_nt_time(&(info->logoff_time));
1382         init_nt_time(&(info->pwd_last_set_time));
1383         init_nt_time(&(info->acct_expiry_time));
1384
1385         info->logon_divs = 0xA8;
1386         info->ptr_logon_hrs = 0; /* Don't care right now */
1387
1388         info->bad_pwd_count = 0;
1389         info->logon_count = 0;
1390         info->acb_info = acb_info;
1391         info->nt_pwd_present = 0;
1392         info->lm_pwd_present = 0;
1393         info->pwd_expired = 0;
1394         info->country = 0;
1395         info->codepage = 0;
1396
1397         info->unknown1 = 0x4EC;
1398         info->unknown2 = 0;
1399
1400         make_unistr2(&(info->uni_acct_name), user_name, len_user_name+1);
1401         make_unistr2(&(info->uni_full_name), full_name, len_full_name+1);
1402         make_unistr2(&(info->uni_home_dir ), home_dir , len_home_dir +1);
1403         make_unistr2(&(info->uni_dir_drive), dir_drive, len_dir_drive+1);
1404         make_unistr2(&(info->uni_logon_script), logon_script, len_logon_script+1);
1405         make_unistr2(&(info->uni_acct_desc), acct_desc, len_acct_desc+1);
1406         make_unistr2(&(info->uni_profile  ), profile  , len_profile  +1);
1407
1408         return True;
1409 }
1410
1411 /*******************************************************************
1412 reads or writes a structure.
1413 ********************************************************************/
1414 static BOOL net_io_sam_passwd_info(char *desc, SAM_PWD *pwd,
1415                                 prs_struct *ps, int depth)
1416 {
1417         if (pwd == NULL) return False;
1418
1419         prs_debug(ps, depth, desc, "net_io_sam_passwd_info");
1420         depth++;
1421
1422         prs_uint32("unk_0 ", ps, depth, &(pwd->unk_0 ));
1423
1424         smb_io_unihdr ("hdr_lm_pwd", &(pwd->hdr_lm_pwd), ps, depth);
1425         prs_uint8s(False, "buf_lm_pwd", ps, depth, pwd->buf_lm_pwd, 16);
1426         
1427         smb_io_unihdr ("hdr_nt_pwd", &(pwd->hdr_nt_pwd), ps, depth);
1428         prs_uint8s(False, "buf_nt_pwd", ps, depth, pwd->buf_nt_pwd, 16);
1429
1430         smb_io_unihdr("", &(pwd->hdr_empty_lm), ps, depth);
1431         smb_io_unihdr("", &(pwd->hdr_empty_nt), ps, depth);
1432
1433         return True;
1434 }
1435
1436 /*******************************************************************
1437 reads or writes a structure.
1438 ********************************************************************/
1439 static BOOL net_io_sam_account_info(char *desc, uint8 sess_key[16],
1440                         SAM_ACCOUNT_INFO *info, prs_struct *ps, int depth)
1441 {
1442         BUFHDR2 hdr_priv_data;
1443         int i;
1444
1445         if (info == NULL) return False;
1446
1447         prs_debug(ps, depth, desc, "net_io_sam_account_info");
1448         depth++;
1449
1450         smb_io_unihdr("hdr_acct_name", &(info->hdr_acct_name), ps, depth);
1451         smb_io_unihdr("hdr_full_name", &(info->hdr_full_name), ps, depth);
1452
1453         prs_uint32("user_rid ", ps, depth, &(info->user_rid ));
1454         prs_uint32("group_rid", ps, depth, &(info->group_rid));
1455
1456         smb_io_unihdr("hdr_home_dir "   , &(info->hdr_home_dir ), ps, depth);
1457         smb_io_unihdr("hdr_dir_drive"   , &(info->hdr_dir_drive), ps, depth);
1458         smb_io_unihdr("hdr_logon_script", &(info->hdr_logon_script), ps, depth);
1459         smb_io_unihdr("hdr_acct_desc"   , &(info->hdr_acct_desc), ps, depth);
1460         smb_io_unihdr("hdr_workstations", &(info->hdr_workstations), ps, depth);
1461
1462         smb_io_time("logon_time" , &(info->logon_time ), ps, depth);
1463         smb_io_time("logoff_time", &(info->logoff_time), ps, depth);
1464
1465         prs_uint32("logon_divs   ", ps, depth, &(info->logon_divs   ));
1466         prs_uint32("ptr_logon_hrs", ps, depth, &(info->ptr_logon_hrs));
1467
1468         prs_uint16("bad_pwd_count", ps, depth, &(info->bad_pwd_count));
1469         prs_uint16("logon_count"  , ps, depth, &(info->logon_count  ));
1470         smb_io_time("pwd_last_set_time", &(info->pwd_last_set_time), ps, depth);
1471         smb_io_time("acct_expiry_time" , &(info->acct_expiry_time ), ps, depth);
1472
1473         prs_uint32("acb_info", ps, depth, &(info->acb_info));
1474         prs_uint8s(False, "nt_pwd", ps, depth, info->nt_pwd, 16);
1475         prs_uint8s(False, "lm_pwd", ps, depth, info->lm_pwd, 16);
1476         prs_uint8("lm_pwd_present", ps, depth, &(info->lm_pwd_present));
1477         prs_uint8("nt_pwd_present", ps, depth, &(info->nt_pwd_present));
1478         prs_uint8("pwd_expired"   , ps, depth, &(info->pwd_expired   ));
1479
1480         smb_io_unihdr("hdr_comment"   , &(info->hdr_comment   ), ps, depth);
1481         smb_io_unihdr("hdr_parameters", &(info->hdr_parameters), ps, depth);
1482         prs_uint16("country" , ps, depth, &(info->country ));
1483         prs_uint16("codepage", ps, depth, &(info->codepage));
1484
1485         smb_io_bufhdr2("hdr_priv_data", &(hdr_priv_data), ps, depth);
1486         smb_io_bufhdr2("hdr_sec_desc" , &(info->hdr_sec_desc) , ps, depth);
1487         smb_io_unihdr ("hdr_profile"  , &(info->hdr_profile)  , ps, depth);
1488
1489         for (i = 0; i < 3; i++)
1490         {
1491                 smb_io_unihdr("hdr_reserved", &(info->hdr_reserved[i]), ps, depth);
1492         }
1493
1494         for (i = 0; i < 4; i++)
1495         {
1496                 prs_uint32("dw_reserved", ps, depth, &(info->dw_reserved[i]));
1497         }
1498
1499         smb_io_unistr2("uni_acct_name", &(info->uni_acct_name),
1500                        info->hdr_acct_name.buffer, ps, depth);
1501         prs_align(ps);
1502         smb_io_unistr2("uni_full_name", &(info->uni_full_name),
1503                        info->hdr_full_name.buffer, ps, depth);
1504         prs_align(ps);
1505         smb_io_unistr2("uni_home_dir ", &(info->uni_home_dir ),
1506                        info->hdr_home_dir .buffer, ps, depth);
1507         prs_align(ps);
1508         smb_io_unistr2("uni_dir_drive", &(info->uni_dir_drive),
1509                        info->hdr_dir_drive.buffer, ps, depth);
1510         prs_align(ps);
1511         smb_io_unistr2("uni_logon_script", &(info->uni_logon_script),
1512                        info->hdr_logon_script.buffer, ps, depth);
1513         prs_align(ps);
1514         smb_io_unistr2("uni_acct_desc", &(info->uni_acct_desc),
1515                        info->hdr_acct_desc.buffer, ps, depth);
1516         prs_align(ps);
1517         smb_io_unistr2("uni_workstations", &(info->uni_workstations),
1518                        info->hdr_workstations.buffer, ps, depth);
1519         prs_align(ps);
1520
1521         prs_uint32("unknown1", ps, depth, &(info->unknown1));
1522         prs_uint32("unknown2", ps, depth, &(info->unknown2));
1523
1524         smb_io_buffer4("buf_logon_hrs" , &(info->buf_logon_hrs ),
1525                        info->ptr_logon_hrs, ps, depth);
1526         prs_align(ps);
1527         smb_io_unistr2("uni_comment"   , &(info->uni_comment   ),
1528                        info->hdr_comment.buffer, ps, depth);
1529         prs_align(ps);
1530         smb_io_unistr2("uni_parameters", &(info->uni_parameters),
1531                        info->hdr_parameters.buffer, ps, depth);
1532         prs_align(ps);
1533         if (hdr_priv_data.buffer != 0)
1534         {
1535                 int old_offset;
1536                 uint32 len = 0x44;
1537                 prs_uint32("pwd_len", ps, depth, &len);
1538                 old_offset = ps->offset;
1539                 if (len == 0x44)
1540                 {
1541                         if (ps->io)
1542                         {
1543                                 /* reading */
1544                                 prs_hash1(ps, ps->offset, sess_key);
1545                         }
1546                         net_io_sam_passwd_info("pass", &(info->pass), ps, depth);
1547                         if (!ps->io)
1548                         {
1549                                 /* writing */
1550                                 prs_hash1(ps, old_offset, sess_key);
1551                         }
1552                 }
1553                 ps->offset = old_offset + len;
1554         }
1555         smb_io_buffer4("buf_sec_desc"  , &(info->buf_sec_desc  ),
1556                        info->hdr_sec_desc.buffer, ps, depth);
1557         prs_align(ps);
1558         smb_io_unistr2("uni_profile"   , &(info->uni_profile   ),
1559                        info->hdr_profile.buffer, ps, depth);
1560         prs_align(ps);
1561
1562         return True;
1563 }
1564
1565 /*******************************************************************
1566 reads or writes a structure.
1567 ********************************************************************/
1568 static BOOL net_io_sam_group_mem_info(char *desc, SAM_GROUP_MEM_INFO *info, prs_struct *ps, int depth)
1569 {
1570         int i;
1571         fstring tmp;
1572
1573         if (info == NULL) return False;
1574
1575         prs_debug(ps, depth, desc, "net_io_sam_group_mem_info");
1576         depth++;
1577
1578         prs_align(ps);
1579         prs_uint32("ptr_rids   ", ps, depth, &(info->ptr_rids   ));
1580         prs_uint32("ptr_attribs", ps, depth, &(info->ptr_attribs));
1581         prs_uint32("num_members", ps, depth, &(info->num_members));
1582         ps->offset += 16;
1583
1584         if (info->ptr_rids != 0)
1585         {
1586                 prs_uint32("num_members2", ps, depth, &(info->num_members2));
1587                 if (info->num_members2 != info->num_members)
1588                 {
1589                         /* RPC fault */
1590                         return False;
1591                 }
1592
1593                 SMB_ASSERT_ARRAY(info->rids, info->num_members2);
1594
1595                 for (i = 0; i < info->num_members2; i++)
1596                 {
1597                         prs_grow(ps);
1598                         slprintf(tmp, sizeof(tmp) - 1, "rids[%02d]", i);
1599                         prs_uint32(tmp, ps, depth, &(info->rids[i]));
1600                 }
1601         }
1602
1603         if (info->ptr_attribs != 0)
1604         {
1605                 prs_uint32("num_members3", ps, depth, &(info->num_members3));
1606                 if (info->num_members3 != info->num_members)
1607                 {
1608                         /* RPC fault */
1609                         return False;
1610                 }
1611
1612                 SMB_ASSERT_ARRAY(info->attribs, info->num_members3);
1613
1614                 for (i = 0; i < info->num_members3; i++)
1615                 {
1616                         prs_grow(ps);
1617                         slprintf(tmp, sizeof(tmp) - 1, "attribs[%02d]", i);
1618                         prs_uint32(tmp, ps, depth, &(info->attribs[i]));
1619                 }
1620         }
1621
1622         return True;
1623 }
1624
1625 /*******************************************************************
1626 reads or writes a structure.
1627 ********************************************************************/
1628 static BOOL net_io_sam_alias_info(char *desc, SAM_ALIAS_INFO *info, prs_struct *ps, int depth)
1629 {
1630         if (info == NULL) return False;
1631
1632         prs_debug(ps, depth, desc, "net_io_sam_alias_info");
1633         depth++;
1634
1635         smb_io_unihdr ("hdr_als_name", &(info->hdr_als_name), ps, depth);
1636         prs_uint32("als_rid", ps, depth, &(info->als_rid));
1637         smb_io_bufhdr2("hdr_sec_desc", &(info->hdr_sec_desc), ps, depth);
1638         smb_io_unihdr ("hdr_als_desc", &(info->hdr_als_desc), ps, depth);
1639         ps->offset += 40;
1640
1641         smb_io_unistr2("uni_als_name", &(info->uni_als_name),
1642                        info->hdr_als_name.buffer, ps, depth);
1643         smb_io_buffer4("buf_sec_desc", &(info->buf_sec_desc),
1644                        info->hdr_sec_desc.buffer, ps, depth);
1645         smb_io_unistr2("uni_als_desc", &(info->uni_als_desc),
1646                        info->hdr_als_name.buffer, ps, depth);
1647
1648         return True;
1649 }
1650
1651 /*******************************************************************
1652 reads or writes a structure.
1653 ********************************************************************/
1654 static BOOL net_io_sam_alias_mem_info(char *desc, SAM_ALIAS_MEM_INFO *info, prs_struct *ps, int depth)
1655 {
1656         int i;
1657         fstring tmp;
1658
1659         if (info == NULL) return False;
1660
1661         prs_debug(ps, depth, desc, "net_io_sam_alias_mem_info");
1662         depth++;
1663
1664         prs_align(ps);
1665         prs_uint32("num_members", ps, depth, &(info->num_members));
1666         prs_uint32("ptr_members", ps, depth, &(info->ptr_members));
1667         ps->offset += 16;
1668
1669         if (info->ptr_members != 0)
1670         {
1671                 prs_uint32("num_sids", ps, depth, &(info->num_sids));
1672                 if (info->num_sids != info->num_members)
1673                 {
1674                         /* RPC fault */
1675                         return False;
1676                 }
1677
1678                 SMB_ASSERT_ARRAY(info->ptr_sids, info->num_sids);
1679
1680                 for (i = 0; i < info->num_sids; i++)
1681                 {
1682                         prs_grow(ps);
1683                         slprintf(tmp, sizeof(tmp) - 1, "ptr_sids[%02d]", i);
1684                         prs_uint32(tmp, ps, depth, &(info->ptr_sids[i]));
1685                 }
1686
1687                 SMB_ASSERT_ARRAY(info->sids, info->num_sids);
1688
1689                 for (i = 0; i < info->num_sids; i++)
1690                 {
1691                         if (info->ptr_sids[i] != 0)
1692                         {
1693                                 prs_grow(ps);
1694                                 slprintf(tmp, sizeof(tmp) - 1, "sids[%02d]", i);
1695                                 smb_io_dom_sid2(tmp, &(info->sids[i]), ps, depth);
1696                         }
1697                 }
1698         }
1699
1700         return True;
1701 }
1702
1703 /*******************************************************************
1704 reads or writes a structure.
1705 ********************************************************************/
1706 static BOOL net_io_sam_delta_ctr(char *desc, uint8 sess_key[16],
1707                                 SAM_DELTA_CTR *delta, uint16 type,
1708                                 prs_struct *ps, int depth)
1709 {
1710         if (delta == NULL) return False;
1711
1712         prs_debug(ps, depth, desc, "net_io_sam_delta_ctr");
1713         depth++;
1714
1715         switch (type)
1716         {
1717                 case 1:
1718                 {
1719                         net_io_sam_domain_info("", &(delta->domain_info),
1720                                                    ps, depth);
1721                         break;
1722                 }
1723                 case 2:
1724                 {
1725                         net_io_sam_group_info("", &(delta->group_info), 
1726                                                    ps, depth);
1727                         break;
1728                 }
1729                 case 5:
1730                 {
1731                         net_io_sam_account_info("", sess_key,
1732                                                 &(delta->account_info), 
1733                                                    ps, depth);
1734                         break;
1735                 }
1736                 case 8:
1737                 {
1738                         net_io_sam_group_mem_info("", &(delta->grp_mem_info), 
1739                                                    ps, depth);
1740                         break;
1741                 }
1742                 case 9:
1743                 {
1744                         net_io_sam_alias_info("", &(delta->alias_info), 
1745                                                    ps, depth);
1746                         break;
1747                 }
1748                 case 0xC:
1749                 {
1750                         net_io_sam_alias_mem_info("", &(delta->als_mem_info), 
1751                                                    ps, depth);
1752                         break;
1753                 }
1754                 default:
1755                 {
1756                         DEBUG(0, ("Replication error: Unknown delta type %x\n", type));
1757                         break;
1758                 }
1759         }
1760
1761         return True;
1762 }
1763
1764 /*******************************************************************
1765 reads or writes a structure.
1766 ********************************************************************/
1767 BOOL net_io_r_sam_sync(char *desc, uint8 sess_key[16],
1768                                 NET_R_SAM_SYNC *r_s, prs_struct *ps, int depth)
1769 {
1770         int i;
1771
1772         if (r_s == NULL) return False;
1773
1774         prs_debug(ps, depth, desc, "net_io_r_sam_sync");
1775         depth++;
1776
1777         smb_io_cred("", &(r_s->srv_creds), ps, depth);
1778         prs_uint32("sync_context", ps, depth, &(r_s->sync_context));
1779
1780         prs_uint32("ptr_deltas", ps, depth, &(r_s->ptr_deltas));
1781         if (r_s->ptr_deltas != 0)
1782         {
1783                 prs_uint32("num_deltas ", ps, depth, &(r_s->num_deltas ));
1784                 prs_uint32("ptr_deltas2", ps, depth, &(r_s->ptr_deltas2));
1785                 if (r_s->ptr_deltas2 != 0)
1786                 {
1787                         prs_uint32("num_deltas2", ps, depth, &(r_s->num_deltas2));
1788                         if (r_s->num_deltas2 != r_s->num_deltas)
1789                         {
1790                                 /* RPC fault */
1791                                 return False;
1792                         }
1793
1794                         for (i = 0; i < r_s->num_deltas2; i++)
1795                         {
1796                                 net_io_sam_delta_hdr("", &r_s->hdr_deltas[i], ps, depth);
1797                         }
1798
1799                         for (i = 0; i < r_s->num_deltas2; i++)
1800                         {
1801                                 net_io_sam_delta_ctr("", sess_key,
1802                                           &r_s->deltas[i],
1803                                           r_s->hdr_deltas[i].type3, ps, depth);
1804                         }
1805                 }
1806         }
1807
1808         prs_align(ps);
1809         prs_uint32("status", ps, depth, &(r_s->status));
1810
1811         return True;
1812 }