added frag field to make_rpc_hdr() function
[Samba.git] / source / client / ntclient.c
blob71f38fcf598e82cf0c22d6ec50474b18753effbf
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 SMB client
5 Copyright (C) Andrew Tridgell 1994-1997
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #ifdef SYSLOG
23 #undef SYSLOG
24 #endif
26 #include "includes.h"
28 extern int DEBUGLEVEL;
29 extern pstring username;
30 extern pstring workgroup;
32 #define CLIENT_TIMEOUT (30*1000)
34 #ifdef NTDOMAIN
36 /****************************************************************************
37 open an rpc pipe (\NETLOGON or \srvsvc for example)
38 ****************************************************************************/
39 static uint16 open_rpc_pipe(char *inbuf, char *outbuf, char *rname, int Client, int cnum)
41 int fnum;
42 char *p;
44 DEBUG(5,("open_rpc_pipe: %s\n", rname));
46 bzero(outbuf,smb_size);
47 set_message(outbuf,15,1 + strlen(rname),True);
49 CVAL(outbuf,smb_com) = SMBopenX;
50 SSVAL(outbuf,smb_tid, cnum);
51 cli_setup_pkt(outbuf);
53 SSVAL(outbuf,smb_vwv0,0xFF);
54 SSVAL(outbuf,smb_vwv2,1);
55 SSVAL(outbuf,smb_vwv3,(DENY_NONE<<4));
56 SSVAL(outbuf,smb_vwv4,aSYSTEM | aHIDDEN);
57 SSVAL(outbuf,smb_vwv5,aSYSTEM | aHIDDEN);
58 SSVAL(outbuf,smb_vwv8,1);
60 p = smb_buf(outbuf);
61 strcpy(p,rname);
62 p = skip_string(p,1);
64 send_smb(Client,outbuf);
65 receive_smb(Client,inbuf,CLIENT_TIMEOUT);
67 if (CVAL(inbuf,smb_rcls) != 0)
69 if (CVAL(inbuf,smb_rcls) == ERRSRV &&
70 SVAL(inbuf,smb_err) == ERRnoresource &&
71 cli_reopen_connection(inbuf,outbuf))
73 return open_rpc_pipe(inbuf, outbuf, rname, Client, cnum);
75 DEBUG(0,("opening remote pipe %s - error %s\n", rname, smb_errstr(inbuf)));
77 return 0xffff;
80 fnum = SVAL(inbuf, smb_vwv2);
82 DEBUG(5,("opening pipe: fnum %d\n", fnum));
84 return fnum;
87 /****************************************************************************
88 do an rpc bind
89 ****************************************************************************/
90 static BOOL do_rpc_bind(uint16 fnum)
92 char *rparam = NULL;
93 char *rdata = NULL;
94 char *p;
95 int rdrcnt,rprcnt;
96 int data_len;
97 pstring data; /* only 1024 bytes */
98 uint16 setup[2]; /* only need 2 uint16 setup parameters */
100 RPC_HDR hdr;
102 RPC_HDR_RB hdr_rb;
103 RPC_IFACE abstract;
104 RPC_IFACE transfer;
106 BOOL valid_ack = False;
107 int call_id = 0x1;
108 int i;
110 static char abs_data[16];
111 static char trn_data[16];
113 /* create and send a MSRPC command with api LSA_OPENPOLICY */
115 DEBUG(4,("LSA RPC Bind[%d]\n", fnum));
117 for (i = 0; i < sizeof(trn_data); i++)
119 trn_data[i] = 2 * i;
122 for (i = 0; i < sizeof(abs_data); i++)
124 abs_data[i] = i;
127 /* create interface UUIDs. */
128 make_rpc_iface(&abstract, abs_data, 0x0);
129 make_rpc_iface(&transfer, trn_data, 0x2);
131 /* create the request RPC_HDR_RB */
132 make_rpc_hdr_rb(&hdr_rb,
133 0x1630, 0x1630, 0x0,
134 0x1, 0x1, 0x1,
135 &abstract, &transfer);
137 /* stream the bind request data */
138 p = smb_io_rpc_hdr_rb(False, &hdr_rb, data + 0x10, data, 4, 0);
140 data_len = PTR_DIFF(p, data);
142 /* create the request RPC_HDR */
143 make_rpc_hdr(&hdr, RPC_BIND, 0x0, call_id, PTR_DIFF(p, data + 0x10));
145 /* stream the header into data */
146 p = smb_io_rpc_hdr(False, &hdr, data, data, 4, 0);
148 /* create setup parameters. */
149 setup[0] = 0x0026; /* 0x26 indicates "transact named pipe" */
150 setup[1] = fnum; /* file handle, from the SMBcreateX pipe, earlier */
152 /* send the data on \PIPE\ */
153 if (cli_call_api("\\PIPE\\", 0, data_len, 2, 1024,
154 BUFFER_SIZE,
155 &rprcnt, &rdrcnt,
156 NULL, data, setup,
157 &rparam, &rdata))
159 RPC_HDR_BA hdr_ba;
160 int hdr_len;
161 int pkt_len;
163 DEBUG(5, ("cli_call_api: return OK\n"));
165 p = rdata;
167 if (p) p = smb_io_rpc_hdr(True, &hdr, p, rdata, 4, 0);
168 if (p) p = align_offset(p, rdata, 4); /* oh, what a surprise */
170 hdr_len = PTR_DIFF(p, rdata);
172 if (p) p = smb_io_rpc_hdr_ba(True, &hdr_ba, p, rdata, 4, 0);
174 pkt_len = PTR_DIFF(p, rdata);
175 #if 0
176 if (p && hdr_len != hdr.hdr.frag_len - hdr.alloc_hint)
178 /* header length not same as calculated header length */
179 DEBUG(2,("do_lsa_open_policy: hdr_len %x != frag_len-alloc_hint %x\n",
180 hdr_len, hdr.hdr.frag_len - hdr.alloc_hint));
181 p = NULL;
185 if (p && pkt_len != hdr.hdr.frag_len)
187 /* packet data size not same as reported fragment length */
188 DEBUG(2,("do_lsa_open_policy: pkt_len %x != frag_len \n",
189 pkt_len, hdr.hdr.frag_len));
190 p = NULL;
192 if (p && r_o.status != 0)
194 /* report error code */
195 DEBUG(0,("LSA_OPENPOLICY: nt_status error %lx\n", r_o.status));
196 p = NULL;
198 #endif
199 if (p)
201 /* ok, at last: we're happy. */
202 valid_ack = True;
206 if (rparam) free(rparam);
207 if (rdata) free(rdata);
209 return valid_ack;
212 /****************************************************************************
213 do a LSA Open Policy
214 ****************************************************************************/
215 static BOOL do_lsa_open_policy(uint16 fnum, char *server_name, LSA_POL_HND *hnd)
217 char *rparam = NULL;
218 char *rdata = NULL;
219 char *p;
220 int rdrcnt,rprcnt;
221 pstring data; /* only 1024 bytes */
222 uint16 setup[2]; /* only need 2 uint16 setup parameters */
223 LSA_Q_OPEN_POL q_o;
224 int call_id = 0x1;
225 BOOL valid_pol = False;
227 if (hnd == NULL) return False;
229 /* create and send a MSRPC command with api LSA_OPENPOLICY */
231 DEBUG(4,("LSA Open Policy\n"));
233 /* store the parameters */
234 make_q_open_pol(&q_o, server_name, 0, 0, 0x1);
236 /* turn parameters into data stream */
237 p = lsa_io_q_open_pol(False, &q_o, data + 0x18, data, 4, 0);
239 /* create the request RPC_HDR_RR with no data */
240 create_rpc_request(call_id, LSA_OPENPOLICY, data, PTR_DIFF(p, data));
242 /* create setup parameters. */
243 setup[0] = 0x0026; /* 0x26 indicates "transact named pipe" */
244 setup[1] = fnum; /* file handle, from the SMBcreateX pipe, earlier */
246 /* send the data on \PIPE\ */
247 if (cli_call_api("\\PIPE\\", 0, PTR_DIFF(p, data), 2, 1024,
248 BUFFER_SIZE,
249 &rprcnt, &rdrcnt,
250 NULL, data, setup,
251 &rparam, &rdata))
253 LSA_R_OPEN_POL r_o;
254 RPC_HDR_RR hdr;
255 int hdr_len;
256 int pkt_len;
258 DEBUG(5, ("cli_call_api: return OK\n"));
260 p = rdata;
262 if (p) p = smb_io_rpc_hdr_rr (True, &hdr, p, rdata, 4, 0);
263 if (p) p = align_offset(p, rdata, 4); /* oh, what a surprise */
265 hdr_len = PTR_DIFF(p, rdata);
267 if (p && hdr_len != hdr.hdr.frag_len - hdr.alloc_hint)
269 /* header length not same as calculated header length */
270 DEBUG(2,("do_lsa_open_policy: hdr_len %x != frag_len-alloc_hint %x\n",
271 hdr_len, hdr.hdr.frag_len - hdr.alloc_hint));
272 p = NULL;
275 if (p) p = lsa_io_r_open_pol(True, &r_o, p, rdata, 4, 0);
277 pkt_len = PTR_DIFF(p, rdata);
279 if (p && pkt_len != hdr.hdr.frag_len)
281 /* packet data size not same as reported fragment length */
282 DEBUG(2,("do_lsa_open_policy: pkt_len %x != frag_len \n",
283 pkt_len, hdr.hdr.frag_len));
284 p = NULL;
287 if (p && r_o.status != 0)
289 /* report error code */
290 DEBUG(0,("LSA_OPENPOLICY: nt_status error %lx\n", r_o.status));
291 p = NULL;
294 if (p)
296 /* ok, at last: we're happy. return the policy handle */
297 memcpy(hnd, r_o.pol.data, sizeof(hnd->data));
298 valid_pol = True;
302 if (rparam) free(rparam);
303 if (rdata) free(rdata);
305 return valid_pol;
308 /****************************************************************************
309 do a LSA Query Info Policy
310 ****************************************************************************/
311 static BOOL do_lsa_query_info_pol(uint16 fnum, LSA_POL_HND *hnd, uint16 info_class,
312 fstring domain_name, pstring domain_sid)
314 char *rparam = NULL;
315 char *rdata = NULL;
316 char *p;
317 int rdrcnt,rprcnt;
318 pstring data; /* only 1024 bytes */
319 uint16 setup[2]; /* only need 2 uint16 setup parameters */
320 LSA_Q_QUERY_INFO q_q;
321 int call_id = 0x1;
322 BOOL valid_response = False;
324 if (hnd == NULL || domain_name == NULL || domain_sid == NULL) return False;
326 /* create and send a MSRPC command with api LSA_QUERYINFOPOLICY */
328 DEBUG(4,("LSA Query Info Policy\n"));
330 /* store the parameters */
331 make_q_query(&q_q, hnd, info_class);
333 /* turn parameters into data stream */
334 p = lsa_io_q_query(False, &q_q, data + 0x18, data, 4, 0);
336 /* create the request RPC_HDR_RR with no data */
337 create_rpc_request(call_id, LSA_QUERYINFOPOLICY, data, PTR_DIFF(p, data));
339 /* create setup parameters. */
340 setup[0] = 0x0026; /* 0x26 indicates "transact named pipe" */
341 setup[1] = fnum; /* file handle, from the SMBcreateX pipe, earlier */
343 /* send the data on \PIPE\ */
344 if (cli_call_api("\\PIPE\\", 0, PTR_DIFF(p, data), 2, 1024,
345 BUFFER_SIZE,
346 &rprcnt, &rdrcnt,
347 NULL, data, setup,
348 &rparam, &rdata))
350 LSA_R_QUERY_INFO r_q;
351 RPC_HDR_RR hdr;
352 int hdr_len;
353 int pkt_len;
355 DEBUG(5, ("cli_call_api: return OK\n"));
357 p = rdata;
359 if (p) p = smb_io_rpc_hdr_rr (True, &hdr, p, rdata, 4, 0);
360 if (p) p = align_offset(p, rdata, 4); /* oh, what a surprise */
362 hdr_len = PTR_DIFF(p, rdata);
364 if (p && hdr_len != hdr.hdr.frag_len - hdr.alloc_hint)
366 /* header length not same as calculated header length */
367 DEBUG(2,("do_lsa_query_info: hdr_len %x != frag_len-alloc_hint %x\n",
368 hdr_len, hdr.hdr.frag_len - hdr.alloc_hint));
369 p = NULL;
372 if (p) p = lsa_io_r_query(True, &r_q, p, rdata, 4, 0);
374 pkt_len = PTR_DIFF(p, rdata);
376 if (p && pkt_len != hdr.hdr.frag_len)
378 /* packet data size not same as reported fragment length */
379 DEBUG(2,("do_lsa_query_info: pkt_len %x != frag_len \n",
380 pkt_len, hdr.hdr.frag_len));
381 p = NULL;
384 if (p && r_q.status != 0)
386 /* report error code */
387 DEBUG(0,("LSA_QUERYINFOPOLICY: nt_status error %lx\n", r_q.status));
388 p = NULL;
391 if (p && r_q.info_class != q_q.info_class)
393 /* report different info classes */
394 DEBUG(0,("LSA_QUERYINFOPOLICY: error info_class (q,r) differ - (%x,%x)\n",
395 q_q.info_class, r_q.info_class));
396 p = NULL;
399 if (p)
401 /* ok, at last: we're happy. */
402 switch (r_q.info_class)
404 case 3:
406 char *dom_name = unistrn2(r_q.dom.id3.uni_domain_name.buffer,
407 r_q.dom.id3.uni_domain_name.uni_str_len);
408 char *dom_sid = dom_sid_to_string(&(r_q.dom.id3.dom_sid));
409 fstrcpy(domain_name, dom_name);
410 pstrcpy(domain_sid , dom_sid);
412 valid_response = True;
413 break;
415 case 5:
417 char *dom_name = unistrn2(r_q.dom.id5.uni_domain_name.buffer,
418 r_q.dom.id5.uni_domain_name.uni_str_len);
419 char *dom_sid = dom_sid_to_string(&(r_q.dom.id5.dom_sid));
420 fstrcpy(domain_name, dom_name);
421 pstrcpy(domain_sid , dom_sid);
423 valid_response = True;
424 break;
426 default:
428 DEBUG(3,("LSA_QUERYINFOPOLICY: unknown info class\n"));
429 domain_name[0] = 0;
430 domain_sid [0] = 0;
432 break;
435 DEBUG(3,("LSA_QUERYINFOPOLICY (level %x): domain:%s domain sid:%s\n",
436 r_q.info_class, domain_name, domain_sid));
440 if (rparam) free(rparam);
441 if (rdata) free(rdata);
443 return valid_response;
446 /****************************************************************************
447 do a LSA Close
448 ****************************************************************************/
449 static BOOL do_lsa_close(uint16 fnum, LSA_POL_HND *hnd)
451 char *rparam = NULL;
452 char *rdata = NULL;
453 char *p;
454 int rdrcnt,rprcnt;
455 pstring data; /* only 1024 bytes */
456 uint16 setup[2]; /* only need 2 uint16 setup parameters */
457 LSA_Q_CLOSE q_c;
458 int call_id = 0x1;
459 BOOL valid_close = False;
461 if (hnd == NULL) return False;
463 /* create and send a MSRPC command with api LSA_OPENPOLICY */
465 DEBUG(4,("LSA Close\n"));
467 /* store the parameters */
468 make_q_close(&q_c, hnd);
470 /* turn parameters into data stream */
471 p = lsa_io_q_close(False, &q_c, data + 0x18, data, 4, 0);
473 /* create the request RPC_HDR_RR with no data */
474 create_rpc_request(call_id, LSA_CLOSE, data, PTR_DIFF(p, data));
476 /* create setup parameters. */
477 setup[0] = 0x0026; /* 0x26 indicates "transact named pipe" */
478 setup[1] = fnum; /* file handle, from the SMBcreateX pipe, earlier */
480 /* send the data on \PIPE\ */
481 if (cli_call_api("\\PIPE\\", 0, PTR_DIFF(p, data), 2, 1024,
482 BUFFER_SIZE,
483 &rprcnt, &rdrcnt,
484 NULL, data, setup,
485 &rparam, &rdata))
487 LSA_R_CLOSE r_c;
488 RPC_HDR_RR hdr;
489 int hdr_len;
490 int pkt_len;
492 DEBUG(5, ("cli_call_api: return OK\n"));
494 p = rdata;
496 if (p) p = smb_io_rpc_hdr_rr (True, &hdr, p, rdata, 4, 0);
497 if (p) p = align_offset(p, rdata, 4); /* oh, what a surprise */
499 hdr_len = PTR_DIFF(p, rdata);
501 if (p && hdr_len != hdr.hdr.frag_len - hdr.alloc_hint)
503 /* header length not same as calculated header length */
504 DEBUG(2,("do_lsa_close: hdr_len %x != frag_len-alloc_hint %x\n",
505 hdr_len, hdr.hdr.frag_len - hdr.alloc_hint));
506 p = NULL;
509 if (p) p = lsa_io_r_close(True, &r_c, p, rdata, 4, 0);
511 pkt_len = PTR_DIFF(p, rdata);
513 if (p && pkt_len != hdr.hdr.frag_len)
515 /* packet data size not same as reported fragment length */
516 DEBUG(2,("do_lsa_close: pkt_len %x != frag_len \n",
517 pkt_len, hdr.hdr.frag_len));
518 p = NULL;
521 if (p && r_c.status != 0)
523 /* report error code */
524 DEBUG(0,("LSA_OPENPOLICY: nt_status error %lx\n", r_c.status));
525 p = NULL;
528 if (p)
530 /* check that the returned policy handle is all zeros */
531 int i;
532 valid_close = True;
534 for (i = 0; i < sizeof(r_c.pol.data); i++)
536 if (r_c.pol.data[i] != 0)
538 valid_close = False;
539 break;
542 if (!valid_close)
544 DEBUG(0,("LSA_CLOSE: non-zero handle returned\n"));
549 if (rparam) free(rparam);
550 if (rdata) free(rdata);
552 return valid_close;
555 /****************************************************************************
556 do a LSA Request Challenge
557 ****************************************************************************/
558 static BOOL do_lsa_req_chal(uint16 fnum,
559 char *desthost, char *myhostname,
560 DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal)
562 char *rparam = NULL;
563 char *rdata = NULL;
564 char *p;
565 int rdrcnt,rprcnt;
566 pstring data; /* only 1024 bytes */
567 uint16 setup[2]; /* only need 2 uint16 setup parameters */
568 LSA_Q_REQ_CHAL q_c;
569 int call_id = 0x1;
570 BOOL valid_chal = False;
572 if (srv_chal == NULL || clnt_chal == NULL) return False;
574 /* create and send a MSRPC command with api LSA_REQCHAL */
576 DEBUG(4,("LSA Request Challenge from %s to %s: %lx %lx\n",
577 desthost, myhostname, clnt_chal->data[0], clnt_chal->data[1]));
579 /* store the parameters */
580 make_q_req_chal(&q_c, desthost, myhostname, clnt_chal);
583 /* turn parameters into data stream */
584 p = lsa_io_q_req_chal(False, &q_c, data + 0x18, data, 4, 0);
586 /* create the request RPC_HDR_RR _after_ the main data: length is now known */
587 create_rpc_request(call_id, LSA_REQCHAL, data, PTR_DIFF(p, data));
589 /* create setup parameters. */
590 setup[0] = 0x0026; /* 0x26 indicates "transact named pipe" */
591 setup[1] = fnum; /* file handle, from the SMBcreateX pipe, earlier */
593 /* send the data on \PIPE\ */
594 if (cli_call_api("\\PIPE\\", 0, PTR_DIFF(p, data), 2, 1024,
595 BUFFER_SIZE,
596 &rprcnt,&rdrcnt,
597 NULL, data, setup,
598 &rparam,&rdata))
600 LSA_R_REQ_CHAL r_c;
601 RPC_HDR_RR hdr;
602 int hdr_len;
603 int pkt_len;
605 DEBUG(5, ("cli_call_api: return OK\n"));
607 p = rdata;
609 if (p) p = smb_io_rpc_hdr_rr (True, &hdr, p, rdata, 4, 0);
610 if (p) p = align_offset(p, rdata, 4); /* oh, what a surprise */
612 hdr_len = PTR_DIFF(p, rdata);
614 if (p && hdr_len != hdr.hdr.frag_len - hdr.alloc_hint)
616 /* header length not same as calculated header length */
617 DEBUG(2,("do_lsa_req_chal: hdr_len %x != frag_len-alloc_hint %x\n",
618 hdr_len, hdr.hdr.frag_len - hdr.alloc_hint));
619 p = NULL;
622 if (p) p = lsa_io_r_req_chal(True, &r_c, p, rdata, 4, 0);
624 pkt_len = PTR_DIFF(p, rdata);
626 if (p && pkt_len != hdr.hdr.frag_len)
628 /* packet data size not same as reported fragment length */
629 DEBUG(2,("do_lsa_req_chal: pkt_len %x != frag_len \n",
630 pkt_len, hdr.hdr.frag_len));
631 p = NULL;
634 if (p && r_c.status != 0)
636 /* report error code */
637 DEBUG(0,("LSA_REQ_CHAL: nt_status error %lx\n", r_c.status));
638 p = NULL;
641 if (p)
643 /* ok, at last: we're happy. return the challenge */
644 memcpy(srv_chal, r_c.srv_chal.data, sizeof(srv_chal->data));
645 valid_chal = True;
649 if (rparam) free(rparam);
650 if (rdata) free(rdata);
652 return valid_chal;
655 /****************************************************************************
656 do a LSA Authenticate 2
657 ****************************************************************************/
658 static BOOL do_lsa_auth2(uint16 fnum,
659 char *logon_srv, char *acct_name, uint16 sec_chan, char *comp_name,
660 DOM_CHAL *clnt_chal, uint32 neg_flags, DOM_CHAL *srv_chal)
662 char *rparam = NULL;
663 char *rdata = NULL;
664 char *p;
665 int rdrcnt,rprcnt;
666 pstring data; /* only 1024 bytes */
667 uint16 setup[2]; /* only need 2 uint16 setup parameters */
668 LSA_Q_AUTH_2 q_a;
669 int call_id = 0x1;
670 BOOL valid_chal = False;
672 if (srv_chal == NULL || clnt_chal == NULL) return False;
674 /* create and send a MSRPC command with api LSA_AUTH2 */
676 DEBUG(4,("LSA Authenticate 2: srv:%s acct:%s sc:%x mc: %s chal %lx %lx neg: %lx\n",
677 logon_srv, acct_name, sec_chan, comp_name,
678 clnt_chal->data[0], clnt_chal->data[1], neg_flags));
680 /* store the parameters */
681 make_q_auth_2(&q_a, logon_srv, acct_name, sec_chan, comp_name,
682 clnt_chal, neg_flags);
684 /* turn parameters into data stream */
685 p = lsa_io_q_auth_2(False, &q_a, data + 0x18, data, 4, 0);
687 /* create the request RPC_HDR_RR _after_ the main data: length is now known */
688 create_rpc_request(call_id, LSA_AUTH2, data, PTR_DIFF(p, data));
690 /* create setup parameters. */
691 setup[0] = 0x0026; /* 0x26 indicates "transact named pipe" */
692 setup[1] = fnum; /* file handle, from the SMBcreateX pipe, earlier */
694 /* send the data on \PIPE\ */
695 if (cli_call_api("\\PIPE\\", 0, PTR_DIFF(p, data), 2, 1024,
696 BUFFER_SIZE,
697 &rprcnt,&rdrcnt,
698 NULL, data, setup,
699 &rparam,&rdata))
701 LSA_R_AUTH_2 r_a;
702 RPC_HDR_RR hdr;
703 int hdr_len;
704 int pkt_len;
706 DEBUG(5, ("cli_call_api: return OK\n"));
708 p = rdata;
710 if (p) p = smb_io_rpc_hdr_rr (True, &hdr, p, rdata, 4, 0);
711 if (p) p = align_offset(p, rdata, 4); /* oh, what a surprise */
713 hdr_len = PTR_DIFF(p, rdata);
715 if (p && hdr_len != hdr.hdr.frag_len - hdr.alloc_hint)
717 /* header length not same as calculated header length */
718 DEBUG(2,("do_lsa_auth2: hdr_len %x != frag_len-alloc_hint %x\n",
719 hdr_len, hdr.hdr.frag_len - hdr.alloc_hint));
720 p = NULL;
723 if (p) p = lsa_io_r_auth_2(True, &r_a, p, rdata, 4, 0);
725 pkt_len = PTR_DIFF(p, rdata);
727 if (p && pkt_len != hdr.hdr.frag_len)
729 /* packet data size not same as reported fragment length */
730 DEBUG(2,("do_lsa_auth2: pkt_len %x != frag_len \n",
731 pkt_len, hdr.hdr.frag_len));
732 p = NULL;
735 if (p && r_a.status != 0)
737 /* report error code */
738 DEBUG(0,("LSA_AUTH2: nt_status error %lx\n", r_a.status));
739 p = NULL;
742 if (p && r_a.srv_flgs.neg_flags != q_a.clnt_flgs.neg_flags)
744 /* report different neg_flags */
745 DEBUG(0,("LSA_AUTH2: error neg_flags (q,r) differ - (%lx,%lx)\n",
746 q_a.clnt_flgs.neg_flags, r_a.srv_flgs.neg_flags));
747 p = NULL;
750 if (p)
752 /* ok, at last: we're happy. return the challenge */
753 memcpy(srv_chal, r_a.srv_chal.data, sizeof(srv_chal->data));
754 valid_chal = True;
758 if (rparam) free(rparam);
759 if (rdata) free(rdata);
761 return valid_chal;
764 /***************************************************************************
765 do a LSA SAM Logon
766 ****************************************************************************/
767 static BOOL do_lsa_sam_logon(uint16 fnum, uint32 sess_key[2], DOM_CRED *sto_clnt_cred,
768 char *logon_srv, char *comp_name,
769 DOM_CRED *clnt_cred, DOM_CRED *rtn_cred,
770 uint16 logon_level, uint16 switch_value, DOM_ID_INFO_1 *id1,
771 LSA_USER_INFO *user_info,
772 DOM_CRED *srv_cred)
774 char *rparam = NULL;
775 char *rdata = NULL;
776 char *p;
777 int rdrcnt,rprcnt;
778 pstring data; /* only 1024 bytes */
779 uint16 setup[2]; /* only need 2 uint16 setup parameters */
780 LSA_Q_SAM_LOGON q_s;
781 int call_id = 0x1;
782 BOOL valid_cred = False;
784 if (srv_cred == NULL || clnt_cred == NULL || rtn_cred == NULL || user_info == NULL) return False;
786 /* create and send a MSRPC command with api LSA_SAMLOGON */
788 DEBUG(4,("LSA SAM Logon: srv:%s mc:%s clnt %lx %lx %lx rtn: %lx %lx %lx ll: %d\n",
789 logon_srv, comp_name,
790 clnt_cred->challenge.data[0], clnt_cred->challenge.data[1], clnt_cred->timestamp.time,
791 rtn_cred ->challenge.data[0], rtn_cred ->challenge.data[1], rtn_cred ->timestamp.time,
792 logon_level));
794 /* store the parameters */
795 make_sam_info(&(q_s.sam_id), logon_srv, comp_name,
796 clnt_cred, rtn_cred, logon_level, switch_value, id1);
798 /* turn parameters into data stream */
799 p = lsa_io_q_sam_logon(False, &q_s, data + 0x18, data, 4, 0);
801 /* create the request RPC_HDR_RR _after_ the main data: length is now known */
802 create_rpc_request(call_id, LSA_SAMLOGON, data, PTR_DIFF(p, data));
804 /* create setup parameters. */
805 setup[0] = 0x0026; /* 0x26 indicates "transact named pipe" */
806 setup[1] = fnum; /* file handle, from the SMBcreateX pipe, earlier */
808 /* send the data on \PIPE\ */
809 if (cli_call_api("\\PIPE\\", 0, PTR_DIFF(p, data), 2, 1024,
810 BUFFER_SIZE,
811 &rprcnt,&rdrcnt,
812 NULL, data, setup,
813 &rparam,&rdata))
815 LSA_R_SAM_LOGON r_s;
816 RPC_HDR_RR hdr;
817 int hdr_len;
818 int pkt_len;
820 r_s.user = user_info;
822 DEBUG(5, ("cli_call_api: return OK\n"));
824 p = rdata;
826 if (p) p = smb_io_rpc_hdr_rr (True, &hdr, p, rdata, 4, 0);
827 if (p) p = align_offset(p, rdata, 4); /* oh, what a surprise */
829 hdr_len = PTR_DIFF(p, rdata);
831 if (p && hdr_len != hdr.hdr.frag_len - hdr.alloc_hint)
833 /* header length not same as calculated header length */
834 DEBUG(2,("do_lsa_sam_logon: hdr_len %x != frag_len-alloc_hint %x\n",
835 hdr_len, hdr.hdr.frag_len - hdr.alloc_hint));
836 p = NULL;
839 if (p) p = lsa_io_r_sam_logon(True, &r_s, p, rdata, 4, 0);
841 pkt_len = PTR_DIFF(p, rdata);
843 if (p && pkt_len != hdr.hdr.frag_len)
845 /* packet data size not same as reported fragment length */
846 DEBUG(2,("do_lsa_sam_logon: pkt_len %x != frag_len \n",
847 pkt_len, hdr.hdr.frag_len));
848 p = NULL;
851 if (p && r_s.status != 0)
853 /* report error code */
854 DEBUG(0,("LSA_SAMLOGON: nt_status error %lx\n", r_s.status));
855 p = NULL;
858 if (p && r_s.switch_value != 3)
860 /* report different switch_value */
861 DEBUG(0,("LSA_SAMLOGON: switch_value of 3 expected %x\n",
862 r_s.switch_value));
863 p = NULL;
866 if (p)
868 if (clnt_deal_with_creds(sess_key, sto_clnt_cred, &(r_s.srv_creds)))
870 DEBUG(5, ("do_lsa_sam_logon: server credential check OK\n"));
871 /* ok, at last: we're happy. return the challenge */
872 memcpy(srv_cred, &(r_s.srv_creds), sizeof(r_s.srv_creds));
873 valid_cred = True;
875 else
877 DEBUG(5, ("do_lsa_sam_logon: server credential check failed\n"));
882 if (rparam) free(rparam);
883 if (rdata) free(rdata);
885 return valid_cred;
888 /***************************************************************************
889 do a LSA SAM Logoff
890 ****************************************************************************/
891 static BOOL do_lsa_sam_logoff(uint16 fnum, uint32 sess_key[2], DOM_CRED *sto_clnt_cred,
892 char *logon_srv, char *comp_name,
893 DOM_CRED *clnt_cred, DOM_CRED *rtn_cred,
894 uint16 logon_level, uint16 switch_value, DOM_ID_INFO_1 *id1,
895 DOM_CRED *srv_cred)
897 char *rparam = NULL;
898 char *rdata = NULL;
899 char *p;
900 int rdrcnt,rprcnt;
901 pstring data; /* only 1024 bytes */
902 uint16 setup[2]; /* only need 2 uint16 setup parameters */
903 LSA_Q_SAM_LOGOFF q_s;
904 int call_id = 0x1;
905 BOOL valid_cred = False;
907 if (srv_cred == NULL || clnt_cred == NULL || rtn_cred == NULL) return False;
909 /* create and send a MSRPC command with api LSA_SAMLOGON */
911 DEBUG(4,("LSA SAM Logoff: srv:%s mc:%s clnt %lx %lx %lx rtn: %lx %lx %lx ll: %d\n",
912 logon_srv, comp_name,
913 clnt_cred->challenge.data[0], clnt_cred->challenge.data[1], clnt_cred->timestamp.time,
914 rtn_cred ->challenge.data[0], rtn_cred ->challenge.data[1], rtn_cred ->timestamp.time,
915 logon_level));
917 /* store the parameters */
918 make_sam_info(&(q_s.sam_id), logon_srv, comp_name,
919 clnt_cred, rtn_cred, logon_level, switch_value, id1);
921 /* turn parameters into data stream */
922 p = lsa_io_q_sam_logoff(False, &q_s, data + 0x18, data, 4, 0);
924 /* create the request RPC_HDR_RR _after_ the main data: length is now known */
925 create_rpc_request(call_id, LSA_SAMLOGOFF, data, PTR_DIFF(p, data));
927 /* create setup parameters. */
928 setup[0] = 0x0026; /* 0x26 indicates "transact named pipe" */
929 setup[1] = fnum; /* file handle, from the SMBcreateX pipe, earlier */
931 /* send the data on \PIPE\ */
932 if (cli_call_api("\\PIPE\\", 0, PTR_DIFF(p, data), 2, 1024,
933 BUFFER_SIZE,
934 &rprcnt,&rdrcnt,
935 NULL, data, setup,
936 &rparam,&rdata))
938 LSA_R_SAM_LOGOFF r_s;
939 RPC_HDR_RR hdr;
940 int hdr_len;
941 int pkt_len;
943 DEBUG(5, ("cli_call_api: return OK\n"));
945 p = rdata;
947 if (p) p = smb_io_rpc_hdr_rr (True, &hdr, p, rdata, 4, 0);
948 if (p) p = align_offset(p, rdata, 4); /* oh, what a surprise */
950 hdr_len = PTR_DIFF(p, rdata);
952 if (p && hdr_len != hdr.hdr.frag_len - hdr.alloc_hint)
954 /* header length not same as calculated header length */
955 DEBUG(2,("do_lsa_sam_logoff: hdr_len %x != frag_len-alloc_hint %x\n",
956 hdr_len, hdr.hdr.frag_len - hdr.alloc_hint));
957 p = NULL;
960 if (p) p = lsa_io_r_sam_logoff(True, &r_s, p, rdata, 4, 0);
962 pkt_len = PTR_DIFF(p, rdata);
964 if (p && pkt_len != hdr.hdr.frag_len)
966 /* packet data size not same as reported fragment length */
967 DEBUG(2,("do_lsa_sam_logoff: pkt_len %x != frag_len \n",
968 pkt_len, hdr.hdr.frag_len));
969 p = NULL;
972 if (p && r_s.status != 0)
974 /* report error code */
975 DEBUG(0,("LSA_SAMLOGOFF: nt_status error %lx\n", r_s.status));
976 p = NULL;
979 if (p)
981 if (clnt_deal_with_creds(sess_key, sto_clnt_cred, &(r_s.srv_creds)))
983 DEBUG(5, ("do_lsa_sam_logoff: server credential check OK\n"));
984 /* ok, at last: we're happy. return the challenge */
985 memcpy(srv_cred, &(r_s.srv_creds), sizeof(r_s.srv_creds));
986 valid_cred = True;
988 else
990 DEBUG(5, ("do_lsa_sam_logoff: server credential check failed\n"));
995 if (rparam) free(rparam);
996 if (rdata) free(rdata);
998 return valid_cred;
1001 /****************************************************************************
1002 experimental nt login.
1003 ****************************************************************************/
1004 BOOL do_nt_login(char *desthost, char *myhostname,
1005 int Client, int cnum)
1007 DOM_CHAL clnt_chal;
1008 DOM_CHAL srv_chal;
1010 DOM_CRED clnt_cred;
1012 DOM_CHAL auth2_srv_chal;
1014 DOM_CRED sam_logon_clnt_cred;
1015 DOM_CRED sam_logon_rtn_cred;
1016 DOM_CRED sam_logon_srv_cred;
1018 DOM_CRED sam_logoff_clnt_cred;
1019 DOM_CRED sam_logoff_rtn_cred;
1020 DOM_CRED sam_logoff_srv_cred;
1022 DOM_ID_INFO_1 id1;
1023 LSA_USER_INFO user_info1;
1024 LSA_POL_HND pol;
1026 UTIME zerotime;
1028 uint32 sess_key[2];
1029 char nt_owf_mach_pwd[16];
1030 fstring mach_acct;
1031 fstring mach_pwd;
1032 fstring server_name;
1034 /* received from LSA Query Info Policy, level 5 */
1035 fstring level5_domain_name;
1036 pstring level5_domain_sid;
1038 /* received from LSA Query Info Policy, level 3 */
1039 fstring level3_domain_name;
1040 pstring level3_domain_sid;
1042 uint16 fnum;
1043 char *inbuf,*outbuf;
1045 zerotime.time = 0;
1047 inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
1048 outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
1050 if (!inbuf || !outbuf)
1052 DEBUG(0,("out of memory\n"));
1053 return False;
1056 /******************* open the \PIPE\lsarpc file *****************/
1058 if ((fnum = open_rpc_pipe(inbuf, outbuf, PIPE_LSARPC, Client, cnum)) == 0xffff)
1060 free(inbuf); free(outbuf);
1061 return False;
1064 /******************* bind request on \PIPE\lsarpc *****************/
1066 if (!do_rpc_bind(fnum))
1068 free(inbuf); free(outbuf);
1069 return False;
1072 /******************* Open Policy ********************/
1074 fstrcpy(server_name, ("\\\\"));
1075 fstrcpy(&server_name[2], myhostname);
1077 /* send an open policy request; receive a policy handle */
1078 if (!do_lsa_open_policy(fnum, server_name, &pol))
1080 cli_smb_close(inbuf, outbuf, Client, cnum, fnum);
1081 free(inbuf); free(outbuf);
1082 return False;
1085 /**************** Query Info Policy, level 3 ********************/
1087 /* send a query info policy at level 3; receive an info policy */
1088 if (!do_lsa_query_info_pol(fnum, &pol, 0x3,
1089 level3_domain_name, level3_domain_sid))
1091 cli_smb_close(inbuf, outbuf, Client, cnum, fnum);
1092 free(inbuf); free(outbuf);
1093 return False;
1096 /**************** Query Info Policy, level 5 ********************/
1098 /* send a query info policy at level 5; receive an info policy */
1099 if (!do_lsa_query_info_pol(fnum, &pol, 0x5,
1100 level5_domain_name, level5_domain_sid))
1102 cli_smb_close(inbuf, outbuf, Client, cnum, fnum);
1103 free(inbuf); free(outbuf);
1104 return False;
1107 /******************* Open Policy ********************/
1109 /* send a close policy request; receive a close pol response */
1110 if (!do_lsa_close(fnum, &pol))
1112 cli_smb_close(inbuf, outbuf, Client, cnum, fnum);
1113 free(inbuf); free(outbuf);
1114 return False;
1117 /******************* close the \PIPE\lsarpc file *******************/
1119 cli_smb_close(inbuf, outbuf, Client, cnum, fnum);
1123 /******************* open the \PIPE\NETLOGON file *****************/
1125 if ((fnum = open_rpc_pipe(inbuf, outbuf, PIPE_NETLOGON, Client, cnum)) == 0xffff)
1127 free(inbuf); free(outbuf);
1128 return False;
1131 /******************* bind request on \PIPE\NETLOGON *****************/
1133 if (!do_rpc_bind(fnum))
1135 free(inbuf); free(outbuf);
1136 return False;
1139 /******************* Request Challenge ********************/
1141 fstrcpy(mach_acct, myhostname);
1142 strlower(mach_pwd);
1144 fstrcpy(mach_pwd , myhostname);
1145 strcat(mach_acct, "$");
1147 clnt_chal.data[0] = 0x11111111;
1148 clnt_chal.data[1] = 0x22222222;
1150 /* send a client challenge; receive a server challenge */
1151 if (!do_lsa_req_chal(fnum, desthost, myhostname, &clnt_chal, &srv_chal))
1153 cli_smb_close(inbuf, outbuf, Client, cnum, fnum);
1154 free(inbuf); free(outbuf);
1155 return False;
1158 /************ Long-term Session key (default) **********/
1160 #if 0
1161 /* DAMN! can't get the machine password - need become_root() to do it! */
1162 /* get the machine password */
1163 if (!get_md4pw(mach_acct, nt_owf_mach_pwd))
1165 cli_smb_close(inbuf, outbuf, Client, cnum, fnum);
1166 free(inbuf); free(outbuf);
1167 return False;
1170 DEBUG(5,("got nt owf from smbpasswd entry: %s\n", mach_pwd));
1171 #else
1174 char lm_owf_mach_pwd[16];
1175 nt_lm_owf_gen(mach_pwd, nt_owf_mach_pwd, lm_owf_mach_pwd);
1176 DEBUG(5,("generating nt owf from initial machine pwd: %s\n", mach_pwd));
1179 #endif
1181 dump_data(6, nt_owf_mach_pwd, 16);
1183 /* calculate the session key */
1184 cred_session_key(&clnt_chal, &srv_chal, nt_owf_mach_pwd, sess_key);
1187 /******************* Authenticate 2 ********************/
1189 /* calculate auth-2 credentials */
1190 cred_create(sess_key, &clnt_chal, zerotime, &(clnt_cred.challenge));
1192 /* send client auth-2 challenge; receive an auth-2 challenge */
1193 if (!do_lsa_auth2(fnum, desthost, mach_acct, 2, myhostname,
1194 &(clnt_cred.challenge), 0x000001ff, &auth2_srv_chal))
1196 cli_smb_close(inbuf, outbuf, Client, cnum, fnum);
1197 free(inbuf); free(outbuf);
1198 return False;
1202 /*********************** SAM Info ***********************/
1204 /* this is used in both the SAM Logon and the SAM Logoff */
1205 make_id_info1(&id1, workgroup, 0,
1206 getuid(), 0,
1207 username, myhostname,
1208 NULL, NULL);
1210 /*********************** SAM Logon **********************/
1212 clnt_cred.timestamp.time = sam_logon_clnt_cred.timestamp.time = time(NULL);
1214 /* calculate sam logon credentials, using the auth2 client challenge */
1215 cred_create(sess_key, &(clnt_cred.challenge), sam_logon_clnt_cred.timestamp,
1216 &(sam_logon_clnt_cred.challenge));
1218 /* send client sam-logon challenge; receive a sam-logon challenge */
1219 if (!do_lsa_sam_logon(fnum, sess_key, &clnt_cred,
1220 desthost, mach_acct,
1221 &sam_logon_clnt_cred, &sam_logon_rtn_cred,
1222 1, 1, &id1, &user_info1,
1223 &sam_logon_srv_cred))
1225 cli_smb_close(inbuf, outbuf, Client, cnum, fnum);
1226 free(inbuf); free(outbuf);
1227 return False;
1230 /*********************** SAM Logoff *********************/
1232 clnt_cred.timestamp.time = sam_logoff_clnt_cred.timestamp.time = time(NULL);
1234 /* calculate sam logoff credentials, using the sam logon return challenge */
1235 cred_create(sess_key, &(clnt_cred.challenge),
1236 sam_logoff_clnt_cred.timestamp,
1237 &(sam_logoff_clnt_cred.challenge));
1239 /* send client sam-logoff challenge; receive a sam-logoff challenge */
1240 if (!do_lsa_sam_logoff(fnum, sess_key, &clnt_cred,
1241 desthost, mach_acct,
1242 &sam_logoff_clnt_cred, &sam_logoff_rtn_cred,
1243 1, 1, &id1,
1244 &sam_logoff_srv_cred))
1246 cli_smb_close(inbuf, outbuf, Client, cnum, fnum);
1247 free(inbuf); free(outbuf);
1248 return False;
1251 /******************** close the \PIPE\NETLOGON file **************/
1253 cli_smb_close(inbuf, outbuf, Client, cnum, fnum);
1255 /* free memory used in all rpc transactions, above */
1256 free(inbuf); free(outbuf);
1258 return True;
1260 #endif /* NTDOMAIN */