2 Unix SMB/Netbios implementation.
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.
28 extern int DEBUGLEVEL
;
29 extern pstring username
;
30 extern pstring workgroup
;
32 #define CLIENT_TIMEOUT (30*1000)
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
)
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);
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
)));
80 fnum
= SVAL(inbuf
, smb_vwv2
);
82 DEBUG(5,("opening pipe: fnum %d\n", fnum
));
87 /****************************************************************************
89 ****************************************************************************/
90 static BOOL
do_rpc_bind(uint16 fnum
)
97 pstring data
; /* only 1024 bytes */
98 uint16 setup
[2]; /* only need 2 uint16 setup parameters */
106 BOOL valid_ack
= False
;
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
++)
122 for (i
= 0; i
< sizeof(abs_data
); 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
,
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,
163 DEBUG(5, ("cli_call_api: return OK\n"));
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
);
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
));
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
));
192 if (p
&& r_o
.status
!= 0)
194 /* report error code */
195 DEBUG(0,("LSA_OPENPOLICY: nt_status error %lx\n", r_o
.status
));
201 /* ok, at last: we're happy. */
206 if (rparam
) free(rparam
);
207 if (rdata
) free(rdata
);
212 /****************************************************************************
214 ****************************************************************************/
215 static BOOL
do_lsa_open_policy(uint16 fnum
, char *server_name
, LSA_POL_HND
*hnd
)
221 pstring data
; /* only 1024 bytes */
222 uint16 setup
[2]; /* only need 2 uint16 setup parameters */
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,
258 DEBUG(5, ("cli_call_api: return OK\n"));
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
));
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
));
287 if (p
&& r_o
.status
!= 0)
289 /* report error code */
290 DEBUG(0,("LSA_OPENPOLICY: nt_status error %lx\n", r_o
.status
));
296 /* ok, at last: we're happy. return the policy handle */
297 memcpy(hnd
, r_o
.pol
.data
, sizeof(hnd
->data
));
302 if (rparam
) free(rparam
);
303 if (rdata
) free(rdata
);
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
)
318 pstring data
; /* only 1024 bytes */
319 uint16 setup
[2]; /* only need 2 uint16 setup parameters */
320 LSA_Q_QUERY_INFO q_q
;
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,
350 LSA_R_QUERY_INFO r_q
;
355 DEBUG(5, ("cli_call_api: return OK\n"));
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
));
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
));
384 if (p
&& r_q
.status
!= 0)
386 /* report error code */
387 DEBUG(0,("LSA_QUERYINFOPOLICY: nt_status error %lx\n", r_q
.status
));
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
));
401 /* ok, at last: we're happy. */
402 switch (r_q
.info_class
)
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
;
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
;
428 DEBUG(3,("LSA_QUERYINFOPOLICY: unknown info class\n"));
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 /****************************************************************************
448 ****************************************************************************/
449 static BOOL
do_lsa_close(uint16 fnum
, LSA_POL_HND
*hnd
)
455 pstring data
; /* only 1024 bytes */
456 uint16 setup
[2]; /* only need 2 uint16 setup parameters */
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,
492 DEBUG(5, ("cli_call_api: return OK\n"));
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
));
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
));
521 if (p
&& r_c
.status
!= 0)
523 /* report error code */
524 DEBUG(0,("LSA_OPENPOLICY: nt_status error %lx\n", r_c
.status
));
530 /* check that the returned policy handle is all zeros */
534 for (i
= 0; i
< sizeof(r_c
.pol
.data
); i
++)
536 if (r_c
.pol
.data
[i
] != 0)
544 DEBUG(0,("LSA_CLOSE: non-zero handle returned\n"));
549 if (rparam
) free(rparam
);
550 if (rdata
) free(rdata
);
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
)
566 pstring data
; /* only 1024 bytes */
567 uint16 setup
[2]; /* only need 2 uint16 setup parameters */
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,
605 DEBUG(5, ("cli_call_api: return OK\n"));
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
));
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
));
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
));
643 /* ok, at last: we're happy. return the challenge */
644 memcpy(srv_chal
, r_c
.srv_chal
.data
, sizeof(srv_chal
->data
));
649 if (rparam
) free(rparam
);
650 if (rdata
) free(rdata
);
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
)
666 pstring data
; /* only 1024 bytes */
667 uint16 setup
[2]; /* only need 2 uint16 setup parameters */
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,
706 DEBUG(5, ("cli_call_api: return OK\n"));
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
));
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
));
735 if (p
&& r_a
.status
!= 0)
737 /* report error code */
738 DEBUG(0,("LSA_AUTH2: nt_status error %lx\n", r_a
.status
));
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
));
752 /* ok, at last: we're happy. return the challenge */
753 memcpy(srv_chal
, r_a
.srv_chal
.data
, sizeof(srv_chal
->data
));
758 if (rparam
) free(rparam
);
759 if (rdata
) free(rdata
);
764 /***************************************************************************
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
,
778 pstring data
; /* only 1024 bytes */
779 uint16 setup
[2]; /* only need 2 uint16 setup parameters */
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
,
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,
820 r_s
.user
= user_info
;
822 DEBUG(5, ("cli_call_api: return OK\n"));
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
));
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
));
851 if (p
&& r_s
.status
!= 0)
853 /* report error code */
854 DEBUG(0,("LSA_SAMLOGON: nt_status error %lx\n", r_s
.status
));
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",
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
));
877 DEBUG(5, ("do_lsa_sam_logon: server credential check failed\n"));
882 if (rparam
) free(rparam
);
883 if (rdata
) free(rdata
);
888 /***************************************************************************
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
,
901 pstring data
; /* only 1024 bytes */
902 uint16 setup
[2]; /* only need 2 uint16 setup parameters */
903 LSA_Q_SAM_LOGOFF q_s
;
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
,
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,
938 LSA_R_SAM_LOGOFF r_s
;
943 DEBUG(5, ("cli_call_api: return OK\n"));
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
));
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
));
972 if (p
&& r_s
.status
!= 0)
974 /* report error code */
975 DEBUG(0,("LSA_SAMLOGOFF: nt_status error %lx\n", r_s
.status
));
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
));
990 DEBUG(5, ("do_lsa_sam_logoff: server credential check failed\n"));
995 if (rparam
) free(rparam
);
996 if (rdata
) free(rdata
);
1001 /****************************************************************************
1002 experimental nt login.
1003 ****************************************************************************/
1004 BOOL
do_nt_login(char *desthost
, char *myhostname
,
1005 int Client
, int cnum
)
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
;
1023 LSA_USER_INFO user_info1
;
1029 char nt_owf_mach_pwd
[16];
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
;
1043 char *inbuf
,*outbuf
;
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"));
1056 /******************* open the \PIPE\lsarpc file *****************/
1058 if ((fnum
= open_rpc_pipe(inbuf
, outbuf
, PIPE_LSARPC
, Client
, cnum
)) == 0xffff)
1060 free(inbuf
); free(outbuf
);
1064 /******************* bind request on \PIPE\lsarpc *****************/
1066 if (!do_rpc_bind(fnum
))
1068 free(inbuf
); free(outbuf
);
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
);
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
);
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
);
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
);
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
);
1131 /******************* bind request on \PIPE\NETLOGON *****************/
1133 if (!do_rpc_bind(fnum
))
1135 free(inbuf
); free(outbuf
);
1139 /******************* Request Challenge ********************/
1141 fstrcpy(mach_acct
, myhostname
);
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
);
1158 /************ Long-term Session key (default) **********/
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
);
1170 DEBUG(5,("got nt owf from smbpasswd entry: %s\n", mach_pwd
));
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
));
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
);
1202 /*********************** SAM Info ***********************/
1204 /* this is used in both the SAM Logon and the SAM Logoff */
1205 make_id_info1(&id1
, workgroup
, 0,
1207 username
, myhostname
,
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
);
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
,
1244 &sam_logoff_srv_cred
))
1246 cli_smb_close(inbuf
, outbuf
, Client
, cnum
, fnum
);
1247 free(inbuf
); free(outbuf
);
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
);
1260 #endif /* NTDOMAIN */