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