qualifier name in session_enum was being assumed to exist. if NULL, the
[samba.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 void net_io_neg_flags(char *desc,  NEG_FLAGS *neg, prs_struct *ps, int depth)
33 {
34         if (neg == NULL) return;
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
44 /*******************************************************************
45 creates a NETLOGON_INFO_3 structure.
46 ********************************************************************/
47 static void make_netinfo_3(NETLOGON_INFO_3 *info, uint32 flags, uint32 logon_attempts)
48 {
49         info->flags          = flags;
50         info->logon_attempts = logon_attempts;
51         info->reserved_1     = 0x0;
52         info->reserved_2     = 0x0;
53         info->reserved_3     = 0x0;
54         info->reserved_4     = 0x0;
55         info->reserved_5     = 0x0;
56 }
57
58 /*******************************************************************
59 reads or writes a NETLOGON_INFO_3 structure.
60 ********************************************************************/
61 static void net_io_netinfo_3(char *desc,  NETLOGON_INFO_3 *info, prs_struct *ps, int depth)
62 {
63         if (info == NULL) return;
64
65         prs_debug(ps, depth, desc, "net_io_netinfo_3");
66         depth++;
67
68         prs_align(ps);
69         
70         prs_uint32("flags         ", ps, depth, &(info->flags         ));
71         prs_uint32("logon_attempts", ps, depth, &(info->logon_attempts));
72         prs_uint32("reserved_1    ", ps, depth, &(info->reserved_1    ));
73         prs_uint32("reserved_2    ", ps, depth, &(info->reserved_2    ));
74         prs_uint32("reserved_3    ", ps, depth, &(info->reserved_3    ));
75         prs_uint32("reserved_4    ", ps, depth, &(info->reserved_4    ));
76         prs_uint32("reserved_5    ", ps, depth, &(info->reserved_5    ));
77 }
78
79
80 /*******************************************************************
81 creates a NETLOGON_INFO_1 structure.
82 ********************************************************************/
83 static void make_netinfo_1(NETLOGON_INFO_1 *info, uint32 flags, uint32 pdc_status)
84 {
85         info->flags      = flags;
86         info->pdc_status = pdc_status;
87 }
88
89 /*******************************************************************
90 reads or writes a NETLOGON_INFO_1 structure.
91 ********************************************************************/
92 static void net_io_netinfo_1(char *desc,  NETLOGON_INFO_1 *info, prs_struct *ps, int depth)
93 {
94         if (info == NULL) return;
95
96         prs_debug(ps, depth, desc, "net_io_netinfo_1");
97         depth++;
98
99         prs_align(ps);
100         
101         prs_uint32("flags     ", ps, depth, &(info->flags     ));
102         prs_uint32("pdc_status", ps, depth, &(info->pdc_status));
103 }
104
105 /*******************************************************************
106 creates a NETLOGON_INFO_2 structure.
107 ********************************************************************/
108 static void make_netinfo_2(NETLOGON_INFO_2 *info, uint32 flags, uint32 pdc_status,
109                                 uint32 tc_status, char *trusted_dc_name)
110 {
111         int len_dc_name = strlen(trusted_dc_name);
112         info->flags      = flags;
113         info->pdc_status = pdc_status;
114         info->ptr_trusted_dc_name = 1;
115         info->tc_status  = tc_status;
116
117         if (trusted_dc_name != NULL)
118         {
119                 make_unistr2(&(info->uni_trusted_dc_name), trusted_dc_name, len_dc_name);
120         }
121         else
122         {
123                 make_unistr2(&(info->uni_trusted_dc_name), "", 1);
124         }
125 }
126
127 /*******************************************************************
128 reads or writes a NETLOGON_INFO_2 structure.
129 ********************************************************************/
130 static void net_io_netinfo_2(char *desc,  NETLOGON_INFO_2 *info, prs_struct *ps, int depth)
131 {
132         if (info == NULL) return;
133
134         prs_debug(ps, depth, desc, "net_io_netinfo_2");
135         depth++;
136
137         prs_align(ps);
138         
139         prs_uint32("flags              ", ps, depth, &(info->flags              ));
140         prs_uint32("pdc_status         ", ps, depth, &(info->pdc_status         ));
141         prs_uint32("ptr_trusted_dc_name", ps, depth, &(info->ptr_trusted_dc_name));
142         prs_uint32("tc_status          ", ps, depth, &(info->tc_status          ));
143
144         if (info->ptr_trusted_dc_name != 0)
145         {
146                 smb_io_unistr2("unistr2", &(info->uni_trusted_dc_name), info->ptr_trusted_dc_name, ps, depth);
147         }
148
149         prs_align(ps);
150 }
151
152 /*******************************************************************
153 reads or writes an NET_Q_LOGON_CTRL2 structure.
154 ********************************************************************/
155 void net_io_q_logon_ctrl2(char *desc,  NET_Q_LOGON_CTRL2 *q_l, prs_struct *ps, int depth)
156 {
157         if (q_l == NULL) return;
158
159         prs_debug(ps, depth, desc, "net_io_q_logon_ctrl2");
160         depth++;
161
162         prs_align(ps);
163
164         prs_uint32("ptr          ", ps, depth, &(q_l->ptr          ));
165
166         smb_io_unistr2 ("", &(q_l->uni_server_name), q_l->ptr, ps, depth);
167
168         prs_align(ps);
169
170         prs_uint32("function_code", ps, depth, &(q_l->function_code));
171         prs_uint32("query_level  ", ps, depth, &(q_l->query_level  ));
172         prs_uint32("switch_value ", ps, depth, &(q_l->switch_value ));
173 }
174
175 /*******************************************************************
176 makes an NET_R_LOGON_CTRL2 structure.
177 ********************************************************************/
178 void make_r_logon_ctrl2(NET_R_LOGON_CTRL2 *r_l, uint32 query_level,
179                                 uint32 flags, uint32 pdc_status, uint32 logon_attempts,
180                                 uint32 tc_status, char *trusted_domain_name)
181 {
182         if (r_l == NULL) return;
183
184         DEBUG(5,("make_r_logon_ctrl2\n"));
185
186         r_l->switch_value  = query_level; /* should only be 0x1 */
187
188         switch (query_level)
189         {
190                 case 1:
191                 {
192                         r_l->ptr = 1; /* undocumented pointer */
193                         make_netinfo_1(&(r_l->logon.info1), flags, pdc_status); 
194                         r_l->status = 0;
195
196                         break;
197                 }
198                 case 2:
199                 {
200                         r_l->ptr = 1; /* undocumented pointer */
201                         make_netinfo_2(&(r_l->logon.info2), flags, pdc_status,
202                                        tc_status, trusted_domain_name); 
203                         r_l->status = 0;
204
205                         break;
206                 }
207                 case 3:
208                 {
209                         r_l->ptr = 1; /* undocumented pointer */
210                         make_netinfo_3(&(r_l->logon.info3), flags, logon_attempts);     
211                         r_l->status = 0;
212
213                         break;
214                 }
215                 default:
216                 {
217                         DEBUG(2,("make_r_logon_ctrl2: unsupported switch value %d\n",
218                                 r_l->switch_value));
219                         r_l->ptr = 0; /* undocumented pointer */
220
221                         /* take a guess at an error code... */
222                         r_l->status = NT_STATUS_INVALID_INFO_CLASS;
223
224                         break;
225                 }
226         }
227 }
228
229 /*******************************************************************
230 reads or writes an NET_R_LOGON_CTRL2 structure.
231 ********************************************************************/
232 void net_io_r_logon_ctrl2(char *desc,  NET_R_LOGON_CTRL2 *r_l, prs_struct *ps, int depth)
233 {
234         if (r_l == NULL) return;
235
236         prs_debug(ps, depth, desc, "net_io_r_logon_ctrl2");
237         depth++;
238
239         prs_uint32("switch_value ", ps, depth, &(r_l->switch_value ));
240         prs_uint32("ptr          ", ps, depth, &(r_l->ptr          ));
241
242         if (r_l->ptr != 0)
243         {
244                 switch (r_l->switch_value)
245                 {
246                         case 1:
247                         {
248                                 net_io_netinfo_1("", &(r_l->logon.info1), ps, depth);
249                                 break;
250                         }
251                         case 2:
252                         {
253                                 net_io_netinfo_2("", &(r_l->logon.info2), ps, depth);
254                                 break;
255                         }
256                         case 3:
257                         {
258                                 net_io_netinfo_3("", &(r_l->logon.info3), ps, depth);
259                                 break;
260                         }
261                         default:
262                         {
263                                 DEBUG(2,("net_io_r_logon_ctrl2: unsupported switch value %d\n",
264                                         r_l->switch_value));
265                                 break;
266                         }
267                 }
268         }
269
270         prs_uint32("status       ", ps, depth, &(r_l->status       ));
271 }
272
273 /*******************************************************************
274 makes an NET_R_TRUST_DOM_LIST structure.
275 ********************************************************************/
276 void make_r_trust_dom(NET_R_TRUST_DOM_LIST *r_t,
277                         uint32 num_doms, char *dom_name)
278 {
279         int i = 0;
280
281         if (r_t == NULL) return;
282
283         DEBUG(5,("make_r_trust_dom\n"));
284
285         for (i = 0; i < MAX_TRUST_DOMS; i++)
286         {
287                 r_t->uni_trust_dom_name[i].uni_str_len = 0;
288                 r_t->uni_trust_dom_name[i].uni_max_len = 0;
289         }
290         if (num_doms > MAX_TRUST_DOMS) num_doms = MAX_TRUST_DOMS;
291
292         for (i = 0; i < num_doms; i++)
293         {
294                 fstring domain_name;
295                 fstrcpy(domain_name, dom_name);
296                 strupper(domain_name);
297                 make_unistr2(&(r_t->uni_trust_dom_name[i]), domain_name, strlen(domain_name));
298                 /* the use of UNISTR2 here is non-standard. */
299                 r_t->uni_trust_dom_name[i].undoc = 0x1;
300         }
301         
302         r_t->status = 0;
303 }
304
305 /*******************************************************************
306 reads or writes an NET_R_TRUST_DOM_LIST structure.
307 ********************************************************************/
308 void net_io_r_trust_dom(char *desc,  NET_R_TRUST_DOM_LIST *r_t, prs_struct *ps, int depth)
309 {
310         int i;
311         if (r_t == NULL) return;
312
313         prs_debug(ps, depth, desc, "net_io_r_trust_dom");
314         depth++;
315
316         for (i = 0; i < MAX_TRUST_DOMS; i++)
317         {
318                 if (r_t->uni_trust_dom_name[i].uni_str_len == 0) break;
319                 smb_io_unistr2("", &(r_t->uni_trust_dom_name[i]), True, ps, depth);
320         }
321
322         prs_uint32("status", ps, depth, &(r_t->status));
323 }
324
325
326 /*******************************************************************
327 reads or writes an NET_Q_TRUST_DOM_LIST structure.
328 ********************************************************************/
329 void net_io_q_trust_dom(char *desc,  NET_Q_TRUST_DOM_LIST *q_l, prs_struct *ps, int depth)
330 {
331         if (q_l == NULL) return;
332
333         prs_debug(ps, depth, desc, "net_io_q_trust_dom");
334         depth++;
335
336         prs_uint32("ptr          ", ps, depth, &(q_l->ptr          ));
337         smb_io_unistr2 ("", &(q_l->uni_server_name), q_l->ptr, ps, depth);
338
339         prs_align(ps);
340
341         prs_uint32("function_code", ps, depth, &(q_l->function_code));
342 }
343
344 /*******************************************************************
345 makes an NET_Q_REQ_CHAL structure.
346 ********************************************************************/
347 void make_q_req_chal(NET_Q_REQ_CHAL *q_c,
348                                 char *logon_srv, char *logon_clnt,
349                                 DOM_CHAL *clnt_chal)
350 {
351         if (q_c == NULL) return;
352
353         DEBUG(5,("make_q_req_chal: %d\n", __LINE__));
354
355         q_c->undoc_buffer = 1; /* don't know what this buffer is */
356
357         make_unistr2(&(q_c->uni_logon_srv ), logon_srv , strlen(logon_srv ));
358         make_unistr2(&(q_c->uni_logon_clnt), logon_clnt, strlen(logon_clnt));
359
360         memcpy(q_c->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data));
361
362         DEBUG(5,("make_q_req_chal: %d\n", __LINE__));
363 }
364
365 /*******************************************************************
366 reads or writes an NET_Q_REQ_CHAL structure.
367 ********************************************************************/
368 void net_io_q_req_chal(char *desc,  NET_Q_REQ_CHAL *q_c, prs_struct *ps, int depth)
369 {
370         int old_align;
371         if (q_c == NULL) return;
372
373         prs_debug(ps, depth, desc, "net_io_q_req_chal");
374         depth++;
375
376         prs_align(ps);
377     
378         prs_uint32("undoc_buffer", ps, depth, &(q_c->undoc_buffer));
379
380         smb_io_unistr2("", &(q_c->uni_logon_srv), True, ps, depth); /* logon server unicode string */
381         smb_io_unistr2("", &(q_c->uni_logon_clnt), True, ps, depth); /* logon client unicode string */
382
383         old_align = ps->align;
384         ps->align = 0;
385         /* client challenge is _not_ aligned after the unicode strings */
386         smb_io_chal("", &(q_c->clnt_chal), ps, depth); /* client challenge */
387         ps->align = old_align;
388 }
389
390 /*******************************************************************
391 reads or writes a structure.
392 ********************************************************************/
393 void net_io_r_req_chal(char *desc,  NET_R_REQ_CHAL *r_c, prs_struct *ps, int depth)
394 {
395         if (r_c == NULL) return;
396
397         prs_debug(ps, depth, desc, "net_io_r_req_chal");
398         depth++;
399
400         prs_align(ps);
401     
402         smb_io_chal("", &(r_c->srv_chal), ps, depth); /* server challenge */
403
404         prs_uint32("status", ps, depth, &(r_c->status));
405 }
406
407
408 /*******************************************************************
409 reads or writes a structure.
410 ********************************************************************/
411 void make_q_auth_2(NET_Q_AUTH_2 *q_a,
412                 char *logon_srv, char *acct_name, uint16 sec_chan, char *comp_name,
413                 DOM_CHAL *clnt_chal, uint32 clnt_flgs)
414 {
415         if (q_a == NULL) return;
416
417         DEBUG(5,("make_q_auth_2: %d\n", __LINE__));
418
419         make_log_info(&(q_a->clnt_id), logon_srv, acct_name, sec_chan, comp_name);
420         memcpy(q_a->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data));
421         q_a->clnt_flgs.neg_flags = clnt_flgs;
422
423         DEBUG(5,("make_q_auth_2: %d\n", __LINE__));
424 }
425
426 /*******************************************************************
427 reads or writes a structure.
428 ********************************************************************/
429 void net_io_q_auth_2(char *desc,  NET_Q_AUTH_2 *q_a, prs_struct *ps, int depth)
430 {
431         int old_align;
432         if (q_a == NULL) return;
433
434         prs_debug(ps, depth, desc, "net_io_q_auth_2");
435         depth++;
436
437         prs_align(ps);
438     
439         smb_io_log_info ("", &(q_a->clnt_id), ps, depth); /* client identification info */
440         /* client challenge is _not_ aligned */
441         old_align = ps->align;
442         ps->align = 0;
443         smb_io_chal     ("", &(q_a->clnt_chal), ps, depth); /* client-calculated credentials */
444         ps->align = old_align;
445         net_io_neg_flags("", &(q_a->clnt_flgs), ps, depth);
446 }
447
448 /*******************************************************************
449 reads or writes a structure.
450 ********************************************************************/
451 void net_io_r_auth_2(char *desc,  NET_R_AUTH_2 *r_a, prs_struct *ps, int depth)
452 {
453         if (r_a == NULL) return;
454
455         prs_debug(ps, depth, desc, "net_io_r_auth_2");
456         depth++;
457
458         prs_align(ps);
459     
460         smb_io_chal     ("", &(r_a->srv_chal), ps, depth); /* server challenge */
461         net_io_neg_flags("", &(r_a->srv_flgs), ps, depth);
462
463         prs_uint32("status", ps, depth, &(r_a->status));
464 }
465
466
467 /*******************************************************************
468 reads or writes a structure.
469 ********************************************************************/
470 void make_q_srv_pwset(NET_Q_SRV_PWSET *q_s, char *logon_srv, char *acct_name, 
471                 uint16 sec_chan, char *comp_name, DOM_CRED *cred, char nt_cypher[16])
472 {
473         if (q_s == NULL || cred == NULL) return;
474
475         DEBUG(5,("make_q_srv_pwset\n"));
476
477         make_clnt_info(&(q_s->clnt_id), logon_srv, acct_name, sec_chan, comp_name, cred);
478
479         memcpy(q_s->pwd, nt_cypher, sizeof(q_s->pwd)); 
480 }
481
482 /*******************************************************************
483 reads or writes a structure.
484 ********************************************************************/
485 void net_io_q_srv_pwset(char *desc,  NET_Q_SRV_PWSET *q_s, prs_struct *ps, int depth)
486 {
487         if (q_s == NULL) return;
488
489         prs_debug(ps, depth, desc, "net_io_q_srv_pwset");
490         depth++;
491
492         prs_align(ps);
493     
494         smb_io_clnt_info("", &(q_s->clnt_id), ps, depth); /* client identification/authentication info */
495         prs_uint8s (False, "pwd", ps, depth, q_s->pwd, 16); /* new password - undocumented */
496 }
497
498 /*******************************************************************
499 reads or writes a structure.
500 ********************************************************************/
501 void net_io_r_srv_pwset(char *desc,  NET_R_SRV_PWSET *r_s, prs_struct *ps, int depth)
502 {
503         if (r_s == NULL) return;
504
505         prs_debug(ps, depth, desc, "net_io_r_srv_pwset");
506         depth++;
507
508         prs_align(ps);
509     
510         smb_io_cred("", &(r_s->srv_cred), ps, depth); /* server challenge */
511
512         prs_uint32("status", ps, depth, &(r_s->status));
513 }
514
515
516 /*************************************************************************
517  make DOM_SID2 array from a string containing multiple sids
518  *************************************************************************/
519 static int make_dom_sid2s(char *sids_str, DOM_SID2 *sids, int max_sids)
520 {
521         char *ptr;
522         pstring s2;
523         int count;
524
525         DEBUG(4,("make_dom_sid2s: %s\n", sids_str ? sids_str:""));
526
527         if (sids_str == NULL || *sids_str == 0) return 0;
528
529         for (count = 0, ptr = sids_str; 
530              next_token(&ptr, s2, NULL, sizeof(s2)) && count < max_sids; 
531              count++) 
532         {
533                 DOM_SID tmpsid;
534                 string_to_sid(&tmpsid, s2);
535                 make_dom_sid2(&sids[count], &tmpsid);
536         }
537
538         return count;
539 }
540
541 /*******************************************************************
542 reads or writes an NET_ID_INFO_1 structure.
543 ********************************************************************/
544 static void net_io_id_info1(char *desc,  NET_ID_INFO_1 *id, prs_struct *ps, int depth)
545 {
546         if (id == NULL) return;
547
548         prs_debug(ps, depth, desc, "net_io_id_info1");
549         depth++;
550
551         prs_align(ps);
552         
553         prs_uint32("ptr_id_info1", ps, depth, &(id->ptr_id_info1));
554
555         if (id->ptr_id_info1 != 0)
556         {
557                 smb_io_unihdr("unihdr", &(id->hdr_domain_name), ps, depth);
558
559                 prs_uint32("param_ctrl", ps, depth, &(id->param_ctrl));
560                 smb_io_logon_id("", &(id->logon_id), ps, depth);
561
562                 smb_io_unihdr("unihdr", &(id->hdr_user_name  ), ps, depth);
563                 smb_io_unihdr("unihdr", &(id->hdr_wksta_name ), ps, depth);
564
565                 smb_io_owf_info("", &(id->lm_owf), ps, depth);
566                 smb_io_owf_info("", &(id->nt_owf), ps, depth);
567
568                 smb_io_unistr2("unistr2", &(id->uni_domain_name), id->hdr_domain_name.buffer, ps, depth);
569                 smb_io_unistr2("unistr2", &(id->uni_user_name  ), id->hdr_user_name.buffer, ps, depth);
570                 smb_io_unistr2("unistr2", &(id->uni_wksta_name ), id->hdr_wksta_name.buffer, ps, depth);
571         }
572 }
573
574 /*******************************************************************
575 makes a NET_ID_INFO_2 structure.
576
577 This is a network logon packet. The log_id parameters
578 are what an NT server would generate for LUID once the
579 user is logged on. I don't think we care about them.
580
581 Note that this has no access to the NT and LM hashed passwords,
582 so it forwards the challenge, and the NT and LM responses (24
583 bytes each) over the secure channel to the Domain controller
584 for it to say yea or nay. This is the preferred method of 
585 checking for a logon as it doesn't export the password
586 hashes to anyone who has compromised the secure channel. JRA.
587 ********************************************************************/
588
589 void make_id_info2(NET_ID_INFO_2 *id, char *domain_name,
590                                 uint32 param_ctrl, uint32 log_id_low, uint32 log_id_high,
591                                 char *user_name, char *wksta_name,
592                                 unsigned char lm_challenge[8],
593                                 unsigned char lm_chal_resp[24],
594                                 unsigned char nt_chal_resp[24])
595 {
596         int len_domain_name = strlen(domain_name);
597         int len_user_name   = strlen(user_name  );
598         int len_wksta_name  = strlen(wksta_name );
599     int nt_chal_resp_len = ((nt_chal_resp != NULL) ? 24 : 0);
600     int lm_chal_resp_len = ((lm_chal_resp != NULL) ? 24 : 0);
601         unsigned char lm_owf[24];
602         unsigned char nt_owf[24];
603
604         if (id == NULL) return;
605
606         DEBUG(5,("make_id_info2: %d\n", __LINE__));
607
608         id->ptr_id_info2 = 1;
609
610         make_uni_hdr(&(id->hdr_domain_name), len_domain_name, len_domain_name, 4);
611
612         id->param_ctrl = param_ctrl;
613         make_logon_id(&(id->logon_id), log_id_low, log_id_high);
614
615         make_uni_hdr(&(id->hdr_user_name  ), len_user_name  , len_user_name  , 4);
616         make_uni_hdr(&(id->hdr_wksta_name ), len_wksta_name , len_wksta_name , 4);
617
618         if (nt_chal_resp)
619         {
620                 /* oops.  can only send what-ever-it-is direct */
621                 memcpy(nt_owf, nt_chal_resp, 24);
622                 nt_chal_resp = nt_owf;
623         }
624         if (lm_chal_resp)
625         {
626                 /* oops.  can only send what-ever-it-is direct */
627                 memcpy(lm_owf, lm_chal_resp, 24);
628                 lm_chal_resp = lm_owf;
629         }
630
631         memcpy(id->lm_chal, lm_challenge, sizeof(id->lm_chal));
632         make_str_hdr(&(id->hdr_nt_chal_resp), 24, nt_chal_resp_len, nt_chal_resp != NULL ? 1 : 0);
633         make_str_hdr(&(id->hdr_lm_chal_resp), 24, lm_chal_resp_len, lm_chal_resp != NULL ? 1 : 0);
634
635         make_unistr2(&(id->uni_domain_name), domain_name, len_domain_name);
636         make_unistr2(&(id->uni_user_name  ), user_name  , len_user_name  );
637         make_unistr2(&(id->uni_wksta_name ), wksta_name , len_wksta_name );
638
639         make_string2(&(id->nt_chal_resp ), (char *)nt_chal_resp , nt_chal_resp_len);
640         make_string2(&(id->lm_chal_resp ), (char *)lm_chal_resp , lm_chal_resp_len);
641 }
642
643 /*******************************************************************
644 reads or writes an NET_ID_INFO_2 structure.
645 ********************************************************************/
646 static void net_io_id_info2(char *desc,  NET_ID_INFO_2 *id, prs_struct *ps, int depth)
647 {
648         if (id == NULL) return;
649
650         prs_debug(ps, depth, desc, "net_io_id_info2");
651         depth++;
652
653         prs_align(ps);
654         
655         prs_uint32("ptr_id_info2", ps, depth, &(id->ptr_id_info2));
656
657         if (id->ptr_id_info2 != 0)
658         {
659                 smb_io_unihdr("unihdr", &(id->hdr_domain_name), ps, depth);
660
661                 prs_uint32("param_ctrl", ps, depth, &(id->param_ctrl));
662                 smb_io_logon_id("", &(id->logon_id), ps, depth);
663
664                 smb_io_unihdr("unihdr", &(id->hdr_user_name  ), ps, depth);
665                 smb_io_unihdr("unihdr", &(id->hdr_wksta_name ), ps, depth);
666
667                 prs_uint8s (False, "lm_chal", ps, depth, id->lm_chal, 8); /* lm 8 byte challenge */
668
669                 smb_io_strhdr("hdr_nt_chal_resp", &(id->hdr_nt_chal_resp ), ps, depth);
670                 smb_io_strhdr("hdr_lm_chal_resp", &(id->hdr_lm_chal_resp ), ps, depth);
671
672                 smb_io_unistr2("uni_domain_name", &(id->uni_domain_name), id->hdr_domain_name .buffer, ps, depth);
673                 smb_io_unistr2("uni_user_name  ", &(id->uni_user_name  ), id->hdr_user_name   .buffer, ps, depth);
674                 smb_io_unistr2("uni_wksta_name ", &(id->uni_wksta_name ), id->hdr_wksta_name  .buffer, ps, depth);
675                 smb_io_string2("nt_chal_resp"   , &(id->nt_chal_resp)   , id->hdr_nt_chal_resp.buffer, ps, depth);
676                 smb_io_string2("lm_chal_resp"   , &(id->lm_chal_resp)   , id->hdr_lm_chal_resp.buffer, ps, depth);
677         }
678 }
679
680
681 /*******************************************************************
682 makes a DOM_SAM_INFO structure.
683 ********************************************************************/
684 void make_sam_info(DOM_SAM_INFO *sam,
685                                 char *logon_srv, char *comp_name, DOM_CRED *clnt_cred,
686                                 DOM_CRED *rtn_cred, uint16 logon_level,
687                                 NET_ID_INFO_CTR *ctr, uint16 validation_level)
688 {
689         if (sam == NULL) return;
690
691         DEBUG(5,("make_sam_info: %d\n", __LINE__));
692
693         make_clnt_info2(&(sam->client), logon_srv, comp_name, clnt_cred);
694
695         if (rtn_cred != NULL)
696         {
697                 sam->ptr_rtn_cred = 1;
698                 memcpy(&(sam->rtn_cred), rtn_cred, sizeof(sam->rtn_cred));
699         }
700         else
701         {
702                 sam->ptr_rtn_cred = 0;
703         }
704
705         sam->logon_level  = logon_level;
706         sam->ctr          = ctr;
707         sam->validation_level = validation_level;
708 }
709
710 /*******************************************************************
711 reads or writes a DOM_SAM_INFO structure.
712 ********************************************************************/
713 static void net_io_id_info_ctr(char *desc,  NET_ID_INFO_CTR *ctr, prs_struct *ps, int depth)
714 {
715         if (ctr == NULL) return;
716
717         prs_debug(ps, depth, desc, "smb_io_sam_info");
718         depth++;
719
720         /* don't 4-byte align here! */
721
722         prs_uint16("switch_value ", ps, depth, &(ctr->switch_value));
723
724         switch (ctr->switch_value)
725         {
726                 case 1:
727                 {
728                         net_io_id_info1("", &(ctr->auth.id1), ps, depth);
729                         break;
730                 }
731                 case 2:
732                 {
733                         net_io_id_info2("", &(ctr->auth.id2), ps, depth);
734                         break;
735                 }
736                 default:
737                 {
738                         /* PANIC! */
739                         DEBUG(4,("smb_io_sam_info: unknown switch_value!\n"));
740                         break;
741                 }
742         }
743 }
744
745 /*******************************************************************
746 reads or writes a DOM_SAM_INFO structure.
747 ********************************************************************/
748 static void smb_io_sam_info(char *desc,  DOM_SAM_INFO *sam, prs_struct *ps, int depth)
749 {
750         if (sam == NULL) return;
751
752         prs_debug(ps, depth, desc, "smb_io_sam_info");
753         depth++;
754
755         prs_align(ps);
756         
757         smb_io_clnt_info2("", &(sam->client  ), ps, depth);
758
759         prs_uint32("ptr_rtn_cred ", ps, depth, &(sam->ptr_rtn_cred));
760         smb_io_cred      ("", &(sam->rtn_cred), ps, depth);
761
762         prs_uint16("logon_level  ", ps, depth, &(sam->logon_level ));
763
764         if (sam->logon_level != 0 && sam->ctr != NULL)
765         {
766                 net_io_id_info_ctr("logon_info", sam->ctr, ps, depth);
767         }
768
769         prs_uint16("validation_level", ps, depth, &(sam->validation_level));
770 }
771
772 /*************************************************************************
773  make_net_user_info3
774  *************************************************************************/
775 void make_net_user_info3(NET_USER_INFO_3 *usr,
776
777         NTTIME *logon_time,
778         NTTIME *logoff_time,
779         NTTIME *kickoff_time,
780         NTTIME *pass_last_set_time,
781         NTTIME *pass_can_change_time,
782         NTTIME *pass_must_change_time,
783
784         char *user_name,
785         char *full_name,
786         char *logon_script,
787         char *profile_path,
788         char *home_dir,
789         char *dir_drive,
790
791         uint16 logon_count,
792         uint16 bad_pw_count,
793
794         uint32 user_id,
795         uint32 group_id,
796         uint32 num_groups,
797         DOM_GID *gids,
798         uint32 user_flgs,
799
800         char sess_key[16],
801
802         char *logon_srv,
803         char *logon_dom,
804
805         DOM_SID *dom_sid,
806         char *other_sids)
807 {
808         /* only cope with one "other" sid, right now. */
809         /* need to count the number of space-delimited sids */
810         int i;
811         int num_other_sids = 0;
812
813         int len_user_name    = strlen(user_name   );
814         int len_full_name    = strlen(full_name   );
815         int len_logon_script = strlen(logon_script);
816         int len_profile_path = strlen(profile_path);
817         int len_home_dir     = strlen(home_dir    );
818         int len_dir_drive    = strlen(dir_drive   );
819
820         int len_logon_srv    = strlen(logon_srv);
821         int len_logon_dom    = strlen(logon_dom);
822
823         usr->ptr_user_info = 1; /* yes, we're bothering to put USER_INFO data here */
824
825         usr->logon_time            = *logon_time;
826         usr->logoff_time           = *logoff_time;
827         usr->kickoff_time          = *kickoff_time;
828         usr->pass_last_set_time    = *pass_last_set_time;
829         usr->pass_can_change_time  = *pass_can_change_time;
830         usr->pass_must_change_time = *pass_must_change_time;
831
832         make_uni_hdr(&(usr->hdr_user_name   ), len_user_name   , len_user_name   , 4);
833         make_uni_hdr(&(usr->hdr_full_name   ), len_full_name   , len_full_name   , 4);
834         make_uni_hdr(&(usr->hdr_logon_script), len_logon_script, len_logon_script, 4);
835         make_uni_hdr(&(usr->hdr_profile_path), len_profile_path, len_profile_path, 4);
836         make_uni_hdr(&(usr->hdr_home_dir    ), len_home_dir    , len_home_dir    , 4);
837         make_uni_hdr(&(usr->hdr_dir_drive   ), len_dir_drive   , len_dir_drive   , 4);
838
839         usr->logon_count = logon_count;
840         usr->bad_pw_count = bad_pw_count;
841
842         usr->user_id = user_id;
843         usr->group_id = group_id;
844         usr->num_groups = num_groups;
845         usr->buffer_groups = 1; /* indicates fill in groups, below, even if there are none */
846         usr->user_flgs = user_flgs;
847
848         if (sess_key != NULL)
849         {
850                 memcpy(usr->user_sess_key, sess_key, sizeof(usr->user_sess_key));
851         }
852         else
853         {
854                 bzero(usr->user_sess_key, sizeof(usr->user_sess_key));
855         }
856
857         make_uni_hdr(&(usr->hdr_logon_srv), len_logon_srv, len_logon_srv, 4);
858         make_uni_hdr(&(usr->hdr_logon_dom), len_logon_dom, len_logon_dom, 4);
859
860         usr->buffer_dom_id = dom_sid ? 1 : 0; /* yes, we're bothering to put a domain SID in */
861
862         bzero(usr->padding, sizeof(usr->padding));
863
864         num_other_sids = make_dom_sid2s(other_sids, usr->other_sids, LSA_MAX_SIDS);
865
866         usr->num_other_sids = num_other_sids;
867         usr->buffer_other_sids = num_other_sids != 0 ? 1 : 0; 
868         
869         make_unistr2(&(usr->uni_user_name   ), user_name   , len_user_name   );
870         make_unistr2(&(usr->uni_full_name   ), full_name   , len_full_name   );
871         make_unistr2(&(usr->uni_logon_script), logon_script, len_logon_script);
872         make_unistr2(&(usr->uni_profile_path), profile_path, len_profile_path);
873         make_unistr2(&(usr->uni_home_dir    ), home_dir    , len_home_dir    );
874         make_unistr2(&(usr->uni_dir_drive   ), dir_drive   , len_dir_drive   );
875
876         usr->num_groups2 = num_groups;
877
878         SMB_ASSERT_ARRAY(usr->gids, num_groups);
879
880         for (i = 0; i < num_groups; i++)
881         {
882                 usr->gids[i] = gids[i];
883         }
884
885         make_unistr2(&(usr->uni_logon_srv), logon_srv, len_logon_srv);
886         make_unistr2(&(usr->uni_logon_dom), logon_dom, len_logon_dom);
887
888         make_dom_sid2(&(usr->dom_sid), dom_sid);
889         /* "other" sids are set up above */
890 }
891
892
893 /*******************************************************************
894 reads or writes a structure.
895 ********************************************************************/
896 static void net_io_user_info3(char *desc,  NET_USER_INFO_3 *usr, prs_struct *ps, int depth)
897 {
898         int i;
899
900         if (usr == NULL) return;
901
902         prs_debug(ps, depth, desc, "lsa_io_lsa_user_info");
903         depth++;
904
905         prs_align(ps);
906         
907         prs_uint32("ptr_user_info ", ps, depth, &(usr->ptr_user_info));
908
909         if (usr->ptr_user_info != 0)
910         {
911                 smb_io_time("time", &(usr->logon_time)           , ps, depth); /* logon time */
912                 smb_io_time("time", &(usr->logoff_time)          , ps, depth); /* logoff time */
913                 smb_io_time("time", &(usr->kickoff_time)         , ps, depth); /* kickoff time */
914                 smb_io_time("time", &(usr->pass_last_set_time)   , ps, depth); /* password last set time */
915                 smb_io_time("time", &(usr->pass_can_change_time) , ps, depth); /* password can change time */
916                 smb_io_time("time", &(usr->pass_must_change_time), ps, depth); /* password must change time */
917
918                 smb_io_unihdr("unihdr", &(usr->hdr_user_name)   , ps, depth); /* username unicode string header */
919                 smb_io_unihdr("unihdr", &(usr->hdr_full_name)   , ps, depth); /* user's full name unicode string header */
920                 smb_io_unihdr("unihdr", &(usr->hdr_logon_script), ps, depth); /* logon script unicode string header */
921                 smb_io_unihdr("unihdr", &(usr->hdr_profile_path), ps, depth); /* profile path unicode string header */
922                 smb_io_unihdr("unihdr", &(usr->hdr_home_dir)    , ps, depth); /* home directory unicode string header */
923                 smb_io_unihdr("unihdr", &(usr->hdr_dir_drive)   , ps, depth); /* home directory drive unicode string header */
924
925                 prs_uint16("logon_count   ", ps, depth, &(usr->logon_count ));  /* logon count */
926                 prs_uint16("bad_pw_count  ", ps, depth, &(usr->bad_pw_count)); /* bad password count */
927
928                 prs_uint32("user_id       ", ps, depth, &(usr->user_id      ));       /* User ID */
929                 prs_uint32("group_id      ", ps, depth, &(usr->group_id     ));      /* Group ID */
930                 prs_uint32("num_groups    ", ps, depth, &(usr->num_groups   ));    /* num groups */
931                 prs_uint32("buffer_groups ", ps, depth, &(usr->buffer_groups)); /* undocumented buffer pointer to groups. */
932                 prs_uint32("user_flgs     ", ps, depth, &(usr->user_flgs    ));     /* user flags */
933
934                 prs_uint8s (False, "user_sess_key", ps, depth, usr->user_sess_key, 16); /* unused user session key */
935
936                 smb_io_unihdr("unihdr", &(usr->hdr_logon_srv), ps, depth); /* logon server unicode string header */
937                 smb_io_unihdr("unihdr", &(usr->hdr_logon_dom), ps, depth); /* logon domain unicode string header */
938
939                 prs_uint32("buffer_dom_id ", ps, depth, &(usr->buffer_dom_id)); /* undocumented logon domain id pointer */
940                 prs_uint8s (False, "padding       ", ps, depth, usr->padding, 40); /* unused padding bytes? */
941
942                 prs_uint32("num_other_sids", ps, depth, &(usr->num_other_sids)); /* 0 - num_sids */
943                 prs_uint32("buffer_other_sids", ps, depth, &(usr->buffer_other_sids)); /* NULL - undocumented pointer to SIDs. */
944                 
945                 smb_io_unistr2("unistr2", &(usr->uni_user_name)   , usr->hdr_user_name   .buffer, ps, depth); /* username unicode string */
946                 smb_io_unistr2("unistr2", &(usr->uni_full_name)   , usr->hdr_full_name   .buffer, ps, depth); /* user's full name unicode string */
947                 smb_io_unistr2("unistr2", &(usr->uni_logon_script), usr->hdr_logon_script.buffer, ps, depth); /* logon script unicode string */
948                 smb_io_unistr2("unistr2", &(usr->uni_profile_path), usr->hdr_profile_path.buffer, ps, depth); /* profile path unicode string */
949                 smb_io_unistr2("unistr2", &(usr->uni_home_dir)    , usr->hdr_home_dir    .buffer, ps, depth); /* home directory unicode string */
950                 smb_io_unistr2("unistr2", &(usr->uni_dir_drive)   , usr->hdr_dir_drive   .buffer, ps, depth); /* home directory drive unicode string */
951
952                 prs_align(ps);
953                 prs_uint32("num_groups2   ", ps, depth, &(usr->num_groups2));        /* num groups */
954                 SMB_ASSERT_ARRAY(usr->gids, usr->num_groups2);
955                 for (i = 0; i < usr->num_groups2; i++)
956                 {
957                         smb_io_gid("", &(usr->gids[i]), ps, depth); /* group info */
958                 }
959
960                 smb_io_unistr2("unistr2", &( usr->uni_logon_srv), usr->hdr_logon_srv.buffer, ps, depth); /* logon server unicode string */
961                 smb_io_unistr2("unistr2", &( usr->uni_logon_dom), usr->hdr_logon_srv.buffer, ps, depth); /* logon domain unicode string */
962
963                 smb_io_dom_sid2("", &(usr->dom_sid), ps, depth);           /* domain SID */
964
965                 SMB_ASSERT_ARRAY(usr->other_sids, usr->num_other_sids);
966
967                 for (i = 0; i < usr->num_other_sids; i++)
968                 {
969                         smb_io_dom_sid2("", &(usr->other_sids[i]), ps, depth); /* other domain SIDs */
970                 }
971         }
972 }
973
974 /*******************************************************************
975 reads or writes a structure.
976 ********************************************************************/
977 void net_io_q_sam_logon(char *desc,  NET_Q_SAM_LOGON *q_l, prs_struct *ps, int depth)
978 {
979         if (q_l == NULL) return;
980
981         prs_debug(ps, depth, desc, "net_io_q_sam_logon");
982         depth++;
983
984         prs_align(ps);
985         
986         smb_io_sam_info("", &(q_l->sam_id), ps, depth);           /* domain SID */
987 }
988
989 /*******************************************************************
990 reads or writes a structure.
991 ********************************************************************/
992 void net_io_r_sam_logon(char *desc,  NET_R_SAM_LOGON *r_l, prs_struct *ps, int depth)
993 {
994         if (r_l == NULL) return;
995
996         prs_debug(ps, depth, desc, "net_io_r_sam_logon");
997         depth++;
998
999         prs_uint32("buffer_creds", ps, depth, &(r_l->buffer_creds)); /* undocumented buffer pointer */
1000         smb_io_cred("", &(r_l->srv_creds), ps, depth); /* server credentials.  server time stamp appears to be ignored. */
1001
1002         prs_uint16("switch_value", ps, depth, &(r_l->switch_value));
1003         prs_align(ps);
1004
1005         if (r_l->switch_value != 0)
1006         {
1007                 net_io_user_info3("", r_l->user, ps, depth);
1008         }
1009
1010         prs_uint32("auth_resp   ", ps, depth, &(r_l->auth_resp)); /* 1 - Authoritative response; 0 - Non-Auth? */
1011
1012         prs_uint32("status      ", ps, depth, &(r_l->status));
1013
1014         prs_align(ps);
1015 }
1016
1017 /*******************************************************************
1018 reads or writes a structure.
1019 ********************************************************************/
1020 void net_io_q_sam_logoff(char *desc,  NET_Q_SAM_LOGOFF *q_l, prs_struct *ps, int depth)
1021 {
1022         if (q_l == NULL) return;
1023
1024         prs_debug(ps, depth, desc, "net_io_q_sam_logoff");
1025         depth++;
1026
1027         prs_align(ps);
1028         
1029         smb_io_sam_info("", &(q_l->sam_id), ps, depth);           /* domain SID */
1030 }
1031
1032 /*******************************************************************
1033 reads or writes a structure.
1034 ********************************************************************/
1035 void net_io_r_sam_logoff(char *desc,  NET_R_SAM_LOGOFF *r_l, prs_struct *ps, int depth)
1036 {
1037         if (r_l == NULL) return;
1038
1039         prs_debug(ps, depth, desc, "net_io_r_sam_logoff");
1040         depth++;
1041
1042         prs_align(ps);
1043         
1044         prs_uint32("buffer_creds", ps, depth, &(r_l->buffer_creds)); /* undocumented buffer pointer */
1045         smb_io_cred("", &(r_l->srv_creds), ps, depth); /* server credentials.  server time stamp appears to be ignored. */
1046
1047         prs_uint32("status      ", ps, depth, &(r_l->status));
1048 }
1049
1050