password.c: Fixes to allow Win95 clients to have lm encrypted passwords
[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     int nt_chal_resp_len = ((nt_chal_resp != NULL) ? 24 : 0);
709     int lm_chal_resp_len = ((lm_chal_resp != NULL) ? 24 : 0);
710         unsigned char lm_owf[24];
711         unsigned char nt_owf[24];
712
713         if (id == NULL) return;
714
715         DEBUG(5,("make_id_info2: %d\n", __LINE__));
716
717         id->ptr_id_info2 = 1;
718
719         make_uni_hdr(&(id->hdr_domain_name), len_domain_name, len_domain_name, 4);
720
721         id->param_ctrl = param_ctrl;
722         make_logon_id(&(id->logon_id), log_id_low, log_id_high);
723
724         make_uni_hdr(&(id->hdr_user_name  ), len_user_name  , len_user_name  , 4);
725         make_uni_hdr(&(id->hdr_wksta_name ), len_wksta_name , len_wksta_name , 4);
726
727         if (nt_chal_resp)
728         {
729                 /* oops.  can only send what-ever-it-is direct */
730                 memcpy(nt_owf, nt_chal_resp, 24);
731                 nt_chal_resp = nt_owf;
732         }
733         if (lm_chal_resp)
734         {
735                 /* oops.  can only send what-ever-it-is direct */
736                 memcpy(lm_owf, lm_chal_resp, 24);
737                 lm_chal_resp = lm_owf;
738         }
739
740         memcpy(id->lm_chal, lm_challenge, sizeof(id->lm_chal));
741         make_str_hdr(&(id->hdr_nt_chal_resp), 24, nt_chal_resp_len, nt_chal_resp != NULL ? 1 : 0);
742         make_str_hdr(&(id->hdr_lm_chal_resp), 24, lm_chal_resp_len, lm_chal_resp != NULL ? 1 : 0);
743
744         make_unistr2(&(id->uni_domain_name), domain_name, len_domain_name);
745         make_unistr2(&(id->uni_user_name  ), user_name  , len_user_name  );
746         make_unistr2(&(id->uni_wksta_name ), wksta_name , len_wksta_name );
747
748         make_string2(&(id->nt_chal_resp ), (char *)nt_chal_resp , nt_chal_resp_len);
749         make_string2(&(id->lm_chal_resp ), (char *)lm_chal_resp , lm_chal_resp_len);
750 }
751
752 /*******************************************************************
753 reads or writes an NET_ID_INFO_2 structure.
754 ********************************************************************/
755 void net_io_id_info2(char *desc,  NET_ID_INFO_2 *id, prs_struct *ps, int depth)
756 {
757         if (id == NULL) return;
758
759         prs_debug(ps, depth, desc, "net_io_id_info2");
760         depth++;
761
762         prs_align(ps);
763         
764         prs_uint32("ptr_id_info2", ps, depth, &(id->ptr_id_info2));
765
766         if (id->ptr_id_info2 != 0)
767         {
768                 smb_io_unihdr("unihdr", &(id->hdr_domain_name), ps, depth);
769
770                 prs_uint32("param_ctrl", ps, depth, &(id->param_ctrl));
771                 smb_io_logon_id("", &(id->logon_id), ps, depth);
772
773                 smb_io_unihdr("unihdr", &(id->hdr_user_name  ), ps, depth);
774                 smb_io_unihdr("unihdr", &(id->hdr_wksta_name ), ps, depth);
775
776                 prs_uint8s (False, "lm_chal", ps, depth, id->lm_chal, 8); /* lm 8 byte challenge */
777
778                 smb_io_strhdr("hdr_nt_chal_resp", &(id->hdr_nt_chal_resp ), ps, depth);
779                 smb_io_strhdr("hdr_lm_chal_resp", &(id->hdr_lm_chal_resp ), ps, depth);
780
781                 smb_io_unistr2("uni_domain_name", &(id->uni_domain_name), id->hdr_domain_name .buffer, ps, depth);
782                 smb_io_unistr2("uni_user_name  ", &(id->uni_user_name  ), id->hdr_user_name   .buffer, ps, depth);
783                 smb_io_unistr2("uni_wksta_name ", &(id->uni_wksta_name ), id->hdr_wksta_name  .buffer, ps, depth);
784                 smb_io_string2("nt_chal_resp"   , &(id->nt_chal_resp)   , id->hdr_nt_chal_resp.buffer, ps, depth);
785                 smb_io_string2("lm_chal_resp"   , &(id->lm_chal_resp)   , id->hdr_lm_chal_resp.buffer, ps, depth);
786         }
787 }
788
789
790 /*******************************************************************
791 makes a DOM_SAM_INFO structure.
792 ********************************************************************/
793 void make_sam_info(DOM_SAM_INFO *sam,
794                                 char *logon_srv, char *comp_name, DOM_CRED *clnt_cred,
795                                 DOM_CRED *rtn_cred, uint16 logon_level,
796                                 NET_ID_INFO_CTR *ctr, uint16 validation_level)
797 {
798         if (sam == NULL) return;
799
800         DEBUG(5,("make_sam_info: %d\n", __LINE__));
801
802         make_clnt_info2(&(sam->client), logon_srv, comp_name, clnt_cred);
803
804         if (rtn_cred != NULL)
805         {
806                 sam->ptr_rtn_cred = 1;
807                 memcpy(&(sam->rtn_cred), rtn_cred, sizeof(sam->rtn_cred));
808         }
809         else
810         {
811                 sam->ptr_rtn_cred = 0;
812         }
813
814         sam->logon_level  = logon_level;
815         sam->ctr          = ctr;
816         sam->validation_level = validation_level;
817 }
818
819 /*******************************************************************
820 reads or writes a DOM_SAM_INFO structure.
821 ********************************************************************/
822 void net_io_id_info_ctr(char *desc,  NET_ID_INFO_CTR *ctr, prs_struct *ps, int depth)
823 {
824         if (ctr == NULL) return;
825
826         prs_debug(ps, depth, desc, "smb_io_sam_info");
827         depth++;
828
829         /* don't 4-byte align here! */
830
831         prs_uint16("switch_value ", ps, depth, &(ctr->switch_value));
832
833         switch (ctr->switch_value)
834         {
835                 case 1:
836                 {
837                         net_io_id_info1("", &(ctr->auth.id1), ps, depth);
838                         break;
839                 }
840                 case 2:
841                 {
842                         net_io_id_info2("", &(ctr->auth.id2), ps, depth);
843                         break;
844                 }
845                 default:
846                 {
847                         /* PANIC! */
848                         DEBUG(4,("smb_io_sam_info: unknown switch_value!\n"));
849                         break;
850                 }
851         }
852 }
853
854 /*******************************************************************
855 reads or writes a DOM_SAM_INFO structure.
856 ********************************************************************/
857 void smb_io_sam_info(char *desc,  DOM_SAM_INFO *sam, prs_struct *ps, int depth)
858 {
859         if (sam == NULL) return;
860
861         prs_debug(ps, depth, desc, "smb_io_sam_info");
862         depth++;
863
864         prs_align(ps);
865         
866         smb_io_clnt_info2("", &(sam->client  ), ps, depth);
867
868         prs_uint32("ptr_rtn_cred ", ps, depth, &(sam->ptr_rtn_cred));
869         smb_io_cred      ("", &(sam->rtn_cred), ps, depth);
870
871         prs_uint16("logon_level  ", ps, depth, &(sam->logon_level ));
872
873         if (sam->logon_level != 0 && sam->ctr != NULL)
874         {
875                 net_io_id_info_ctr("logon_info", sam->ctr, ps, depth);
876         }
877
878         prs_uint16("validation_level", ps, depth, &(sam->validation_level));
879 }
880
881 /*************************************************************************
882  make_net_user_info3
883  *************************************************************************/
884 void make_net_user_info3(NET_USER_INFO_3 *usr,
885
886         NTTIME *logon_time,
887         NTTIME *logoff_time,
888         NTTIME *kickoff_time,
889         NTTIME *pass_last_set_time,
890         NTTIME *pass_can_change_time,
891         NTTIME *pass_must_change_time,
892
893         char *user_name,
894         char *full_name,
895         char *logon_script,
896         char *profile_path,
897         char *home_dir,
898         char *dir_drive,
899
900         uint16 logon_count,
901         uint16 bad_pw_count,
902
903         uint32 user_id,
904         uint32 group_id,
905         uint32 num_groups,
906         DOM_GID *gids,
907         uint32 user_flgs,
908
909         char sess_key[16],
910
911         char *logon_srv,
912         char *logon_dom,
913
914         DOM_SID *dom_sid,
915         char *other_sids)
916 {
917         /* only cope with one "other" sid, right now. */
918         /* need to count the number of space-delimited sids */
919         int i;
920         int num_other_sids = 0;
921
922         int len_user_name    = strlen(user_name   );
923         int len_full_name    = strlen(full_name   );
924         int len_logon_script = strlen(logon_script);
925         int len_profile_path = strlen(profile_path);
926         int len_home_dir     = strlen(home_dir    );
927         int len_dir_drive    = strlen(dir_drive   );
928
929         int len_logon_srv    = strlen(logon_srv);
930         int len_logon_dom    = strlen(logon_dom);
931
932         usr->ptr_user_info = 1; /* yes, we're bothering to put USER_INFO data here */
933
934         usr->logon_time            = *logon_time;
935         usr->logoff_time           = *logoff_time;
936         usr->kickoff_time          = *kickoff_time;
937         usr->pass_last_set_time    = *pass_last_set_time;
938         usr->pass_can_change_time  = *pass_can_change_time;
939         usr->pass_must_change_time = *pass_must_change_time;
940
941         make_uni_hdr(&(usr->hdr_user_name   ), len_user_name   , len_user_name   , 4);
942         make_uni_hdr(&(usr->hdr_full_name   ), len_full_name   , len_full_name   , 4);
943         make_uni_hdr(&(usr->hdr_logon_script), len_logon_script, len_logon_script, 4);
944         make_uni_hdr(&(usr->hdr_profile_path), len_profile_path, len_profile_path, 4);
945         make_uni_hdr(&(usr->hdr_home_dir    ), len_home_dir    , len_home_dir    , 4);
946         make_uni_hdr(&(usr->hdr_dir_drive   ), len_dir_drive   , len_dir_drive   , 4);
947
948         usr->logon_count = logon_count;
949         usr->bad_pw_count = bad_pw_count;
950
951         usr->user_id = user_id;
952         usr->group_id = group_id;
953         usr->num_groups = num_groups;
954         usr->buffer_groups = 1; /* indicates fill in groups, below, even if there are none */
955         usr->user_flgs = user_flgs;
956
957         if (sess_key != NULL)
958         {
959                 memcpy(usr->user_sess_key, sess_key, sizeof(usr->user_sess_key));
960         }
961         else
962         {
963                 bzero(usr->user_sess_key, sizeof(usr->user_sess_key));
964         }
965
966         make_uni_hdr(&(usr->hdr_logon_srv), len_logon_srv, len_logon_srv, 4);
967         make_uni_hdr(&(usr->hdr_logon_dom), len_logon_dom, len_logon_dom, 4);
968
969         usr->buffer_dom_id = dom_sid ? 1 : 0; /* yes, we're bothering to put a domain SID in */
970
971         bzero(usr->padding, sizeof(usr->padding));
972
973         num_other_sids = make_dom_sid2s(other_sids, usr->other_sids, LSA_MAX_SIDS);
974
975         usr->num_other_sids = num_other_sids;
976         usr->buffer_other_sids = num_other_sids != 0 ? 1 : 0; 
977         
978         make_unistr2(&(usr->uni_user_name   ), user_name   , len_user_name   );
979         make_unistr2(&(usr->uni_full_name   ), full_name   , len_full_name   );
980         make_unistr2(&(usr->uni_logon_script), logon_script, len_logon_script);
981         make_unistr2(&(usr->uni_profile_path), profile_path, len_profile_path);
982         make_unistr2(&(usr->uni_home_dir    ), home_dir    , len_home_dir    );
983         make_unistr2(&(usr->uni_dir_drive   ), dir_drive   , len_dir_drive   );
984
985         usr->num_groups2 = num_groups;
986         for (i = 0; i < num_groups; i++)
987         {
988                 usr->gids[i] = gids[i];
989         }
990
991         make_unistr2(&(usr->uni_logon_srv), logon_srv, len_logon_srv);
992         make_unistr2(&(usr->uni_logon_dom), logon_dom, len_logon_dom);
993
994         make_dom_sid2(&(usr->dom_sid), dom_sid);
995         /* "other" sids are set up above */
996 }
997
998
999 /*******************************************************************
1000 reads or writes a structure.
1001 ********************************************************************/
1002 void net_io_user_info3(char *desc,  NET_USER_INFO_3 *usr, prs_struct *ps, int depth)
1003 {
1004         int i;
1005
1006         if (usr == NULL) return;
1007
1008         prs_debug(ps, depth, desc, "lsa_io_lsa_user_info");
1009         depth++;
1010
1011         prs_align(ps);
1012         
1013         prs_uint32("ptr_user_info ", ps, depth, &(usr->ptr_user_info));
1014
1015         if (usr->ptr_user_info != 0)
1016         {
1017                 smb_io_time("time", &(usr->logon_time)           , ps, depth); /* logon time */
1018                 smb_io_time("time", &(usr->logoff_time)          , ps, depth); /* logoff time */
1019                 smb_io_time("time", &(usr->kickoff_time)         , ps, depth); /* kickoff time */
1020                 smb_io_time("time", &(usr->pass_last_set_time)   , ps, depth); /* password last set time */
1021                 smb_io_time("time", &(usr->pass_can_change_time) , ps, depth); /* password can change time */
1022                 smb_io_time("time", &(usr->pass_must_change_time), ps, depth); /* password must change time */
1023
1024                 smb_io_unihdr("unihdr", &(usr->hdr_user_name)   , ps, depth); /* username unicode string header */
1025                 smb_io_unihdr("unihdr", &(usr->hdr_full_name)   , ps, depth); /* user's full name unicode string header */
1026                 smb_io_unihdr("unihdr", &(usr->hdr_logon_script), ps, depth); /* logon script unicode string header */
1027                 smb_io_unihdr("unihdr", &(usr->hdr_profile_path), ps, depth); /* profile path unicode string header */
1028                 smb_io_unihdr("unihdr", &(usr->hdr_home_dir)    , ps, depth); /* home directory unicode string header */
1029                 smb_io_unihdr("unihdr", &(usr->hdr_dir_drive)   , ps, depth); /* home directory drive unicode string header */
1030
1031                 prs_uint16("logon_count   ", ps, depth, &(usr->logon_count ));  /* logon count */
1032                 prs_uint16("bad_pw_count  ", ps, depth, &(usr->bad_pw_count)); /* bad password count */
1033
1034                 prs_uint32("user_id       ", ps, depth, &(usr->user_id      ));       /* User ID */
1035                 prs_uint32("group_id      ", ps, depth, &(usr->group_id     ));      /* Group ID */
1036                 prs_uint32("num_groups    ", ps, depth, &(usr->num_groups   ));    /* num groups */
1037                 prs_uint32("buffer_groups ", ps, depth, &(usr->buffer_groups)); /* undocumented buffer pointer to groups. */
1038                 prs_uint32("user_flgs     ", ps, depth, &(usr->user_flgs    ));     /* user flags */
1039
1040                 prs_uint8s (False, "user_sess_key", ps, depth, usr->user_sess_key, 16); /* unused user session key */
1041
1042                 smb_io_unihdr("unihdr", &(usr->hdr_logon_srv), ps, depth); /* logon server unicode string header */
1043                 smb_io_unihdr("unihdr", &(usr->hdr_logon_dom), ps, depth); /* logon domain unicode string header */
1044
1045                 prs_uint32("buffer_dom_id ", ps, depth, &(usr->buffer_dom_id)); /* undocumented logon domain id pointer */
1046                 prs_uint8s (False, "padding       ", ps, depth, usr->padding, 40); /* unused padding bytes? */
1047
1048                 prs_uint32("num_other_sids", ps, depth, &(usr->num_other_sids)); /* 0 - num_sids */
1049                 prs_uint32("buffer_other_sids", ps, depth, &(usr->buffer_other_sids)); /* NULL - undocumented pointer to SIDs. */
1050                 
1051                 smb_io_unistr2("unistr2", &(usr->uni_user_name)   , usr->hdr_user_name   .buffer, ps, depth); /* username unicode string */
1052                 smb_io_unistr2("unistr2", &(usr->uni_full_name)   , usr->hdr_full_name   .buffer, ps, depth); /* user's full name unicode string */
1053                 smb_io_unistr2("unistr2", &(usr->uni_logon_script), usr->hdr_logon_script.buffer, ps, depth); /* logon script unicode string */
1054                 smb_io_unistr2("unistr2", &(usr->uni_profile_path), usr->hdr_profile_path.buffer, ps, depth); /* profile path unicode string */
1055                 smb_io_unistr2("unistr2", &(usr->uni_home_dir)    , usr->hdr_home_dir    .buffer, ps, depth); /* home directory unicode string */
1056                 smb_io_unistr2("unistr2", &(usr->uni_dir_drive)   , usr->hdr_dir_drive   .buffer, ps, depth); /* home directory drive unicode string */
1057
1058                 prs_align(ps);
1059                 prs_uint32("num_groups2   ", ps, depth, &(usr->num_groups2));        /* num groups */
1060                 for (i = 0; i < usr->num_groups2; i++)
1061                 {
1062                         smb_io_gid("", &(usr->gids[i]), ps, depth); /* group info */
1063                 }
1064
1065                 smb_io_unistr2("unistr2", &( usr->uni_logon_srv), usr->hdr_logon_srv.buffer, ps, depth); /* logon server unicode string */
1066                 smb_io_unistr2("unistr2", &( usr->uni_logon_dom), usr->hdr_logon_srv.buffer, ps, depth); /* logon domain unicode string */
1067
1068                 smb_io_dom_sid2("", &(usr->dom_sid), ps, depth);           /* domain SID */
1069
1070                 for (i = 0; i < usr->num_other_sids; i++)
1071                 {
1072                         smb_io_dom_sid2("", &(usr->other_sids[i]), ps, depth); /* other domain SIDs */
1073                 }
1074         }
1075 }
1076
1077 /*******************************************************************
1078 reads or writes a structure.
1079 ********************************************************************/
1080 void net_io_q_sam_logon(char *desc,  NET_Q_SAM_LOGON *q_l, prs_struct *ps, int depth)
1081 {
1082         if (q_l == NULL) return;
1083
1084         prs_debug(ps, depth, desc, "net_io_q_sam_logon");
1085         depth++;
1086
1087         prs_align(ps);
1088         
1089         smb_io_sam_info("", &(q_l->sam_id), ps, depth);           /* domain SID */
1090 }
1091
1092 /*******************************************************************
1093 reads or writes a structure.
1094 ********************************************************************/
1095 void net_io_r_sam_logon(char *desc,  NET_R_SAM_LOGON *r_l, prs_struct *ps, int depth)
1096 {
1097         if (r_l == NULL) return;
1098
1099         prs_debug(ps, depth, desc, "net_io_r_sam_logon");
1100         depth++;
1101
1102         prs_uint32("buffer_creds", ps, depth, &(r_l->buffer_creds)); /* undocumented buffer pointer */
1103         smb_io_cred("", &(r_l->srv_creds), ps, depth); /* server credentials.  server time stamp appears to be ignored. */
1104
1105         prs_uint16("switch_value", ps, depth, &(r_l->switch_value));
1106         prs_align(ps);
1107
1108         if (r_l->switch_value != 0)
1109         {
1110                 net_io_user_info3("", r_l->user, ps, depth);
1111         }
1112
1113         prs_uint32("auth_resp   ", ps, depth, &(r_l->auth_resp)); /* 1 - Authoritative response; 0 - Non-Auth? */
1114
1115         prs_uint32("status      ", ps, depth, &(r_l->status));
1116
1117         prs_align(ps);
1118 }
1119
1120 /*******************************************************************
1121 reads or writes a structure.
1122 ********************************************************************/
1123 void net_io_q_sam_logoff(char *desc,  NET_Q_SAM_LOGOFF *q_l, prs_struct *ps, int depth)
1124 {
1125         if (q_l == NULL) return;
1126
1127         prs_debug(ps, depth, desc, "net_io_q_sam_logoff");
1128         depth++;
1129
1130         prs_align(ps);
1131         
1132         smb_io_sam_info("", &(q_l->sam_id), ps, depth);           /* domain SID */
1133 }
1134
1135 /*******************************************************************
1136 reads or writes a structure.
1137 ********************************************************************/
1138 void net_io_r_sam_logoff(char *desc,  NET_R_SAM_LOGOFF *r_l, prs_struct *ps, int depth)
1139 {
1140         if (r_l == NULL) return;
1141
1142         prs_debug(ps, depth, desc, "net_io_r_sam_logoff");
1143         depth++;
1144
1145         prs_align(ps);
1146         
1147         prs_uint32("buffer_creds", ps, depth, &(r_l->buffer_creds)); /* undocumented buffer pointer */
1148         smb_io_cred("", &(r_l->srv_creds), ps, depth); /* server credentials.  server time stamp appears to be ignored. */
1149
1150         prs_uint32("status      ", ps, depth, &(r_l->status));
1151 }
1152
1153