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