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