a5dfad9b7f7aaef62294824a0df88a070ddcf92f
[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 *logon_srv, char *acct_name, 
503                 uint16 sec_chan, char *comp_name, DOM_CRED *cred, char nt_cypher[16])
504 {
505         if (q_s == NULL || cred == NULL) return;
506
507         DEBUG(5,("make_q_srv_pwset\n"));
508
509         make_clnt_info(&(q_s->clnt_id), logon_srv, acct_name, sec_chan, comp_name, cred);
510
511         memcpy(q_s->pwd, nt_cypher, sizeof(q_s->pwd)); 
512 }
513
514 /*******************************************************************
515 reads or writes a structure.
516 ********************************************************************/
517 void net_io_q_srv_pwset(char *desc,  NET_Q_SRV_PWSET *q_s, prs_struct *ps, int depth)
518 {
519         if (q_s == NULL) return;
520
521         prs_debug(ps, depth, desc, "net_io_q_srv_pwset");
522         depth++;
523
524         prs_align(ps);
525     
526         smb_io_clnt_info("", &(q_s->clnt_id), ps, depth); /* client identification/authentication info */
527         prs_uint8s (False, "pwd", ps, depth, q_s->pwd, 16); /* new password - undocumented */
528 }
529
530 /*******************************************************************
531 reads or writes a structure.
532 ********************************************************************/
533 void net_io_r_srv_pwset(char *desc,  NET_R_SRV_PWSET *r_s, prs_struct *ps, int depth)
534 {
535         if (r_s == NULL) return;
536
537         prs_debug(ps, depth, desc, "net_io_r_srv_pwset");
538         depth++;
539
540         prs_align(ps);
541     
542         smb_io_cred("", &(r_s->srv_cred), ps, depth); /* server challenge */
543
544         prs_uint32("status", ps, depth, &(r_s->status));
545 }
546
547
548 /*************************************************************************
549  make DOM_SID2 array from a string containing multiple sids
550  *************************************************************************/
551 static int make_dom_sid2s(char *sids_str, DOM_SID2 *sids, int max_sids)
552 {
553         char *ptr;
554         pstring s2;
555         int count;
556
557         DEBUG(4,("make_dom_sid2s: %s\n", sids_str ? sids_str:""));
558
559         if (sids_str == NULL || *sids_str == 0) return 0;
560
561         for (count = 0, ptr = sids_str; next_token(&ptr, s2, NULL) && count < max_sids; count++) 
562         {
563                 DOM_SID tmpsid;
564                 string_to_sid(&tmpsid, s2);
565                 make_dom_sid2(&sids[count], &tmpsid);
566         }
567
568         return count;
569 }
570
571 /*******************************************************************
572 makes a NET_ID_INFO_1 structure.
573
574 This is an interactive logon packet. The log_id parameters
575 are what an NT server would generate for LUID once the
576 user is logged on. I don't think we care about them.
577
578 Note that this passes the actual NT and LM hashed passwords
579 over the secure channel. This is not the preferred logon 
580 method from a Samba domain client as it exposes the password
581 hashes to anyone who has compromised the secure channel. JRA.
582 ********************************************************************/
583
584 void make_id_info1(NET_ID_INFO_1 *id, char *domain_name,
585                                 uint32 param_ctrl, uint32 log_id_low, uint32 log_id_high,
586                                 char *user_name, char *wksta_name,
587                                 char sess_key[16],
588                                 unsigned char lm_cypher[16], unsigned char nt_cypher[16])
589 {
590         int len_domain_name = strlen(domain_name);
591         int len_user_name   = strlen(user_name  );
592         int len_wksta_name  = strlen(wksta_name );
593
594         unsigned char lm_owf[16];
595         unsigned char nt_owf[16];
596
597         if (id == NULL) return;
598
599         DEBUG(5,("make_id_info1: %d\n", __LINE__));
600
601         id->ptr_id_info1 = 1;
602
603         make_uni_hdr(&(id->hdr_domain_name), len_domain_name, len_domain_name, 4);
604
605         id->param_ctrl = param_ctrl;
606         make_logon_id(&(id->logon_id), log_id_low, log_id_high);
607
608         make_uni_hdr(&(id->hdr_user_name  ), len_user_name  , len_user_name  , 4);
609         make_uni_hdr(&(id->hdr_wksta_name ), len_wksta_name , len_wksta_name , 4);
610
611         if (lm_cypher && nt_cypher)
612         {
613                 void arcfour(uint8 key[16], uint8 out[16], uint8 in[16]);
614                 unsigned char owf_key[16];
615 #ifdef DEBUG_PASSWORD
616                 DEBUG(100,("lm cypher:"));
617                 dump_data(100, lm_cypher, 16);
618
619                 DEBUG(100,("nt cypher:"));
620                 dump_data(100, nt_cypher, 16);
621 #endif
622
623                 memcpy(owf_key, sess_key, 16);
624
625                 memcpy(lm_owf, lm_cypher, 16);
626                 memcpy(nt_owf, nt_cypher, 16);
627                 SamOEMhash(lm_owf, owf_key, False);
628                 SamOEMhash(nt_owf, owf_key, False);
629
630 #ifdef DEBUG_PASSWORD
631                 DEBUG(100,("hash of lm owf password:"));
632                 dump_data(100, lm_owf, 16);
633
634                 DEBUG(100,("hash of nt owf password:"));
635                 dump_data(100, nt_owf, 16);
636 #endif
637                 /* set up pointers to blocks */
638                 lm_cypher = lm_owf;
639                 nt_cypher = nt_owf;
640         }
641
642         make_owf_info(&(id->lm_owf), lm_cypher);
643         make_owf_info(&(id->nt_owf), nt_cypher);
644
645         make_unistr2(&(id->uni_domain_name), domain_name, len_domain_name);
646         make_unistr2(&(id->uni_user_name  ), user_name  , len_user_name  );
647         make_unistr2(&(id->uni_wksta_name ), wksta_name , len_wksta_name );
648 }
649
650 /*******************************************************************
651 reads or writes an NET_ID_INFO_1 structure.
652 ********************************************************************/
653 void net_io_id_info1(char *desc,  NET_ID_INFO_1 *id, prs_struct *ps, int depth)
654 {
655         if (id == NULL) return;
656
657         prs_debug(ps, depth, desc, "net_io_id_info1");
658         depth++;
659
660         prs_align(ps);
661         
662         prs_uint32("ptr_id_info1", ps, depth, &(id->ptr_id_info1));
663
664         if (id->ptr_id_info1 != 0)
665         {
666                 smb_io_unihdr("unihdr", &(id->hdr_domain_name), ps, depth);
667
668                 prs_uint32("param_ctrl", ps, depth, &(id->param_ctrl));
669                 smb_io_logon_id("", &(id->logon_id), ps, depth);
670
671                 smb_io_unihdr("unihdr", &(id->hdr_user_name  ), ps, depth);
672                 smb_io_unihdr("unihdr", &(id->hdr_wksta_name ), ps, depth);
673
674                 smb_io_owf_info("", &(id->lm_owf), ps, depth);
675                 smb_io_owf_info("", &(id->nt_owf), ps, depth);
676
677                 smb_io_unistr2("unistr2", &(id->uni_domain_name), id->hdr_domain_name.buffer, ps, depth);
678                 smb_io_unistr2("unistr2", &(id->uni_user_name  ), id->hdr_user_name.buffer, ps, depth);
679                 smb_io_unistr2("unistr2", &(id->uni_wksta_name ), id->hdr_wksta_name.buffer, ps, depth);
680         }
681 }
682
683 /*******************************************************************
684 makes a NET_ID_INFO_2 structure.
685
686 This is a network logon packet. The log_id parameters
687 are what an NT server would generate for LUID once the
688 user is logged on. I don't think we care about them.
689
690 Note that this has no access to the NT and LM hashed passwords,
691 so it forwards the challenge, and the NT and LM responses (24
692 bytes each) over the secure channel to the Domain controller
693 for it to say yea or nay. This is the preferred method of 
694 checking for a logon as it doesn't export the password
695 hashes to anyone who has compromised the secure channel. JRA.
696 ********************************************************************/
697
698 void make_id_info2(NET_ID_INFO_2 *id, char *domain_name,
699                                 uint32 param_ctrl, uint32 log_id_low, uint32 log_id_high,
700                                 char *user_name, char *wksta_name,
701                                 unsigned char lm_challenge[8],
702                                 unsigned char lm_chal_resp[24],
703                                 unsigned char nt_chal_resp[24])
704 {
705         int len_domain_name = strlen(domain_name);
706         int len_user_name   = strlen(user_name  );
707         int len_wksta_name  = strlen(wksta_name );
708
709         unsigned char lm_owf[24];
710         unsigned char nt_owf[24];
711
712         if (id == NULL) return;
713
714         DEBUG(5,("make_id_info2: %d\n", __LINE__));
715
716         id->ptr_id_info2 = 1;
717
718         make_uni_hdr(&(id->hdr_domain_name), len_domain_name, len_domain_name, 4);
719
720         id->param_ctrl = param_ctrl;
721         make_logon_id(&(id->logon_id), log_id_low, log_id_high);
722
723         make_uni_hdr(&(id->hdr_user_name  ), len_user_name  , len_user_name  , 4);
724         make_uni_hdr(&(id->hdr_wksta_name ), len_wksta_name , len_wksta_name , 4);
725
726         if (nt_chal_resp)
727         {
728                 /* oops.  can only send what-ever-it-is direct */
729                 memcpy(nt_owf, nt_chal_resp, 24);
730                 nt_chal_resp = nt_owf;
731         }
732         if (lm_chal_resp)
733         {
734                 /* oops.  can only send what-ever-it-is direct */
735                 memcpy(lm_owf, lm_chal_resp, 24);
736                 lm_chal_resp = lm_owf;
737         }
738
739         memcpy(id->lm_chal, lm_challenge, sizeof(id->lm_chal));
740         make_str_hdr(&(id->hdr_nt_chal_resp), 24, 24, nt_chal_resp != NULL ? 1 : 0);
741         make_str_hdr(&(id->hdr_lm_chal_resp), 24, 24, lm_chal_resp != NULL ? 1 : 0);
742
743         make_unistr2(&(id->uni_domain_name), domain_name, len_domain_name);
744         make_unistr2(&(id->uni_user_name  ), user_name  , len_user_name  );
745         make_unistr2(&(id->uni_wksta_name ), wksta_name , len_wksta_name );
746
747         make_string2(&(id->nt_chal_resp ), (char *)nt_chal_resp , nt_chal_resp != NULL ? 24 : 0);
748         make_string2(&(id->lm_chal_resp ), (char *)lm_chal_resp , lm_chal_resp != NULL ? 24 : 0);
749 }
750
751 /*******************************************************************
752 reads or writes an NET_ID_INFO_2 structure.
753 ********************************************************************/
754 void net_io_id_info2(char *desc,  NET_ID_INFO_2 *id, prs_struct *ps, int depth)
755 {
756         if (id == NULL) return;
757
758         prs_debug(ps, depth, desc, "net_io_id_info2");
759         depth++;
760
761         prs_align(ps);
762         
763         prs_uint32("ptr_id_info2", ps, depth, &(id->ptr_id_info2));
764
765         if (id->ptr_id_info2 != 0)
766         {
767                 smb_io_unihdr("unihdr", &(id->hdr_domain_name), ps, depth);
768
769                 prs_uint32("param_ctrl", ps, depth, &(id->param_ctrl));
770                 smb_io_logon_id("", &(id->logon_id), ps, depth);
771
772                 smb_io_unihdr("unihdr", &(id->hdr_user_name  ), ps, depth);
773                 smb_io_unihdr("unihdr", &(id->hdr_wksta_name ), ps, depth);
774
775                 prs_uint8s (False, "lm_chal", ps, depth, id->lm_chal, 8); /* lm 8 byte challenge */
776
777                 smb_io_strhdr("hdr_nt_chal_resp", &(id->hdr_nt_chal_resp ), ps, depth);
778                 smb_io_strhdr("hdr_lm_chal_resp", &(id->hdr_lm_chal_resp ), ps, depth);
779
780                 smb_io_unistr2("uni_domain_name", &(id->uni_domain_name), id->hdr_domain_name .buffer, ps, depth);
781                 smb_io_unistr2("uni_user_name  ", &(id->uni_user_name  ), id->hdr_user_name   .buffer, ps, depth);
782                 smb_io_unistr2("uni_wksta_name ", &(id->uni_wksta_name ), id->hdr_wksta_name  .buffer, ps, depth);
783                 smb_io_string2("nt_chal_resp"   , &(id->nt_chal_resp)   , id->hdr_nt_chal_resp.buffer, ps, depth);
784                 smb_io_string2("lm_chal_resp"   , &(id->lm_chal_resp)   , id->hdr_lm_chal_resp.buffer, ps, depth);
785         }
786 }
787
788
789 /*******************************************************************
790 makes a DOM_SAM_INFO structure.
791 ********************************************************************/
792 void make_sam_info(DOM_SAM_INFO *sam,
793                                 char *logon_srv, char *comp_name, DOM_CRED *clnt_cred,
794                                 DOM_CRED *rtn_cred, uint16 logon_level,
795                                 NET_ID_INFO_CTR *ctr, uint16 validation_level)
796 {
797         if (sam == NULL) return;
798
799         DEBUG(5,("make_sam_info: %d\n", __LINE__));
800
801         make_clnt_info2(&(sam->client), logon_srv, comp_name, clnt_cred);
802
803         if (rtn_cred != NULL)
804         {
805                 sam->ptr_rtn_cred = 1;
806                 memcpy(&(sam->rtn_cred), rtn_cred, sizeof(sam->rtn_cred));
807         }
808         else
809         {
810                 sam->ptr_rtn_cred = 0;
811         }
812
813         sam->logon_level  = logon_level;
814         sam->ctr          = ctr;
815         sam->validation_level = validation_level;
816 }
817
818 /*******************************************************************
819 reads or writes a DOM_SAM_INFO structure.
820 ********************************************************************/
821 void net_io_id_info_ctr(char *desc,  NET_ID_INFO_CTR *ctr, prs_struct *ps, int depth)
822 {
823         if (ctr == NULL) return;
824
825         prs_debug(ps, depth, desc, "smb_io_sam_info");
826         depth++;
827
828         /* don't 4-byte align here! */
829
830         prs_uint16("switch_value ", ps, depth, &(ctr->switch_value));
831
832         switch (ctr->switch_value)
833         {
834                 case 1:
835                 {
836                         net_io_id_info1("", &(ctr->auth.id1), ps, depth);
837                         break;
838                 }
839                 case 2:
840                 {
841                         net_io_id_info2("", &(ctr->auth.id2), ps, depth);
842                         break;
843                 }
844                 default:
845                 {
846                         /* PANIC! */
847                         DEBUG(4,("smb_io_sam_info: unknown switch_value!\n"));
848                         break;
849                 }
850         }
851 }
852
853 /*******************************************************************
854 reads or writes a DOM_SAM_INFO structure.
855 ********************************************************************/
856 void smb_io_sam_info(char *desc,  DOM_SAM_INFO *sam, prs_struct *ps, int depth)
857 {
858         if (sam == NULL) return;
859
860         prs_debug(ps, depth, desc, "smb_io_sam_info");
861         depth++;
862
863         prs_align(ps);
864         
865         smb_io_clnt_info2("", &(sam->client  ), ps, depth);
866
867         prs_uint32("ptr_rtn_cred ", ps, depth, &(sam->ptr_rtn_cred));
868         smb_io_cred      ("", &(sam->rtn_cred), ps, depth);
869
870         prs_uint16("logon_level  ", ps, depth, &(sam->logon_level ));
871
872         if (sam->logon_level != 0 && sam->ctr != NULL)
873         {
874                 net_io_id_info_ctr("logon_info", sam->ctr, ps, depth);
875         }
876
877         prs_uint16("validation_level", ps, depth, &(sam->validation_level));
878 }
879
880 /*************************************************************************
881  make_net_user_info3
882  *************************************************************************/
883 void make_net_user_info3(NET_USER_INFO_3 *usr,
884
885         NTTIME *logon_time,
886         NTTIME *logoff_time,
887         NTTIME *kickoff_time,
888         NTTIME *pass_last_set_time,
889         NTTIME *pass_can_change_time,
890         NTTIME *pass_must_change_time,
891
892         char *user_name,
893         char *full_name,
894         char *logon_script,
895         char *profile_path,
896         char *home_dir,
897         char *dir_drive,
898
899         uint16 logon_count,
900         uint16 bad_pw_count,
901
902         uint32 user_id,
903         uint32 group_id,
904         uint32 num_groups,
905         DOM_GID *gids,
906         uint32 user_flgs,
907
908         char sess_key[16],
909
910         char *logon_srv,
911         char *logon_dom,
912
913         DOM_SID *dom_sid,
914         char *other_sids)
915 {
916         /* only cope with one "other" sid, right now. */
917         /* need to count the number of space-delimited sids */
918         int i;
919         int num_other_sids = 0;
920
921         int len_user_name    = strlen(user_name   );
922         int len_full_name    = strlen(full_name   );
923         int len_logon_script = strlen(logon_script);
924         int len_profile_path = strlen(profile_path);
925         int len_home_dir     = strlen(home_dir    );
926         int len_dir_drive    = strlen(dir_drive   );
927
928         int len_logon_srv    = strlen(logon_srv);
929         int len_logon_dom    = strlen(logon_dom);
930
931         usr->ptr_user_info = 1; /* yes, we're bothering to put USER_INFO data here */
932
933         usr->logon_time            = *logon_time;
934         usr->logoff_time           = *logoff_time;
935         usr->kickoff_time          = *kickoff_time;
936         usr->pass_last_set_time    = *pass_last_set_time;
937         usr->pass_can_change_time  = *pass_can_change_time;
938         usr->pass_must_change_time = *pass_must_change_time;
939
940         make_uni_hdr(&(usr->hdr_user_name   ), len_user_name   , len_user_name   , 4);
941         make_uni_hdr(&(usr->hdr_full_name   ), len_full_name   , len_full_name   , 4);
942         make_uni_hdr(&(usr->hdr_logon_script), len_logon_script, len_logon_script, 4);
943         make_uni_hdr(&(usr->hdr_profile_path), len_profile_path, len_profile_path, 4);
944         make_uni_hdr(&(usr->hdr_home_dir    ), len_home_dir    , len_home_dir    , 4);
945         make_uni_hdr(&(usr->hdr_dir_drive   ), len_dir_drive   , len_dir_drive   , 4);
946
947         usr->logon_count = logon_count;
948         usr->bad_pw_count = bad_pw_count;
949
950         usr->user_id = user_id;
951         usr->group_id = group_id;
952         usr->num_groups = num_groups;
953         usr->buffer_groups = 1; /* indicates fill in groups, below, even if there are none */
954         usr->user_flgs = user_flgs;
955
956         if (sess_key != NULL)
957         {
958                 memcpy(usr->user_sess_key, sess_key, sizeof(usr->user_sess_key));
959         }
960         else
961         {
962                 bzero(usr->user_sess_key, sizeof(usr->user_sess_key));
963         }
964
965         make_uni_hdr(&(usr->hdr_logon_srv), len_logon_srv, len_logon_srv, 4);
966         make_uni_hdr(&(usr->hdr_logon_dom), len_logon_dom, len_logon_dom, 4);
967
968         usr->buffer_dom_id = dom_sid ? 1 : 0; /* yes, we're bothering to put a domain SID in */
969
970         bzero(usr->padding, sizeof(usr->padding));
971
972         num_other_sids = make_dom_sid2s(other_sids, usr->other_sids, LSA_MAX_SIDS);
973
974         usr->num_other_sids = num_other_sids;
975         usr->buffer_other_sids = num_other_sids != 0 ? 1 : 0; 
976         
977         make_unistr2(&(usr->uni_user_name   ), user_name   , len_user_name   );
978         make_unistr2(&(usr->uni_full_name   ), full_name   , len_full_name   );
979         make_unistr2(&(usr->uni_logon_script), logon_script, len_logon_script);
980         make_unistr2(&(usr->uni_profile_path), profile_path, len_profile_path);
981         make_unistr2(&(usr->uni_home_dir    ), home_dir    , len_home_dir    );
982         make_unistr2(&(usr->uni_dir_drive   ), dir_drive   , len_dir_drive   );
983
984         usr->num_groups2 = num_groups;
985         for (i = 0; i < num_groups; i++)
986         {
987                 usr->gids[i] = gids[i];
988         }
989
990         make_unistr2(&(usr->uni_logon_srv), logon_srv, len_logon_srv);
991         make_unistr2(&(usr->uni_logon_dom), logon_dom, len_logon_dom);
992
993         make_dom_sid2(&(usr->dom_sid), dom_sid);
994         /* "other" sids are set up above */
995 }
996
997
998 /*******************************************************************
999 reads or writes a structure.
1000 ********************************************************************/
1001 void net_io_user_info3(char *desc,  NET_USER_INFO_3 *usr, prs_struct *ps, int depth)
1002 {
1003         int i;
1004
1005         if (usr == NULL) return;
1006
1007         prs_debug(ps, depth, desc, "lsa_io_lsa_user_info");
1008         depth++;
1009
1010         prs_align(ps);
1011         
1012         prs_uint32("ptr_user_info ", ps, depth, &(usr->ptr_user_info));
1013
1014         if (usr->ptr_user_info != 0)
1015         {
1016                 smb_io_time("time", &(usr->logon_time)           , ps, depth); /* logon time */
1017                 smb_io_time("time", &(usr->logoff_time)          , ps, depth); /* logoff time */
1018                 smb_io_time("time", &(usr->kickoff_time)         , ps, depth); /* kickoff time */
1019                 smb_io_time("time", &(usr->pass_last_set_time)   , ps, depth); /* password last set time */
1020                 smb_io_time("time", &(usr->pass_can_change_time) , ps, depth); /* password can change time */
1021                 smb_io_time("time", &(usr->pass_must_change_time), ps, depth); /* password must change time */
1022
1023                 smb_io_unihdr("unihdr", &(usr->hdr_user_name)   , ps, depth); /* username unicode string header */
1024                 smb_io_unihdr("unihdr", &(usr->hdr_full_name)   , ps, depth); /* user's full name unicode string header */
1025                 smb_io_unihdr("unihdr", &(usr->hdr_logon_script), ps, depth); /* logon script unicode string header */
1026                 smb_io_unihdr("unihdr", &(usr->hdr_profile_path), ps, depth); /* profile path unicode string header */
1027                 smb_io_unihdr("unihdr", &(usr->hdr_home_dir)    , ps, depth); /* home directory unicode string header */
1028                 smb_io_unihdr("unihdr", &(usr->hdr_dir_drive)   , ps, depth); /* home directory drive unicode string header */
1029
1030                 prs_uint16("logon_count   ", ps, depth, &(usr->logon_count ));  /* logon count */
1031                 prs_uint16("bad_pw_count  ", ps, depth, &(usr->bad_pw_count)); /* bad password count */
1032
1033                 prs_uint32("user_id       ", ps, depth, &(usr->user_id      ));       /* User ID */
1034                 prs_uint32("group_id      ", ps, depth, &(usr->group_id     ));      /* Group ID */
1035                 prs_uint32("num_groups    ", ps, depth, &(usr->num_groups   ));    /* num groups */
1036                 prs_uint32("buffer_groups ", ps, depth, &(usr->buffer_groups)); /* undocumented buffer pointer to groups. */
1037                 prs_uint32("user_flgs     ", ps, depth, &(usr->user_flgs    ));     /* user flags */
1038
1039                 prs_uint8s (False, "user_sess_key", ps, depth, usr->user_sess_key, 16); /* unused user session key */
1040
1041                 smb_io_unihdr("unihdr", &(usr->hdr_logon_srv), ps, depth); /* logon server unicode string header */
1042                 smb_io_unihdr("unihdr", &(usr->hdr_logon_dom), ps, depth); /* logon domain unicode string header */
1043
1044                 prs_uint32("buffer_dom_id ", ps, depth, &(usr->buffer_dom_id)); /* undocumented logon domain id pointer */
1045                 prs_uint8s (False, "padding       ", ps, depth, usr->padding, 40); /* unused padding bytes? */
1046
1047                 prs_uint32("num_other_sids", ps, depth, &(usr->num_other_sids)); /* 0 - num_sids */
1048                 prs_uint32("buffer_other_sids", ps, depth, &(usr->buffer_other_sids)); /* NULL - undocumented pointer to SIDs. */
1049                 
1050                 smb_io_unistr2("unistr2", &(usr->uni_user_name)   , usr->hdr_user_name   .buffer, ps, depth); /* username unicode string */
1051                 smb_io_unistr2("unistr2", &(usr->uni_full_name)   , usr->hdr_full_name   .buffer, ps, depth); /* user's full name unicode string */
1052                 smb_io_unistr2("unistr2", &(usr->uni_logon_script), usr->hdr_logon_script.buffer, ps, depth); /* logon script unicode string */
1053                 smb_io_unistr2("unistr2", &(usr->uni_profile_path), usr->hdr_profile_path.buffer, ps, depth); /* profile path unicode string */
1054                 smb_io_unistr2("unistr2", &(usr->uni_home_dir)    , usr->hdr_home_dir    .buffer, ps, depth); /* home directory unicode string */
1055                 smb_io_unistr2("unistr2", &(usr->uni_dir_drive)   , usr->hdr_dir_drive   .buffer, ps, depth); /* home directory drive unicode string */
1056
1057                 prs_align(ps);
1058                 prs_uint32("num_groups2   ", ps, depth, &(usr->num_groups2));        /* num groups */
1059                 for (i = 0; i < usr->num_groups2; i++)
1060                 {
1061                         smb_io_gid("", &(usr->gids[i]), ps, depth); /* group info */
1062                 }
1063
1064                 smb_io_unistr2("unistr2", &( usr->uni_logon_srv), usr->hdr_logon_srv.buffer, ps, depth); /* logon server unicode string */
1065                 smb_io_unistr2("unistr2", &( usr->uni_logon_dom), usr->hdr_logon_srv.buffer, ps, depth); /* logon domain unicode string */
1066
1067                 smb_io_dom_sid2("", &(usr->dom_sid), ps, depth);           /* domain SID */
1068
1069                 for (i = 0; i < usr->num_other_sids; i++)
1070                 {
1071                         smb_io_dom_sid2("", &(usr->other_sids[i]), ps, depth); /* other domain SIDs */
1072                 }
1073         }
1074 }
1075
1076 /*******************************************************************
1077 reads or writes a structure.
1078 ********************************************************************/
1079 void net_io_q_sam_logon(char *desc,  NET_Q_SAM_LOGON *q_l, prs_struct *ps, int depth)
1080 {
1081         if (q_l == NULL) return;
1082
1083         prs_debug(ps, depth, desc, "net_io_q_sam_logon");
1084         depth++;
1085
1086         prs_align(ps);
1087         
1088         smb_io_sam_info("", &(q_l->sam_id), ps, depth);           /* domain SID */
1089 }
1090
1091 /*******************************************************************
1092 reads or writes a structure.
1093 ********************************************************************/
1094 void net_io_r_sam_logon(char *desc,  NET_R_SAM_LOGON *r_l, prs_struct *ps, int depth)
1095 {
1096         if (r_l == NULL) return;
1097
1098         prs_debug(ps, depth, desc, "net_io_r_sam_logon");
1099         depth++;
1100
1101         prs_uint32("buffer_creds", ps, depth, &(r_l->buffer_creds)); /* undocumented buffer pointer */
1102         smb_io_cred("", &(r_l->srv_creds), ps, depth); /* server credentials.  server time stamp appears to be ignored. */
1103
1104         prs_uint16("switch_value", ps, depth, &(r_l->switch_value));
1105         prs_align(ps);
1106
1107         if (r_l->switch_value != 0)
1108         {
1109                 net_io_user_info3("", r_l->user, ps, depth);
1110         }
1111
1112         prs_uint32("auth_resp   ", ps, depth, &(r_l->auth_resp)); /* 1 - Authoritative response; 0 - Non-Auth? */
1113
1114         prs_uint32("status      ", ps, depth, &(r_l->status));
1115
1116         prs_align(ps);
1117 }
1118
1119 /*******************************************************************
1120 reads or writes a structure.
1121 ********************************************************************/
1122 void net_io_q_sam_logoff(char *desc,  NET_Q_SAM_LOGOFF *q_l, prs_struct *ps, int depth)
1123 {
1124         if (q_l == NULL) return;
1125
1126         prs_debug(ps, depth, desc, "net_io_q_sam_logoff");
1127         depth++;
1128
1129         prs_align(ps);
1130         
1131         smb_io_sam_info("", &(q_l->sam_id), ps, depth);           /* domain SID */
1132 }
1133
1134 /*******************************************************************
1135 reads or writes a structure.
1136 ********************************************************************/
1137 void net_io_r_sam_logoff(char *desc,  NET_R_SAM_LOGOFF *r_l, prs_struct *ps, int depth)
1138 {
1139         if (r_l == NULL) return;
1140
1141         prs_debug(ps, depth, desc, "net_io_r_sam_logoff");
1142         depth++;
1143
1144         prs_align(ps);
1145         
1146         prs_uint32("buffer_creds", ps, depth, &(r_l->buffer_creds)); /* undocumented buffer pointer */
1147         smb_io_cred("", &(r_l->srv_creds), ps, depth); /* server credentials.  server time stamp appears to be ignored. */
1148
1149         prs_uint32("status      ", ps, depth, &(r_l->status));
1150 }
1151
1152