2 Unix SMB/CIFS implementation.
3 client connect/disconnect routines
4 Copyright (C) Andrew Tridgell 1994-1998
5 Copyright (C) Andrew Bartlett 2001-2003
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 3 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, see <http://www.gnu.org/licenses/>.
27 {PROTOCOL_CORE, "PC NETWORK PROGRAM 1.0"},
28 {PROTOCOL_COREPLUS, "MICROSOFT NETWORKS 1.03"},
29 {PROTOCOL_LANMAN1, "MICROSOFT NETWORKS 3.0"},
30 {PROTOCOL_LANMAN1, "LANMAN1.0"},
31 {PROTOCOL_LANMAN2, "LM1.2X002"},
32 {PROTOCOL_LANMAN2, "DOS LANMAN2.1"},
33 {PROTOCOL_LANMAN2, "LANMAN2.1"},
34 {PROTOCOL_LANMAN2, "Samba"},
35 {PROTOCOL_NT1, "NT LANMAN 1.0"},
36 {PROTOCOL_NT1, "NT LM 0.12"},
39 #define STAR_SMBSERVER "*SMBSERVER"
42 * Set the user session key for a connection
43 * @param cli The cli structure to add it too
44 * @param session_key The session key used. (A copy of this is taken for the cli struct)
48 static void cli_set_session_key (struct cli_state *cli, const DATA_BLOB session_key)
50 cli->user_session_key = data_blob(session_key.data, session_key.length);
53 /****************************************************************************
54 Do an old lanman2 style session setup.
55 ****************************************************************************/
57 static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli,
59 const char *pass, size_t passlen,
60 const char *workgroup)
62 DATA_BLOB session_key = data_blob_null;
63 DATA_BLOB lm_response = data_blob_null;
67 if (passlen > sizeof(pword)-1) {
68 return NT_STATUS_INVALID_PARAMETER;
71 /* LANMAN servers predate NT status codes and Unicode and ignore those
72 smb flags so we must disable the corresponding default capabilities
73 that would otherwise cause the Unicode and NT Status flags to be
74 set (and even returned by the server) */
76 cli->capabilities &= ~(CAP_UNICODE | CAP_STATUS32);
78 /* if in share level security then don't send a password now */
79 if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL))
82 if (passlen > 0 && (cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen != 24) {
83 /* Encrypted mode needed, and non encrypted password supplied. */
84 lm_response = data_blob(NULL, 24);
85 if (!SMBencrypt(pass, cli->secblob.data,(uchar *)lm_response.data)) {
86 DEBUG(1, ("Password is > 14 chars in length, and is therefore incompatible with Lanman authentication\n"));
87 return NT_STATUS_ACCESS_DENIED;
89 } else if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen == 24) {
90 /* Encrypted mode needed, and encrypted password supplied. */
91 lm_response = data_blob(pass, passlen);
92 } else if (passlen > 0) {
93 /* Plaintext mode needed, assume plaintext supplied. */
94 passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE);
95 lm_response = data_blob(pass, passlen);
98 /* send a session setup command */
99 memset(cli->outbuf,'\0',smb_size);
100 cli_set_message(cli->outbuf,10, 0, True);
101 SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
102 cli_setup_packet(cli);
104 SCVAL(cli->outbuf,smb_vwv0,0xFF);
105 SSVAL(cli->outbuf,smb_vwv2,cli->max_xmit);
106 SSVAL(cli->outbuf,smb_vwv3,2);
107 SSVAL(cli->outbuf,smb_vwv4,1);
108 SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
109 SSVAL(cli->outbuf,smb_vwv7,lm_response.length);
111 p = smb_buf(cli->outbuf);
112 memcpy(p,lm_response.data,lm_response.length);
113 p += lm_response.length;
114 p += clistr_push(cli, p, user, -1, STR_TERMINATE|STR_UPPER);
115 p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE|STR_UPPER);
116 p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
117 p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE);
118 cli_setup_bcc(cli, p);
120 if (!cli_send_smb(cli) || !cli_receive_smb(cli)) {
121 return cli_nt_error(cli);
124 show_msg(cli->inbuf);
126 if (cli_is_error(cli)) {
127 return cli_nt_error(cli);
130 /* use the returned vuid from now on */
131 cli->vuid = SVAL(cli->inbuf,smb_uid);
132 fstrcpy(cli->user_name, user);
134 if (session_key.data) {
135 /* Have plaintext orginal */
136 cli_set_session_key(cli, session_key);
142 /****************************************************************************
143 Work out suitable capabilities to offer the server.
144 ****************************************************************************/
146 static uint32 cli_session_setup_capabilities(struct cli_state *cli)
148 uint32 capabilities = CAP_NT_SMBS;
150 if (!cli->force_dos_errors)
151 capabilities |= CAP_STATUS32;
153 if (cli->use_level_II_oplocks)
154 capabilities |= CAP_LEVEL_II_OPLOCKS;
156 capabilities |= (cli->capabilities & (CAP_UNICODE|CAP_LARGE_FILES|CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_DFS));
160 /****************************************************************************
161 Do a NT1 guest session setup.
162 ****************************************************************************/
164 struct async_req *cli_session_setup_guest_send(TALLOC_CTX *mem_ctx,
165 struct event_context *ev,
166 struct cli_state *cli)
168 struct async_req *result;
172 SCVAL(vwv+0, 0, 0xFF);
175 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE);
177 SSVAL(vwv+4, 0, cli->pid);
178 SIVAL(vwv+5, 0, cli->sesskey);
183 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli));
185 bytes = talloc_array(talloc_tos(), uint8_t, 0);
187 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "", 1, /* username */
189 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "", 1, /* workgroup */
191 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Unix",
192 strlen("Unix")+1, NULL);
193 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Samba",
194 strlen("Samba")+1, NULL);
200 result = cli_request_send(mem_ctx, ev, cli, SMBsesssetupX, 0,
201 13, vwv, 0, talloc_get_size(bytes), bytes);
206 NTSTATUS cli_session_setup_guest_recv(struct async_req *req)
208 struct cli_request *cli_req = talloc_get_type_abort(
209 req->private_data, struct cli_request);
210 struct cli_state *cli = cli_req->cli;
218 if (async_req_is_nterror(req, &status)) {
222 status = cli_pull_reply(req, &wct, &vwv, &num_bytes, &bytes);
223 if (!NT_STATUS_IS_OK(status)) {
229 cli->vuid = SVAL(cli_req->inbuf, smb_uid);
231 p += clistr_pull(cli_req->inbuf, cli->server_os, (char *)p,
232 sizeof(fstring), bytes+num_bytes-p, STR_TERMINATE);
233 p += clistr_pull(cli_req->inbuf, cli->server_type, (char *)p,
234 sizeof(fstring), bytes+num_bytes-p, STR_TERMINATE);
235 p += clistr_pull(cli_req->inbuf, cli->server_domain, (char *)p,
236 sizeof(fstring), bytes+num_bytes-p, STR_TERMINATE);
238 if (strstr(cli->server_type, "Samba")) {
239 cli->is_samba = True;
242 fstrcpy(cli->user_name, "");
247 static NTSTATUS cli_session_setup_guest(struct cli_state *cli)
249 TALLOC_CTX *frame = talloc_stackframe();
250 struct event_context *ev;
251 struct async_req *req;
254 if (cli->fd_event != NULL) {
256 * Can't use sync call while an async call is in flight
258 status = NT_STATUS_INVALID_PARAMETER;
262 ev = event_context_init(frame);
264 status = NT_STATUS_NO_MEMORY;
268 req = cli_session_setup_guest_send(frame, ev, cli);
270 status = NT_STATUS_NO_MEMORY;
274 while (req->state < ASYNC_REQ_DONE) {
278 status = cli_session_setup_guest_recv(req);
284 /****************************************************************************
285 Do a NT1 plaintext session setup.
286 ****************************************************************************/
288 static NTSTATUS cli_session_setup_plaintext(struct cli_state *cli,
289 const char *user, const char *pass,
290 const char *workgroup)
292 uint32 capabilities = cli_session_setup_capabilities(cli);
296 fstr_sprintf( lanman, "Samba %s", samba_version_string());
298 memset(cli->outbuf, '\0', smb_size);
299 cli_set_message(cli->outbuf,13,0,True);
300 SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
301 cli_setup_packet(cli);
303 SCVAL(cli->outbuf,smb_vwv0,0xFF);
304 SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
305 SSVAL(cli->outbuf,smb_vwv3,2);
306 SSVAL(cli->outbuf,smb_vwv4,cli->pid);
307 SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
308 SSVAL(cli->outbuf,smb_vwv8,0);
309 SIVAL(cli->outbuf,smb_vwv11,capabilities);
310 p = smb_buf(cli->outbuf);
312 /* check wether to send the ASCII or UNICODE version of the password */
314 if ( (capabilities & CAP_UNICODE) == 0 ) {
315 p += clistr_push(cli, p, pass, -1, STR_TERMINATE); /* password */
316 SSVAL(cli->outbuf,smb_vwv7,PTR_DIFF(p, smb_buf(cli->outbuf)));
319 /* For ucs2 passwords clistr_push calls ucs2_align, which causes
320 * the space taken by the unicode password to be one byte too
321 * long (as we're on an odd byte boundary here). Reduce the
322 * count by 1 to cope with this. Fixes smbclient against NetApp
323 * servers which can't cope. Fix from
324 * bryan.kolodziej@allenlund.com in bug #3840.
326 p += clistr_push(cli, p, pass, -1, STR_UNICODE|STR_TERMINATE); /* unicode password */
327 SSVAL(cli->outbuf,smb_vwv8,PTR_DIFF(p, smb_buf(cli->outbuf))-1);
330 p += clistr_push(cli, p, user, -1, STR_TERMINATE); /* username */
331 p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE); /* workgroup */
332 p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
333 p += clistr_push(cli, p, lanman, -1, STR_TERMINATE);
334 cli_setup_bcc(cli, p);
336 if (!cli_send_smb(cli) || !cli_receive_smb(cli)) {
337 return cli_nt_error(cli);
340 show_msg(cli->inbuf);
342 if (cli_is_error(cli)) {
343 return cli_nt_error(cli);
346 cli->vuid = SVAL(cli->inbuf,smb_uid);
347 p = smb_buf(cli->inbuf);
348 p += clistr_pull(cli->inbuf, cli->server_os, p, sizeof(fstring),
350 p += clistr_pull(cli->inbuf, cli->server_type, p, sizeof(fstring),
352 p += clistr_pull(cli->inbuf, cli->server_domain, p, sizeof(fstring),
354 fstrcpy(cli->user_name, user);
356 if (strstr(cli->server_type, "Samba")) {
357 cli->is_samba = True;
363 /****************************************************************************
364 do a NT1 NTLM/LM encrypted session setup - for when extended security
366 @param cli client state to create do session setup on
368 @param pass *either* cleartext password (passlen !=24) or LM response.
369 @param ntpass NT response, implies ntpasslen >=24, implies pass is not clear
370 @param workgroup The user's domain.
371 ****************************************************************************/
373 static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user,
374 const char *pass, size_t passlen,
375 const char *ntpass, size_t ntpasslen,
376 const char *workgroup)
378 uint32 capabilities = cli_session_setup_capabilities(cli);
379 DATA_BLOB lm_response = data_blob_null;
380 DATA_BLOB nt_response = data_blob_null;
381 DATA_BLOB session_key = data_blob_null;
386 /* do nothing - guest login */
387 } else if (passlen != 24) {
388 if (lp_client_ntlmv2_auth()) {
389 DATA_BLOB server_chal;
390 DATA_BLOB names_blob;
391 server_chal = data_blob(cli->secblob.data, MIN(cli->secblob.length, 8));
393 /* note that the 'workgroup' here is a best guess - we don't know
394 the server's domain at this point. The 'server name' is also
397 names_blob = NTLMv2_generate_names_blob(cli->called.name, workgroup);
399 if (!SMBNTLMv2encrypt(user, workgroup, pass, &server_chal,
401 &lm_response, &nt_response, &session_key)) {
402 data_blob_free(&names_blob);
403 data_blob_free(&server_chal);
404 return NT_STATUS_ACCESS_DENIED;
406 data_blob_free(&names_blob);
407 data_blob_free(&server_chal);
411 E_md4hash(pass, nt_hash);
414 nt_response = data_blob_null;
416 nt_response = data_blob(NULL, 24);
417 SMBNTencrypt(pass,cli->secblob.data,nt_response.data);
419 /* non encrypted password supplied. Ignore ntpass. */
420 if (lp_client_lanman_auth()) {
421 lm_response = data_blob(NULL, 24);
422 if (!SMBencrypt(pass,cli->secblob.data, lm_response.data)) {
423 /* Oops, the LM response is invalid, just put
424 the NT response there instead */
425 data_blob_free(&lm_response);
426 lm_response = data_blob(nt_response.data, nt_response.length);
429 /* LM disabled, place NT# in LM field instead */
430 lm_response = data_blob(nt_response.data, nt_response.length);
433 session_key = data_blob(NULL, 16);
435 E_deshash(pass, session_key.data);
436 memset(&session_key.data[8], '\0', 8);
438 SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data);
442 cli_simple_set_signing(cli, session_key, lm_response);
444 cli_simple_set_signing(cli, session_key, nt_response);
447 /* pre-encrypted password supplied. Only used for
448 security=server, can't do
449 signing because we don't have original key */
451 lm_response = data_blob(pass, passlen);
452 nt_response = data_blob(ntpass, ntpasslen);
455 /* send a session setup command */
456 memset(cli->outbuf,'\0',smb_size);
458 cli_set_message(cli->outbuf,13,0,True);
459 SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
460 cli_setup_packet(cli);
462 SCVAL(cli->outbuf,smb_vwv0,0xFF);
463 SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
464 SSVAL(cli->outbuf,smb_vwv3,2);
465 SSVAL(cli->outbuf,smb_vwv4,cli->pid);
466 SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
467 SSVAL(cli->outbuf,smb_vwv7,lm_response.length);
468 SSVAL(cli->outbuf,smb_vwv8,nt_response.length);
469 SIVAL(cli->outbuf,smb_vwv11,capabilities);
470 p = smb_buf(cli->outbuf);
471 if (lm_response.length) {
472 memcpy(p,lm_response.data, lm_response.length); p += lm_response.length;
474 if (nt_response.length) {
475 memcpy(p,nt_response.data, nt_response.length); p += nt_response.length;
477 p += clistr_push(cli, p, user, -1, STR_TERMINATE);
479 /* Upper case here might help some NTLMv2 implementations */
480 p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE|STR_UPPER);
481 p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
482 p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE);
483 cli_setup_bcc(cli, p);
485 if (!cli_send_smb(cli) || !cli_receive_smb(cli)) {
486 result = cli_nt_error(cli);
490 /* show_msg(cli->inbuf); */
492 if (cli_is_error(cli)) {
493 result = cli_nt_error(cli);
497 /* use the returned vuid from now on */
498 cli->vuid = SVAL(cli->inbuf,smb_uid);
500 p = smb_buf(cli->inbuf);
501 p += clistr_pull(cli->inbuf, cli->server_os, p, sizeof(fstring),
503 p += clistr_pull(cli->inbuf, cli->server_type, p, sizeof(fstring),
505 p += clistr_pull(cli->inbuf, cli->server_domain, p, sizeof(fstring),
508 if (strstr(cli->server_type, "Samba")) {
509 cli->is_samba = True;
512 fstrcpy(cli->user_name, user);
514 if (session_key.data) {
515 /* Have plaintext orginal */
516 cli_set_session_key(cli, session_key);
519 result = NT_STATUS_OK;
521 data_blob_free(&lm_response);
522 data_blob_free(&nt_response);
523 data_blob_free(&session_key);
527 /****************************************************************************
528 Send a extended security session setup blob
529 ****************************************************************************/
531 static bool cli_session_setup_blob_send(struct cli_state *cli, DATA_BLOB blob)
533 uint32 capabilities = cli_session_setup_capabilities(cli);
536 capabilities |= CAP_EXTENDED_SECURITY;
538 /* send a session setup command */
539 memset(cli->outbuf,'\0',smb_size);
541 cli_set_message(cli->outbuf,12,0,True);
542 SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
544 cli_setup_packet(cli);
546 SCVAL(cli->outbuf,smb_vwv0,0xFF);
547 SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
548 SSVAL(cli->outbuf,smb_vwv3,2);
549 SSVAL(cli->outbuf,smb_vwv4,1);
550 SIVAL(cli->outbuf,smb_vwv5,0);
551 SSVAL(cli->outbuf,smb_vwv7,blob.length);
552 SIVAL(cli->outbuf,smb_vwv10,capabilities);
553 p = smb_buf(cli->outbuf);
554 memcpy(p, blob.data, blob.length);
556 p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
557 p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE);
558 cli_setup_bcc(cli, p);
559 return cli_send_smb(cli);
562 /****************************************************************************
563 Send a extended security session setup blob, returning a reply blob.
564 ****************************************************************************/
566 static DATA_BLOB cli_session_setup_blob_receive(struct cli_state *cli)
568 DATA_BLOB blob2 = data_blob_null;
572 if (!cli_receive_smb(cli))
575 show_msg(cli->inbuf);
577 if (cli_is_error(cli) && !NT_STATUS_EQUAL(cli_nt_error(cli),
578 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
582 /* use the returned vuid from now on */
583 cli->vuid = SVAL(cli->inbuf,smb_uid);
585 p = smb_buf(cli->inbuf);
587 blob2 = data_blob(p, SVAL(cli->inbuf, smb_vwv3));
590 p += clistr_pull(cli->inbuf, cli->server_os, p, sizeof(fstring),
593 /* w2k with kerberos doesn't properly null terminate this field */
594 len = smb_bufrem(cli->inbuf, p);
595 p += clistr_pull(cli->inbuf, cli->server_type, p, sizeof(fstring),
602 /****************************************************************************
603 Send a extended security session setup blob, returning a reply blob.
604 ****************************************************************************/
606 /* The following is calculated from :
608 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
609 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
613 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
615 static bool cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob)
617 int32 remaining = blob.length;
619 DATA_BLOB send_blob = data_blob_null;
620 int32 max_blob_size = 0;
621 DATA_BLOB receive_blob = data_blob_null;
623 if (cli->max_xmit < BASE_SESSSETUP_BLOB_PACKET_SIZE + 1) {
624 DEBUG(0,("cli_session_setup_blob: cli->max_xmit too small "
625 "(was %u, need minimum %u)\n",
626 (unsigned int)cli->max_xmit,
627 BASE_SESSSETUP_BLOB_PACKET_SIZE));
628 cli_set_nt_error(cli, NT_STATUS_INVALID_PARAMETER);
632 max_blob_size = cli->max_xmit - BASE_SESSSETUP_BLOB_PACKET_SIZE;
634 while ( remaining > 0) {
635 if (remaining >= max_blob_size) {
636 send_blob.length = max_blob_size;
637 remaining -= max_blob_size;
639 send_blob.length = remaining;
643 send_blob.data = &blob.data[cur];
644 cur += send_blob.length;
646 DEBUG(10, ("cli_session_setup_blob: Remaining (%u) sending (%u) current (%u)\n",
647 (unsigned int)remaining,
648 (unsigned int)send_blob.length,
649 (unsigned int)cur ));
651 if (!cli_session_setup_blob_send(cli, send_blob)) {
652 DEBUG(0, ("cli_session_setup_blob: send failed\n"));
656 receive_blob = cli_session_setup_blob_receive(cli);
657 data_blob_free(&receive_blob);
659 if (cli_is_error(cli) &&
660 !NT_STATUS_EQUAL( cli_get_nt_error(cli),
661 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
662 DEBUG(0, ("cli_session_setup_blob: receive failed "
663 "(%s)\n", nt_errstr(cli_get_nt_error(cli))));
672 /****************************************************************************
673 Use in-memory credentials cache
674 ****************************************************************************/
676 static void use_in_memory_ccache(void) {
677 setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1);
680 /****************************************************************************
681 Do a spnego/kerberos encrypted session setup.
682 ****************************************************************************/
684 static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli, const char *principal, const char *workgroup)
686 DATA_BLOB negTokenTarg;
687 DATA_BLOB session_key_krb5;
691 cli_temp_set_signing(cli);
693 DEBUG(2,("Doing kerberos session setup\n"));
695 /* generate the encapsulated kerberos5 ticket */
696 rc = spnego_gen_negTokenTarg(principal, 0, &negTokenTarg, &session_key_krb5, 0, NULL);
699 DEBUG(1, ("cli_session_setup_kerberos: spnego_gen_negTokenTarg failed: %s\n",
701 return ADS_ERROR_KRB5(rc);
705 file_save("negTokenTarg.dat", negTokenTarg.data, negTokenTarg.length);
708 if (!cli_session_setup_blob(cli, negTokenTarg)) {
709 nt_status = cli_nt_error(cli);
713 if (cli_is_error(cli)) {
714 nt_status = cli_nt_error(cli);
715 if (NT_STATUS_IS_OK(nt_status)) {
716 nt_status = NT_STATUS_UNSUCCESSFUL;
721 cli_set_session_key(cli, session_key_krb5);
723 if (cli_simple_set_signing(
724 cli, session_key_krb5, data_blob_null)) {
726 /* 'resign' the last message, so we get the right sequence numbers
727 for checking the first reply from the server */
728 cli_calculate_sign_mac(cli, cli->outbuf);
730 if (!cli_check_sign_mac(cli, cli->inbuf)) {
731 nt_status = NT_STATUS_ACCESS_DENIED;
736 data_blob_free(&negTokenTarg);
737 data_blob_free(&session_key_krb5);
739 return ADS_ERROR_NT(NT_STATUS_OK);
742 data_blob_free(&negTokenTarg);
743 data_blob_free(&session_key_krb5);
745 return ADS_ERROR_NT(nt_status);
747 #endif /* HAVE_KRB5 */
750 /****************************************************************************
751 Do a spnego/NTLMSSP encrypted session setup.
752 ****************************************************************************/
754 static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *user,
755 const char *pass, const char *domain)
757 struct ntlmssp_state *ntlmssp_state;
761 DATA_BLOB blob = data_blob_null;
762 DATA_BLOB blob_in = data_blob_null;
763 DATA_BLOB blob_out = data_blob_null;
765 cli_temp_set_signing(cli);
767 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_client_start(&ntlmssp_state))) {
770 ntlmssp_want_feature(ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY);
772 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) {
775 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) {
778 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_password(ntlmssp_state, pass))) {
783 nt_status = ntlmssp_update(ntlmssp_state,
785 data_blob_free(&blob_in);
786 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) || NT_STATUS_IS_OK(nt_status)) {
788 /* and wrap it in a SPNEGO wrapper */
789 msg1 = gen_negTokenInit(OID_NTLMSSP, blob_out);
791 /* wrap it in SPNEGO */
792 msg1 = spnego_gen_auth(blob_out);
795 /* now send that blob on its way */
796 if (!cli_session_setup_blob_send(cli, msg1)) {
797 DEBUG(3, ("Failed to send NTLMSSP/SPNEGO blob to server!\n"));
798 nt_status = NT_STATUS_UNSUCCESSFUL;
800 blob = cli_session_setup_blob_receive(cli);
802 nt_status = cli_nt_error(cli);
803 if (cli_is_error(cli) && NT_STATUS_IS_OK(nt_status)) {
804 if (cli->smb_rw_error == SMB_READ_BAD_SIG) {
805 nt_status = NT_STATUS_ACCESS_DENIED;
807 nt_status = NT_STATUS_UNSUCCESSFUL;
811 data_blob_free(&msg1);
815 if (NT_STATUS_IS_OK(nt_status)) {
816 nt_status = NT_STATUS_UNSUCCESSFUL;
818 } else if ((turn == 1) &&
819 NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
820 DATA_BLOB tmp_blob = data_blob_null;
821 /* the server might give us back two challenges */
822 if (!spnego_parse_challenge(blob, &blob_in,
824 DEBUG(3,("Failed to parse challenges\n"));
825 nt_status = NT_STATUS_INVALID_PARAMETER;
827 data_blob_free(&tmp_blob);
829 if (!spnego_parse_auth_response(blob, nt_status, OID_NTLMSSP,
831 DEBUG(3,("Failed to parse auth response\n"));
832 if (NT_STATUS_IS_OK(nt_status)
833 || NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED))
834 nt_status = NT_STATUS_INVALID_PARAMETER;
837 data_blob_free(&blob);
838 data_blob_free(&blob_out);
840 } while (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED));
842 data_blob_free(&blob_in);
844 if (NT_STATUS_IS_OK(nt_status)) {
846 fstrcpy(cli->server_domain, ntlmssp_state->server_domain);
847 cli_set_session_key(cli, ntlmssp_state->session_key);
849 if (cli_simple_set_signing(
850 cli, ntlmssp_state->session_key, data_blob_null)) {
852 /* 'resign' the last message, so we get the right sequence numbers
853 for checking the first reply from the server */
854 cli_calculate_sign_mac(cli, cli->outbuf);
856 if (!cli_check_sign_mac(cli, cli->inbuf)) {
857 nt_status = NT_STATUS_ACCESS_DENIED;
862 /* we have a reference conter on ntlmssp_state, if we are signing
863 then the state will be kept by the signing engine */
865 ntlmssp_end(&ntlmssp_state);
867 if (!NT_STATUS_IS_OK(nt_status)) {
873 /****************************************************************************
874 Do a spnego encrypted session setup.
876 user_domain: The shortname of the domain the user/machine is a member of.
877 dest_realm: The realm we're connecting to, if NULL we use our default realm.
878 ****************************************************************************/
880 ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user,
881 const char *pass, const char *user_domain,
882 const char * dest_realm)
884 char *principal = NULL;
885 char *OIDs[ASN1_MAX_OIDS];
888 const char *p = NULL;
889 char *account = NULL;
891 DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli->secblob.length));
893 /* the server might not even do spnego */
894 if (cli->secblob.length <= 16) {
895 DEBUG(3,("server didn't supply a full spnego negprot\n"));
900 file_save("negprot.dat", cli->secblob.data, cli->secblob.length);
903 /* there is 16 bytes of GUID before the real spnego packet starts */
904 blob = data_blob(cli->secblob.data+16, cli->secblob.length-16);
906 /* The server sent us the first part of the SPNEGO exchange in the
907 * negprot reply. It is WRONG to depend on the principal sent in the
908 * negprot reply, but right now we do it. If we don't receive one,
909 * we try to best guess, then fall back to NTLM. */
910 if (!spnego_parse_negTokenInit(blob, OIDs, &principal)) {
911 data_blob_free(&blob);
912 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
914 data_blob_free(&blob);
916 /* make sure the server understands kerberos */
917 for (i=0;OIDs[i];i++) {
918 DEBUG(3,("got OID=%s\n", OIDs[i]));
919 if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 ||
920 strcmp(OIDs[i], OID_KERBEROS5) == 0) {
921 cli->got_kerberos_mechanism = True;
923 talloc_free(OIDs[i]);
926 DEBUG(3,("got principal=%s\n", principal ? principal : "<null>"));
928 fstrcpy(cli->user_name, user);
931 /* If password is set we reauthenticate to kerberos server
932 * and do not store results */
934 if (cli->got_kerberos_mechanism && cli->use_kerberos) {
940 use_in_memory_ccache();
941 ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */, NULL);
944 TALLOC_FREE(principal);
945 DEBUG(0, ("Kinit failed: %s\n", error_message(ret)));
946 if (cli->fallback_after_kerberos)
948 return ADS_ERROR_KRB5(ret);
952 /* If we get a bad principal, try to guess it if
953 we have a valid host NetBIOS name.
955 if (strequal(principal, ADS_IGNORE_PRINCIPAL)) {
956 TALLOC_FREE(principal);
959 if (principal == NULL &&
960 !is_ipaddress(cli->desthost) &&
961 !strequal(STAR_SMBSERVER,
964 char *machine = NULL;
966 DEBUG(3,("cli_session_setup_spnego: got a "
967 "bad server principal, trying to guess ...\n"));
969 host = strchr_m(cli->desthost, '.');
971 machine = SMB_STRNDUP(cli->desthost,
972 host - cli->desthost);
974 machine = SMB_STRDUP(cli->desthost);
976 if (machine == NULL) {
977 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
981 realm = SMB_STRDUP(dest_realm);
984 realm = kerberos_get_default_realm_from_ccache();
986 if (realm && *realm) {
987 principal = talloc_asprintf(NULL, "%s$@%s",
992 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
994 DEBUG(3,("cli_session_setup_spnego: guessed "
995 "server principal=%s\n",
996 principal ? principal : "<null>"));
1003 rc = cli_session_setup_kerberos(cli, principal,
1005 if (ADS_ERR_OK(rc) || !cli->fallback_after_kerberos) {
1006 TALLOC_FREE(principal);
1013 TALLOC_FREE(principal);
1017 account = talloc_strdup(talloc_tos(), user);
1019 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1022 /* when falling back to ntlmssp while authenticating with a machine
1023 * account strip off the realm - gd */
1025 if ((p = strchr_m(user, '@')) != NULL) {
1026 account[PTR_DIFF(p,user)] = '\0';
1029 return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, account, pass, user_domain));
1032 /****************************************************************************
1033 Send a session setup. The username and workgroup is in UNIX character
1034 format and must be converted to DOS codepage format before sending. If the
1035 password is in plaintext, the same should be done.
1036 ****************************************************************************/
1038 NTSTATUS cli_session_setup(struct cli_state *cli,
1040 const char *pass, int passlen,
1041 const char *ntpass, int ntpasslen,
1042 const char *workgroup)
1048 fstrcpy(user2, user);
1057 /* allow for workgroups as part of the username */
1058 if ((p=strchr_m(user2,'\\')) || (p=strchr_m(user2,'/')) ||
1059 (p=strchr_m(user2,*lp_winbind_separator()))) {
1065 if (cli->protocol < PROTOCOL_LANMAN1) {
1066 return NT_STATUS_OK;
1069 /* now work out what sort of session setup we are going to
1070 do. I have split this into separate functions to make the
1071 flow a bit easier to understand (tridge) */
1073 /* if its an older server then we have to use the older request format */
1075 if (cli->protocol < PROTOCOL_NT1) {
1076 if (!lp_client_lanman_auth() && passlen != 24 && (*pass)) {
1077 DEBUG(1, ("Server requested LM password but 'client lanman auth'"
1079 return NT_STATUS_ACCESS_DENIED;
1082 if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 &&
1083 !lp_client_plaintext_auth() && (*pass)) {
1084 DEBUG(1, ("Server requested plaintext password but "
1085 "'client plaintext auth' is disabled\n"));
1086 return NT_STATUS_ACCESS_DENIED;
1089 return cli_session_setup_lanman2(cli, user, pass, passlen,
1093 /* if no user is supplied then we have to do an anonymous connection.
1094 passwords are ignored */
1096 if (!user || !*user)
1097 return cli_session_setup_guest(cli);
1099 /* if the server is share level then send a plaintext null
1100 password at this point. The password is sent in the tree
1103 if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0)
1104 return cli_session_setup_plaintext(cli, user, "", workgroup);
1106 /* if the server doesn't support encryption then we have to use
1107 plaintext. The second password is ignored */
1109 if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
1110 if (!lp_client_plaintext_auth() && (*pass)) {
1111 DEBUG(1, ("Server requested plaintext password but "
1112 "'client plaintext auth' is disabled\n"));
1113 return NT_STATUS_ACCESS_DENIED;
1115 return cli_session_setup_plaintext(cli, user, pass, workgroup);
1118 /* if the server supports extended security then use SPNEGO */
1120 if (cli->capabilities & CAP_EXTENDED_SECURITY) {
1121 ADS_STATUS status = cli_session_setup_spnego(cli, user, pass,
1123 if (!ADS_ERR_OK(status)) {
1124 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
1125 return ads_ntstatus(status);
1130 /* otherwise do a NT1 style session setup */
1131 status = cli_session_setup_nt1(cli, user, pass, passlen,
1132 ntpass, ntpasslen, workgroup);
1133 if (!NT_STATUS_IS_OK(status)) {
1134 DEBUG(3,("cli_session_setup: NT1 session setup "
1135 "failed: %s\n", nt_errstr(status)));
1140 if (strstr(cli->server_type, "Samba")) {
1141 cli->is_samba = True;
1144 return NT_STATUS_OK;
1147 /****************************************************************************
1149 *****************************************************************************/
1151 bool cli_ulogoff(struct cli_state *cli)
1153 memset(cli->outbuf,'\0',smb_size);
1154 cli_set_message(cli->outbuf,2,0,True);
1155 SCVAL(cli->outbuf,smb_com,SMBulogoffX);
1156 cli_setup_packet(cli);
1157 SSVAL(cli->outbuf,smb_vwv0,0xFF);
1158 SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */
1161 if (!cli_receive_smb(cli))
1164 if (cli_is_error(cli)) {
1172 /****************************************************************************
1174 ****************************************************************************/
1176 struct async_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
1177 struct event_context *ev,
1178 struct cli_state *cli,
1179 const char *share, const char *dev,
1180 const char *pass, int passlen)
1184 struct async_req *result;
1188 fstrcpy(cli->share, share);
1190 /* in user level security don't send a password now */
1191 if (cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
1194 } else if (pass == NULL) {
1195 DEBUG(1, ("Server not using user level security and no "
1196 "password supplied.\n"));
1200 if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
1201 *pass && passlen != 24) {
1202 if (!lp_client_lanman_auth()) {
1203 DEBUG(1, ("Server requested LANMAN password "
1204 "(share-level security) but "
1205 "'client lanman auth' is disabled\n"));
1210 * Non-encrypted passwords - convert to DOS codepage before
1214 SMBencrypt(pass, cli->secblob.data, (uchar *)pword);
1216 if((cli->sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL
1217 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE))
1219 if (!lp_client_plaintext_auth() && (*pass)) {
1220 DEBUG(1, ("Server requested plaintext "
1221 "password but 'client plaintext "
1222 "auth' is disabled\n"));
1227 * Non-encrypted passwords - convert to DOS codepage
1230 passlen = clistr_push(cli, pword, pass, sizeof(pword),
1234 memcpy(pword, pass, passlen);
1239 SCVAL(vwv+0, 0, 0xFF);
1242 SSVAL(vwv+2, 0, TCONX_FLAG_EXTENDED_RESPONSE);
1243 SSVAL(vwv+3, 0, passlen);
1246 bytes = (uint8_t *)talloc_memdup(talloc_tos(), pword, passlen);
1248 bytes = talloc_array(talloc_tos(), uint8_t, 0);
1254 tmp = talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
1255 cli->desthost, share);
1260 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1,
1265 * Add the devicetype
1267 tmp = talloc_strdup_upper(talloc_tos(), dev);
1272 bytes = smb_bytes_push_str(bytes, false, tmp, strlen(tmp)+1, NULL);
1275 if (bytes == NULL) {
1279 result = cli_request_send(mem_ctx, ev, cli, SMBtconX, 0,
1280 4, vwv, 0, talloc_get_size(bytes), bytes);
1285 result = async_req_new(mem_ctx);
1286 if (async_post_ntstatus(result, ev, NT_STATUS_ACCESS_DENIED)) {
1289 TALLOC_FREE(result);
1293 NTSTATUS cli_tcon_andx_recv(struct async_req *req)
1295 struct cli_request *cli_req = talloc_get_type_abort(
1296 req->private_data, struct cli_request);
1297 struct cli_state *cli = cli_req->cli;
1304 if (async_req_is_nterror(req, &status)) {
1308 status = cli_pull_reply(req, &wct, &vwv, &num_bytes, &bytes);
1309 if (!NT_STATUS_IS_OK(status)) {
1313 clistr_pull(cli_req->inbuf, cli->dev, bytes, sizeof(fstring),
1314 num_bytes, STR_TERMINATE|STR_ASCII);
1316 if ((cli->protocol >= PROTOCOL_NT1) && (num_bytes == 3)) {
1317 /* almost certainly win95 - enable bug fixes */
1322 * Make sure that we have the optional support 16-bit field. WCT > 2.
1323 * Avoids issues when connecting to Win9x boxes sharing files
1326 cli->dfsroot = false;
1328 if ((wct > 2) && (cli->protocol >= PROTOCOL_LANMAN2)) {
1329 cli->dfsroot = ((SVAL(vwv+2, 0) & SMB_SHARE_IN_DFS) != 0);
1332 cli->cnum = SVAL(cli_req->inbuf,smb_tid);
1333 return NT_STATUS_OK;
1336 NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
1337 const char *dev, const char *pass, int passlen)
1339 TALLOC_CTX *frame = talloc_stackframe();
1340 struct event_context *ev;
1341 struct async_req *req;
1344 if (cli->fd_event != NULL) {
1346 * Can't use sync call while an async call is in flight
1348 status = NT_STATUS_INVALID_PARAMETER;
1352 ev = event_context_init(frame);
1354 status = NT_STATUS_NO_MEMORY;
1358 req = cli_tcon_andx_send(frame, ev, cli, share, dev, pass, passlen);
1360 status = NT_STATUS_NO_MEMORY;
1364 while (req->state < ASYNC_REQ_DONE) {
1365 event_loop_once(ev);
1368 status = cli_tcon_andx_recv(req);
1374 /****************************************************************************
1375 Send a tree disconnect.
1376 ****************************************************************************/
1378 bool cli_tdis(struct cli_state *cli)
1380 memset(cli->outbuf,'\0',smb_size);
1381 cli_set_message(cli->outbuf,0,0,True);
1382 SCVAL(cli->outbuf,smb_com,SMBtdis);
1383 SSVAL(cli->outbuf,smb_tid,cli->cnum);
1384 cli_setup_packet(cli);
1387 if (!cli_receive_smb(cli))
1390 if (cli_is_error(cli)) {
1398 /****************************************************************************
1399 Send a negprot command.
1400 ****************************************************************************/
1402 void cli_negprot_sendsync(struct cli_state *cli)
1407 if (cli->protocol < PROTOCOL_NT1)
1408 cli->use_spnego = False;
1410 memset(cli->outbuf,'\0',smb_size);
1412 /* setup the protocol strings */
1413 cli_set_message(cli->outbuf,0,0,True);
1415 p = smb_buf(cli->outbuf);
1416 for (numprots=0; numprots < ARRAY_SIZE(prots); numprots++) {
1417 if (prots[numprots].prot > cli->protocol) {
1421 p += clistr_push(cli, p, prots[numprots].name, -1, STR_TERMINATE);
1424 SCVAL(cli->outbuf,smb_com,SMBnegprot);
1425 cli_setup_bcc(cli, p);
1426 cli_setup_packet(cli);
1428 SCVAL(smb_buf(cli->outbuf),0,2);
1433 /****************************************************************************
1434 Send a negprot command.
1435 ****************************************************************************/
1437 struct async_req *cli_negprot_send(TALLOC_CTX *mem_ctx,
1438 struct event_context *ev,
1439 struct cli_state *cli)
1441 struct async_req *result;
1442 uint8_t *bytes = NULL;
1445 if (cli->protocol < PROTOCOL_NT1)
1446 cli->use_spnego = False;
1448 /* setup the protocol strings */
1449 for (numprots=0; numprots < ARRAY_SIZE(prots); numprots++) {
1451 if (prots[numprots].prot > cli->protocol) {
1454 bytes = (uint8_t *)talloc_append_blob(
1455 talloc_tos(), bytes, data_blob_const(&c, sizeof(c)));
1456 if (bytes == NULL) {
1459 bytes = smb_bytes_push_str(bytes, false,
1460 prots[numprots].name,
1461 strlen(prots[numprots].name)+1,
1463 if (bytes == NULL) {
1468 result = cli_request_send(mem_ctx, ev, cli, SMBnegprot, 0, 0, NULL, 0,
1469 talloc_get_size(bytes), bytes);
1474 NTSTATUS cli_negprot_recv(struct async_req *req)
1476 struct cli_request *cli_req = talloc_get_type_abort(
1477 req->private_data, struct cli_request);
1478 struct cli_state *cli = cli_req->cli;
1486 if (async_req_is_nterror(req, &status)) {
1490 status = cli_pull_reply(req, &wct, &vwv, &num_bytes, &bytes);
1491 if (!NT_STATUS_IS_OK(status)) {
1495 protnum = SVAL(vwv, 0);
1497 if ((protnum >= ARRAY_SIZE(prots))
1498 || (prots[protnum].prot > cli_req->cli->protocol)) {
1499 return NT_STATUS_INVALID_NETWORK_RESPONSE;
1502 cli->protocol = prots[protnum].prot;
1504 if ((cli->protocol < PROTOCOL_NT1) && cli->sign_info.mandatory_signing) {
1505 DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n"));
1506 return NT_STATUS_ACCESS_DENIED;
1509 if (cli->protocol >= PROTOCOL_NT1) {
1512 cli->sec_mode = CVAL(vwv + 1, 0);
1513 cli->max_mux = SVAL(vwv + 1, 1);
1514 cli->max_xmit = IVAL(vwv + 3, 1);
1515 cli->sesskey = IVAL(vwv + 7, 1);
1516 cli->serverzone = SVALS(vwv + 15, 1);
1517 cli->serverzone *= 60;
1518 /* this time arrives in real GMT */
1519 ts = interpret_long_date(((char *)(vwv+11))+1);
1520 cli->servertime = ts.tv_sec;
1521 cli->secblob = data_blob(bytes, num_bytes);
1522 cli->capabilities = IVAL(vwv + 9, 1);
1523 if (cli->capabilities & CAP_RAW_MODE) {
1524 cli->readbraw_supported = True;
1525 cli->writebraw_supported = True;
1527 /* work out if they sent us a workgroup */
1528 if (!(cli->capabilities & CAP_EXTENDED_SECURITY) &&
1529 smb_buflen(cli->inbuf) > 8) {
1530 clistr_pull(cli->inbuf, cli->server_domain,
1531 bytes+8, sizeof(cli->server_domain),
1533 STR_UNICODE|STR_NOALIGN);
1537 * As signing is slow we only turn it on if either the client or
1538 * the server require it. JRA.
1541 if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) {
1542 /* Fail if server says signing is mandatory and we don't want to support it. */
1543 if (!cli->sign_info.allow_smb_signing) {
1544 DEBUG(0,("cli_negprot: SMB signing is mandatory and we have disabled it.\n"));
1545 return NT_STATUS_ACCESS_DENIED;
1547 cli->sign_info.negotiated_smb_signing = True;
1548 cli->sign_info.mandatory_signing = True;
1549 } else if (cli->sign_info.mandatory_signing && cli->sign_info.allow_smb_signing) {
1550 /* Fail if client says signing is mandatory and the server doesn't support it. */
1551 if (!(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) {
1552 DEBUG(1,("cli_negprot: SMB signing is mandatory and the server doesn't support it.\n"));
1553 return NT_STATUS_ACCESS_DENIED;
1555 cli->sign_info.negotiated_smb_signing = True;
1556 cli->sign_info.mandatory_signing = True;
1557 } else if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
1558 cli->sign_info.negotiated_smb_signing = True;
1561 if (cli->capabilities & (CAP_LARGE_READX|CAP_LARGE_WRITEX)) {
1562 SAFE_FREE(cli->outbuf);
1563 SAFE_FREE(cli->inbuf);
1564 cli->outbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN);
1565 cli->inbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN);
1566 cli->bufsize = CLI_SAMBA_MAX_LARGE_READX_SIZE + LARGE_WRITEX_HDR_SIZE;
1569 } else if (cli->protocol >= PROTOCOL_LANMAN1) {
1570 cli->use_spnego = False;
1571 cli->sec_mode = SVAL(vwv + 1, 0);
1572 cli->max_xmit = SVAL(vwv + 2, 0);
1573 cli->max_mux = SVAL(vwv + 3, 0);
1574 cli->sesskey = IVAL(vwv + 6, 0);
1575 cli->serverzone = SVALS(vwv + 10, 0);
1576 cli->serverzone *= 60;
1577 /* this time is converted to GMT by make_unix_date */
1578 cli->servertime = cli_make_unix_date(
1579 cli, (char *)(vwv + 8));
1580 cli->readbraw_supported = ((SVAL(vwv + 5, 0) & 0x1) != 0);
1581 cli->writebraw_supported = ((SVAL(vwv + 5, 0) & 0x2) != 0);
1582 cli->secblob = data_blob(bytes, num_bytes);
1584 /* the old core protocol */
1585 cli->use_spnego = False;
1587 cli->serverzone = get_time_zone(time(NULL));
1590 cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE);
1592 /* a way to force ascii SMB */
1593 if (getenv("CLI_FORCE_ASCII"))
1594 cli->capabilities &= ~CAP_UNICODE;
1596 return NT_STATUS_OK;
1599 NTSTATUS cli_negprot(struct cli_state *cli)
1601 TALLOC_CTX *frame = talloc_stackframe();
1602 struct event_context *ev;
1603 struct async_req *req;
1604 NTSTATUS status = NT_STATUS_NO_MEMORY;
1606 if (cli->fd_event != NULL) {
1608 * Can't use sync call while an async call is in flight
1610 cli_set_error(cli, NT_STATUS_INVALID_PARAMETER);
1614 ev = event_context_init(frame);
1619 req = cli_negprot_send(frame, ev, cli);
1624 while (req->state < ASYNC_REQ_DONE) {
1625 event_loop_once(ev);
1628 status = cli_negprot_recv(req);
1634 /****************************************************************************
1635 Send a session request. See rfc1002.txt 4.3 and 4.3.2.
1636 ****************************************************************************/
1638 bool cli_session_request(struct cli_state *cli,
1639 struct nmb_name *calling, struct nmb_name *called)
1644 /* 445 doesn't have session request */
1645 if (cli->port == 445)
1648 memcpy(&(cli->calling), calling, sizeof(*calling));
1649 memcpy(&(cli->called ), called , sizeof(*called ));
1651 /* put in the destination name */
1652 p = cli->outbuf+len;
1653 name_mangle(cli->called .name, p, cli->called .name_type);
1657 p = cli->outbuf+len;
1658 name_mangle(cli->calling.name, p, cli->calling.name_type);
1661 /* send a session request (RFC 1002) */
1662 /* setup the packet length
1663 * Remove four bytes from the length count, since the length
1664 * field in the NBT Session Service header counts the number
1665 * of bytes which follow. The cli_send_smb() function knows
1666 * about this and accounts for those four bytes.
1670 _smb_setlen(cli->outbuf,len);
1671 SCVAL(cli->outbuf,0,0x81);
1674 DEBUG(5,("Sent session request\n"));
1676 if (!cli_receive_smb(cli))
1679 if (CVAL(cli->inbuf,0) == 0x84) {
1680 /* C. Hoch 9/14/95 Start */
1681 /* For information, here is the response structure.
1682 * We do the byte-twiddling to for portability.
1683 struct RetargetResponse{
1685 unsigned char flags;
1691 uint16_t port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9);
1692 struct in_addr dest_ip;
1695 /* SESSION RETARGET */
1696 putip((char *)&dest_ip,cli->inbuf+4);
1697 in_addr_to_sockaddr_storage(&cli->dest_ss, dest_ip);
1699 status = open_socket_out(&cli->dest_ss, port,
1700 LONG_CONNECT_TIMEOUT, &cli->fd);
1701 if (!NT_STATUS_IS_OK(status)) {
1705 DEBUG(3,("Retargeted\n"));
1707 set_socket_options(cli->fd, lp_socket_options());
1714 DEBUG(0,("Retarget recursion - failing\n"));
1718 ret = cli_session_request(cli, calling, called);
1722 } /* C. Hoch 9/14/95 End */
1724 if (CVAL(cli->inbuf,0) != 0x82) {
1725 /* This is the wrong place to put the error... JRA. */
1726 cli->rap_error = CVAL(cli->inbuf,4);
1732 static void smb_sock_connected(struct async_req *req)
1734 int *pfd = (int *)req->async.priv;
1738 status = open_socket_out_defer_recv(req, &fd);
1739 if (NT_STATUS_IS_OK(status)) {
1744 static NTSTATUS open_smb_socket(const struct sockaddr_storage *pss,
1745 uint16_t *port, int timeout, int *pfd)
1747 struct event_context *ev;
1748 struct async_req *r139, *r445;
1754 return open_socket_out(pss, *port, timeout, pfd);
1757 ev = event_context_init(talloc_tos());
1759 return NT_STATUS_NO_MEMORY;
1762 r445 = open_socket_out_defer_send(ev, ev, timeval_set(0, 0),
1764 r139 = open_socket_out_defer_send(ev, ev, timeval_set(0, 3000),
1766 if ((r445 == NULL) || (r139 == NULL)) {
1767 status = NT_STATUS_NO_MEMORY;
1770 r445->async.fn = smb_sock_connected;
1771 r445->async.priv = &fd445;
1772 r139->async.fn = smb_sock_connected;
1773 r139->async.priv = &fd139;
1775 while ((fd139 == -1) && (r139->state < ASYNC_REQ_DONE)
1776 && (fd445 == -1) && (r445->state < ASYNC_REQ_DONE)) {
1777 event_loop_once(ev);
1780 if ((fd139 != -1) && (fd445 != -1)) {
1788 status = NT_STATUS_OK;
1794 status = NT_STATUS_OK;
1798 status = open_socket_out_defer_recv(r445, &fd445);
1804 /****************************************************************************
1805 Open the client sockets.
1806 ****************************************************************************/
1808 NTSTATUS cli_connect(struct cli_state *cli,
1810 struct sockaddr_storage *dest_ss)
1813 int name_type = 0x20;
1814 TALLOC_CTX *frame = talloc_stackframe();
1815 unsigned int num_addrs = 0;
1817 struct sockaddr_storage *ss_arr = NULL;
1820 /* reasonable default hostname */
1822 host = STAR_SMBSERVER;
1825 fstrcpy(cli->desthost, host);
1827 /* allow hostnames of the form NAME#xx and do a netbios lookup */
1828 if ((p = strchr(cli->desthost, '#'))) {
1829 name_type = strtol(p+1, NULL, 16);
1833 if (!dest_ss || is_zero_addr((struct sockaddr *)dest_ss)) {
1834 NTSTATUS status =resolve_name_list(frame,
1839 if (!NT_STATUS_IS_OK(status)) {
1841 return NT_STATUS_BAD_NETWORK_NAME;
1845 ss_arr = TALLOC_P(frame, struct sockaddr_storage);
1848 return NT_STATUS_NO_MEMORY;
1853 for (i = 0; i < num_addrs; i++) {
1854 cli->dest_ss = ss_arr[i];
1855 if (getenv("LIBSMB_PROG")) {
1856 cli->fd = sock_exec(getenv("LIBSMB_PROG"));
1858 uint16_t port = cli->port;
1860 status = open_smb_socket(&cli->dest_ss, &port,
1861 cli->timeout, &cli->fd);
1862 if (NT_STATUS_IS_OK(status)) {
1866 if (cli->fd == -1) {
1867 char addr[INET6_ADDRSTRLEN];
1868 print_sockaddr(addr, sizeof(addr), &ss_arr[i]);
1869 DEBUG(2,("Error connecting to %s (%s)\n",
1870 dest_ss?addr:host,strerror(errno)));
1872 /* Exit from loop on first connection. */
1877 if (cli->fd == -1) {
1879 return map_nt_error_from_unix(errno);
1883 *dest_ss = cli->dest_ss;
1886 set_socket_options(cli->fd, lp_socket_options());
1889 return NT_STATUS_OK;
1893 establishes a connection to after the negprot.
1894 @param output_cli A fully initialised cli structure, non-null only on success
1895 @param dest_host The netbios name of the remote host
1896 @param dest_ss (optional) The the destination IP, NULL for name based lookup
1897 @param port (optional) The destination port (0 for default)
1898 @param retry bool. Did this connection fail with a retryable error ?
1901 NTSTATUS cli_start_connection(struct cli_state **output_cli,
1902 const char *my_name,
1903 const char *dest_host,
1904 struct sockaddr_storage *dest_ss, int port,
1905 int signing_state, int flags,
1909 struct nmb_name calling;
1910 struct nmb_name called;
1911 struct cli_state *cli;
1912 struct sockaddr_storage ss;
1918 my_name = global_myname();
1920 if (!(cli = cli_initialise())) {
1921 return NT_STATUS_NO_MEMORY;
1924 make_nmb_name(&calling, my_name, 0x0);
1925 make_nmb_name(&called , dest_host, 0x20);
1927 cli_set_port(cli, port);
1928 cli_set_timeout(cli, 10000); /* 10 seconds. */
1938 DEBUG(3,("Connecting to host=%s\n", dest_host));
1940 nt_status = cli_connect(cli, dest_host, &ss);
1941 if (!NT_STATUS_IS_OK(nt_status)) {
1942 char addr[INET6_ADDRSTRLEN];
1943 print_sockaddr(addr, sizeof(addr), &ss);
1944 DEBUG(1,("cli_start_connection: failed to connect to %s (%s). Error %s\n",
1945 nmb_namestr(&called), addr, nt_errstr(nt_status) ));
1953 if (!cli_session_request(cli, &calling, &called)) {
1955 DEBUG(1,("session request to %s failed (%s)\n",
1956 called.name, cli_errstr(cli)));
1957 if ((p=strchr(called.name, '.')) && !is_ipaddress(called.name)) {
1961 if (strcmp(called.name, STAR_SMBSERVER)) {
1962 make_nmb_name(&called , STAR_SMBSERVER, 0x20);
1965 return NT_STATUS_BAD_NETWORK_NAME;
1968 cli_setup_signing_state(cli, signing_state);
1970 if (flags & CLI_FULL_CONNECTION_DONT_SPNEGO)
1971 cli->use_spnego = False;
1972 else if (flags & CLI_FULL_CONNECTION_USE_KERBEROS)
1973 cli->use_kerberos = True;
1975 if ((flags & CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS) &&
1976 cli->use_kerberos) {
1977 cli->fallback_after_kerberos = true;
1980 nt_status = cli_negprot(cli);
1981 if (!NT_STATUS_IS_OK(nt_status)) {
1982 DEBUG(1, ("failed negprot: %s\n", nt_errstr(nt_status)));
1988 return NT_STATUS_OK;
1993 establishes a connection right up to doing tconX, password specified.
1994 @param output_cli A fully initialised cli structure, non-null only on success
1995 @param dest_host The netbios name of the remote host
1996 @param dest_ip (optional) The the destination IP, NULL for name based lookup
1997 @param port (optional) The destination port (0 for default)
1998 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
1999 @param service_type The 'type' of serivice.
2000 @param user Username, unix string
2001 @param domain User's domain
2002 @param password User's password, unencrypted unix string.
2003 @param retry bool. Did this connection fail with a retryable error ?
2006 NTSTATUS cli_full_connection(struct cli_state **output_cli,
2007 const char *my_name,
2008 const char *dest_host,
2009 struct sockaddr_storage *dest_ss, int port,
2010 const char *service, const char *service_type,
2011 const char *user, const char *domain,
2012 const char *password, int flags,
2017 struct cli_state *cli = NULL;
2018 int pw_len = password ? strlen(password)+1 : 0;
2022 if (password == NULL) {
2026 nt_status = cli_start_connection(&cli, my_name, dest_host,
2027 dest_ss, port, signing_state,
2030 if (!NT_STATUS_IS_OK(nt_status)) {
2034 nt_status = cli_session_setup(cli, user, password, pw_len, password,
2036 if (!NT_STATUS_IS_OK(nt_status)) {
2038 if (!(flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
2039 DEBUG(1,("failed session setup with %s\n",
2040 nt_errstr(nt_status)));
2045 nt_status = cli_session_setup(cli, "", "", 0, "", 0, domain);
2046 if (!NT_STATUS_IS_OK(nt_status)) {
2047 DEBUG(1,("anonymous failed session setup with %s\n",
2048 nt_errstr(nt_status)));
2055 nt_status = cli_tcon_andx(cli, service, service_type, password,
2057 if (!NT_STATUS_IS_OK(nt_status)) {
2058 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status)));
2060 if (NT_STATUS_IS_OK(nt_status)) {
2061 nt_status = NT_STATUS_UNSUCCESSFUL;
2067 cli_init_creds(cli, user, domain, password);
2070 return NT_STATUS_OK;
2073 /****************************************************************************
2074 Attempt a NetBIOS session request, falling back to *SMBSERVER if needed.
2075 ****************************************************************************/
2077 bool attempt_netbios_session_request(struct cli_state **ppcli, const char *srchost, const char *desthost,
2078 struct sockaddr_storage *pdest_ss)
2080 struct nmb_name calling, called;
2082 make_nmb_name(&calling, srchost, 0x0);
2085 * If the called name is an IP address
2086 * then use *SMBSERVER immediately.
2089 if(is_ipaddress(desthost)) {
2090 make_nmb_name(&called, STAR_SMBSERVER, 0x20);
2092 make_nmb_name(&called, desthost, 0x20);
2095 if (!cli_session_request(*ppcli, &calling, &called)) {
2097 struct nmb_name smbservername;
2099 make_nmb_name(&smbservername, STAR_SMBSERVER, 0x20);
2102 * If the name wasn't *SMBSERVER then
2103 * try with *SMBSERVER if the first name fails.
2106 if (nmb_name_equal(&called, &smbservername)) {
2109 * The name used was *SMBSERVER, don't bother with another name.
2112 DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \
2113 with error %s.\n", desthost, cli_errstr(*ppcli) ));
2118 cli_shutdown(*ppcli);
2120 *ppcli = cli_initialise();
2122 /* Out of memory... */
2126 status = cli_connect(*ppcli, desthost, pdest_ss);
2127 if (!NT_STATUS_IS_OK(status) ||
2128 !cli_session_request(*ppcli, &calling, &smbservername)) {
2129 DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \
2130 name *SMBSERVER with error %s\n", desthost, cli_errstr(*ppcli) ));
2138 /****************************************************************************
2139 Send an old style tcon.
2140 ****************************************************************************/
2141 NTSTATUS cli_raw_tcon(struct cli_state *cli,
2142 const char *service, const char *pass, const char *dev,
2143 uint16 *max_xmit, uint16 *tid)
2147 if (!lp_client_plaintext_auth() && (*pass)) {
2148 DEBUG(1, ("Server requested plaintext password but 'client "
2149 "plaintext auth' is disabled\n"));
2150 return NT_STATUS_ACCESS_DENIED;
2153 memset(cli->outbuf,'\0',smb_size);
2154 memset(cli->inbuf,'\0',smb_size);
2156 cli_set_message(cli->outbuf, 0, 0, True);
2157 SCVAL(cli->outbuf,smb_com,SMBtcon);
2158 cli_setup_packet(cli);
2160 p = smb_buf(cli->outbuf);
2161 *p++ = 4; p += clistr_push(cli, p, service, -1, STR_TERMINATE | STR_NOALIGN);
2162 *p++ = 4; p += clistr_push(cli, p, pass, -1, STR_TERMINATE | STR_NOALIGN);
2163 *p++ = 4; p += clistr_push(cli, p, dev, -1, STR_TERMINATE | STR_NOALIGN);
2165 cli_setup_bcc(cli, p);
2168 if (!cli_receive_smb(cli)) {
2169 return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
2172 if (cli_is_error(cli)) {
2173 return cli_nt_error(cli);
2176 *max_xmit = SVAL(cli->inbuf, smb_vwv0);
2177 *tid = SVAL(cli->inbuf, smb_vwv1);
2179 return NT_STATUS_OK;
2182 /* Return a cli_state pointing at the IPC$ share for the given server */
2184 struct cli_state *get_ipc_connect(char *server,
2185 struct sockaddr_storage *server_ss,
2186 const struct user_auth_info *user_info)
2188 struct cli_state *cli;
2190 uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
2192 if (user_info->use_kerberos) {
2193 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
2196 nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC",
2197 user_info->username ? user_info->username : "",
2199 user_info->password ? user_info->password : "",
2203 if (NT_STATUS_IS_OK(nt_status)) {
2205 } else if (is_ipaddress(server)) {
2206 /* windows 9* needs a correct NMB name for connections */
2207 fstring remote_name;
2209 if (name_status_find("*", 0, 0, server_ss, remote_name)) {
2210 cli = get_ipc_connect(remote_name, server_ss, user_info);
2219 * Given the IP address of a master browser on the network, return its
2220 * workgroup and connect to it.
2222 * This function is provided to allow additional processing beyond what
2223 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
2224 * browsers and obtain each master browsers' list of domains (in case the
2225 * first master browser is recently on the network and has not yet
2226 * synchronized with other master browsers and therefore does not yet have the
2227 * entire network browse list)
2230 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
2231 struct ip_service *mb_ip,
2232 const struct user_auth_info *user_info,
2233 char **pp_workgroup_out)
2235 char addr[INET6_ADDRSTRLEN];
2237 struct cli_state *cli;
2238 struct sockaddr_storage server_ss;
2240 *pp_workgroup_out = NULL;
2242 print_sockaddr(addr, sizeof(addr), &mb_ip->ss);
2243 DEBUG(99, ("Looking up name of master browser %s\n",
2247 * Do a name status query to find out the name of the master browser.
2248 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
2249 * master browser will not respond to a wildcard query (or, at least,
2250 * an NT4 server acting as the domain master browser will not).
2252 * We might be able to use ONLY the query on MSBROWSE, but that's not
2253 * yet been tested with all Windows versions, so until it is, leave
2254 * the original wildcard query as the first choice and fall back to
2255 * MSBROWSE if the wildcard query fails.
2257 if (!name_status_find("*", 0, 0x1d, &mb_ip->ss, name) &&
2258 !name_status_find(MSBROWSE, 1, 0x1d, &mb_ip->ss, name)) {
2260 DEBUG(99, ("Could not retrieve name status for %s\n",
2265 if (!find_master_ip(name, &server_ss)) {
2266 DEBUG(99, ("Could not find master ip for %s\n", name));
2270 *pp_workgroup_out = talloc_strdup(ctx, name);
2272 DEBUG(4, ("found master browser %s, %s\n", name, addr));
2274 print_sockaddr(addr, sizeof(addr), &server_ss);
2275 cli = get_ipc_connect(addr, &server_ss, user_info);
2281 * Return the IP address and workgroup of a master browser on the network, and
2285 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
2286 const struct user_auth_info *user_info,
2287 char **pp_workgroup_out)
2289 struct ip_service *ip_list;
2290 struct cli_state *cli;
2293 *pp_workgroup_out = NULL;
2295 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
2297 /* Go looking for workgroups by broadcasting on the local network */
2299 if (!NT_STATUS_IS_OK(name_resolve_bcast(MSBROWSE, 1, &ip_list,
2301 DEBUG(99, ("No master browsers responded\n"));
2305 for (i = 0; i < count; i++) {
2306 char addr[INET6_ADDRSTRLEN];
2307 print_sockaddr(addr, sizeof(addr), &ip_list[i].ss);
2308 DEBUG(99, ("Found master browser %s\n", addr));
2310 cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
2311 user_info, pp_workgroup_out);