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_error(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 bool cli_send_tconX(struct cli_state *cli,
1177 const char *share, const char *dev, const char *pass, int passlen)
1179 fstring fullshare, pword;
1181 memset(cli->outbuf,'\0',smb_size);
1182 memset(cli->inbuf,'\0',smb_size);
1184 fstrcpy(cli->share, share);
1186 /* in user level security don't send a password now */
1187 if (cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
1191 DEBUG(1, ("Server not using user level security and no password supplied.\n"));
1195 if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
1196 *pass && passlen != 24) {
1197 if (!lp_client_lanman_auth()) {
1198 DEBUG(1, ("Server requested LANMAN password "
1199 "(share-level security) but "
1200 "'client lanman auth' is disabled\n"));
1205 * Non-encrypted passwords - convert to DOS codepage before encryption.
1208 SMBencrypt(pass,cli->secblob.data,(uchar *)pword);
1210 if((cli->sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL|NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)) == 0) {
1211 if (!lp_client_plaintext_auth() && (*pass)) {
1212 DEBUG(1, ("Server requested plaintext "
1213 "password but 'client plaintext "
1214 "auth' is disabled\n"));
1219 * Non-encrypted passwords - convert to DOS codepage before using.
1221 passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE);
1225 memcpy(pword, pass, passlen);
1230 slprintf(fullshare, sizeof(fullshare)-1,
1231 "\\\\%s\\%s", cli->desthost, share);
1233 cli_set_message(cli->outbuf,4, 0, True);
1234 SCVAL(cli->outbuf,smb_com,SMBtconX);
1235 cli_setup_packet(cli);
1237 SSVAL(cli->outbuf,smb_vwv0,0xFF);
1238 SSVAL(cli->outbuf,smb_vwv2,TCONX_FLAG_EXTENDED_RESPONSE);
1239 SSVAL(cli->outbuf,smb_vwv3,passlen);
1241 p = smb_buf(cli->outbuf);
1243 memcpy(p,pword,passlen);
1246 p += clistr_push(cli, p, fullshare, -1, STR_TERMINATE |STR_UPPER);
1247 p += clistr_push(cli, p, dev, -1, STR_TERMINATE |STR_UPPER | STR_ASCII);
1249 cli_setup_bcc(cli, p);
1252 if (!cli_receive_smb(cli))
1255 if (cli_is_error(cli))
1258 clistr_pull(cli->inbuf, cli->dev, smb_buf(cli->inbuf), sizeof(fstring),
1259 -1, STR_TERMINATE|STR_ASCII);
1261 if (cli->protocol >= PROTOCOL_NT1 &&
1262 smb_buflen(cli->inbuf) == 3) {
1263 /* almost certainly win95 - enable bug fixes */
1267 /* Make sure that we have the optional support 16-bit field. WCT > 2 */
1268 /* Avoids issues when connecting to Win9x boxes sharing files */
1270 cli->dfsroot = False;
1271 if ( (CVAL(cli->inbuf, smb_wct))>2 && cli->protocol >= PROTOCOL_LANMAN2 )
1272 cli->dfsroot = (SVAL( cli->inbuf, smb_vwv2 ) & SMB_SHARE_IN_DFS) ? True : False;
1274 cli->cnum = SVAL(cli->inbuf,smb_tid);
1278 /****************************************************************************
1279 Send a tree disconnect.
1280 ****************************************************************************/
1282 bool cli_tdis(struct cli_state *cli)
1284 memset(cli->outbuf,'\0',smb_size);
1285 cli_set_message(cli->outbuf,0,0,True);
1286 SCVAL(cli->outbuf,smb_com,SMBtdis);
1287 SSVAL(cli->outbuf,smb_tid,cli->cnum);
1288 cli_setup_packet(cli);
1291 if (!cli_receive_smb(cli))
1294 if (cli_is_error(cli)) {
1302 /****************************************************************************
1303 Send a negprot command.
1304 ****************************************************************************/
1306 void cli_negprot_sendsync(struct cli_state *cli)
1311 if (cli->protocol < PROTOCOL_NT1)
1312 cli->use_spnego = False;
1314 memset(cli->outbuf,'\0',smb_size);
1316 /* setup the protocol strings */
1317 cli_set_message(cli->outbuf,0,0,True);
1319 p = smb_buf(cli->outbuf);
1320 for (numprots=0; numprots < ARRAY_SIZE(prots); numprots++) {
1321 if (prots[numprots].prot > cli->protocol) {
1325 p += clistr_push(cli, p, prots[numprots].name, -1, STR_TERMINATE);
1328 SCVAL(cli->outbuf,smb_com,SMBnegprot);
1329 cli_setup_bcc(cli, p);
1330 cli_setup_packet(cli);
1332 SCVAL(smb_buf(cli->outbuf),0,2);
1337 /****************************************************************************
1338 Send a negprot command.
1339 ****************************************************************************/
1341 struct async_req *cli_negprot_send(TALLOC_CTX *mem_ctx,
1342 struct event_context *ev,
1343 struct cli_state *cli)
1345 struct async_req *result;
1346 uint8_t *bytes = NULL;
1349 if (cli->protocol < PROTOCOL_NT1)
1350 cli->use_spnego = False;
1352 /* setup the protocol strings */
1353 for (numprots=0; numprots < ARRAY_SIZE(prots); numprots++) {
1355 if (prots[numprots].prot > cli->protocol) {
1358 bytes = (uint8_t *)talloc_append_blob(
1359 talloc_tos(), bytes, data_blob_const(&c, sizeof(c)));
1360 if (bytes == NULL) {
1363 bytes = smb_bytes_push_str(bytes, false,
1364 prots[numprots].name,
1365 strlen(prots[numprots].name)+1,
1367 if (bytes == NULL) {
1372 result = cli_request_send(mem_ctx, ev, cli, SMBnegprot, 0, 0, NULL, 0,
1373 talloc_get_size(bytes), bytes);
1378 NTSTATUS cli_negprot_recv(struct async_req *req)
1380 struct cli_request *cli_req = talloc_get_type_abort(
1381 req->private_data, struct cli_request);
1382 struct cli_state *cli = cli_req->cli;
1390 if (async_req_is_error(req, &status)) {
1394 status = cli_pull_reply(req, &wct, &vwv, &num_bytes, &bytes);
1395 if (!NT_STATUS_IS_OK(status)) {
1399 protnum = SVAL(vwv, 0);
1401 if ((protnum >= ARRAY_SIZE(prots))
1402 || (prots[protnum].prot > cli_req->cli->protocol)) {
1403 return NT_STATUS_INVALID_NETWORK_RESPONSE;
1406 cli->protocol = prots[protnum].prot;
1408 if ((cli->protocol < PROTOCOL_NT1) && cli->sign_info.mandatory_signing) {
1409 DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n"));
1410 return NT_STATUS_ACCESS_DENIED;
1413 if (cli->protocol >= PROTOCOL_NT1) {
1416 cli->sec_mode = CVAL(vwv + 1, 0);
1417 cli->max_mux = SVAL(vwv + 1, 1);
1418 cli->max_xmit = IVAL(vwv + 3, 1);
1419 cli->sesskey = IVAL(vwv + 7, 1);
1420 cli->serverzone = SVALS(vwv + 15, 1);
1421 cli->serverzone *= 60;
1422 /* this time arrives in real GMT */
1423 ts = interpret_long_date(((char *)(vwv+11))+1);
1424 cli->servertime = ts.tv_sec;
1425 cli->secblob = data_blob(bytes, num_bytes);
1426 cli->capabilities = IVAL(vwv + 9, 1);
1427 if (cli->capabilities & CAP_RAW_MODE) {
1428 cli->readbraw_supported = True;
1429 cli->writebraw_supported = True;
1431 /* work out if they sent us a workgroup */
1432 if (!(cli->capabilities & CAP_EXTENDED_SECURITY) &&
1433 smb_buflen(cli->inbuf) > 8) {
1434 clistr_pull(cli->inbuf, cli->server_domain,
1435 bytes+8, sizeof(cli->server_domain),
1437 STR_UNICODE|STR_NOALIGN);
1441 * As signing is slow we only turn it on if either the client or
1442 * the server require it. JRA.
1445 if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) {
1446 /* Fail if server says signing is mandatory and we don't want to support it. */
1447 if (!cli->sign_info.allow_smb_signing) {
1448 DEBUG(0,("cli_negprot: SMB signing is mandatory and we have disabled it.\n"));
1449 return NT_STATUS_ACCESS_DENIED;
1451 cli->sign_info.negotiated_smb_signing = True;
1452 cli->sign_info.mandatory_signing = True;
1453 } else if (cli->sign_info.mandatory_signing && cli->sign_info.allow_smb_signing) {
1454 /* Fail if client says signing is mandatory and the server doesn't support it. */
1455 if (!(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) {
1456 DEBUG(1,("cli_negprot: SMB signing is mandatory and the server doesn't support it.\n"));
1457 return NT_STATUS_ACCESS_DENIED;
1459 cli->sign_info.negotiated_smb_signing = True;
1460 cli->sign_info.mandatory_signing = True;
1461 } else if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
1462 cli->sign_info.negotiated_smb_signing = True;
1465 if (cli->capabilities & (CAP_LARGE_READX|CAP_LARGE_WRITEX)) {
1466 SAFE_FREE(cli->outbuf);
1467 SAFE_FREE(cli->inbuf);
1468 cli->outbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN);
1469 cli->inbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN);
1470 cli->bufsize = CLI_SAMBA_MAX_LARGE_READX_SIZE + LARGE_WRITEX_HDR_SIZE;
1473 } else if (cli->protocol >= PROTOCOL_LANMAN1) {
1474 cli->use_spnego = False;
1475 cli->sec_mode = SVAL(vwv + 1, 0);
1476 cli->max_xmit = SVAL(vwv + 2, 0);
1477 cli->max_mux = SVAL(vwv + 3, 0);
1478 cli->sesskey = IVAL(vwv + 6, 0);
1479 cli->serverzone = SVALS(vwv + 10, 0);
1480 cli->serverzone *= 60;
1481 /* this time is converted to GMT by make_unix_date */
1482 cli->servertime = cli_make_unix_date(
1483 cli, (char *)(vwv + 8));
1484 cli->readbraw_supported = ((SVAL(vwv + 5, 0) & 0x1) != 0);
1485 cli->writebraw_supported = ((SVAL(vwv + 5, 0) & 0x2) != 0);
1486 cli->secblob = data_blob(bytes, num_bytes);
1488 /* the old core protocol */
1489 cli->use_spnego = False;
1491 cli->serverzone = get_time_zone(time(NULL));
1494 cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE);
1496 /* a way to force ascii SMB */
1497 if (getenv("CLI_FORCE_ASCII"))
1498 cli->capabilities &= ~CAP_UNICODE;
1500 return NT_STATUS_OK;
1503 NTSTATUS cli_negprot(struct cli_state *cli)
1505 TALLOC_CTX *frame = talloc_stackframe();
1506 struct event_context *ev;
1507 struct async_req *req;
1508 NTSTATUS status = NT_STATUS_NO_MEMORY;
1510 if (cli->fd_event != NULL) {
1512 * Can't use sync call while an async call is in flight
1514 cli_set_error(cli, NT_STATUS_INVALID_PARAMETER);
1518 ev = event_context_init(frame);
1523 req = cli_negprot_send(frame, ev, cli);
1528 while (req->state < ASYNC_REQ_DONE) {
1529 event_loop_once(ev);
1532 status = cli_negprot_recv(req);
1538 /****************************************************************************
1539 Send a session request. See rfc1002.txt 4.3 and 4.3.2.
1540 ****************************************************************************/
1542 bool cli_session_request(struct cli_state *cli,
1543 struct nmb_name *calling, struct nmb_name *called)
1548 /* 445 doesn't have session request */
1549 if (cli->port == 445)
1552 memcpy(&(cli->calling), calling, sizeof(*calling));
1553 memcpy(&(cli->called ), called , sizeof(*called ));
1555 /* put in the destination name */
1556 p = cli->outbuf+len;
1557 name_mangle(cli->called .name, p, cli->called .name_type);
1561 p = cli->outbuf+len;
1562 name_mangle(cli->calling.name, p, cli->calling.name_type);
1565 /* send a session request (RFC 1002) */
1566 /* setup the packet length
1567 * Remove four bytes from the length count, since the length
1568 * field in the NBT Session Service header counts the number
1569 * of bytes which follow. The cli_send_smb() function knows
1570 * about this and accounts for those four bytes.
1574 _smb_setlen(cli->outbuf,len);
1575 SCVAL(cli->outbuf,0,0x81);
1578 DEBUG(5,("Sent session request\n"));
1580 if (!cli_receive_smb(cli))
1583 if (CVAL(cli->inbuf,0) == 0x84) {
1584 /* C. Hoch 9/14/95 Start */
1585 /* For information, here is the response structure.
1586 * We do the byte-twiddling to for portability.
1587 struct RetargetResponse{
1589 unsigned char flags;
1595 uint16_t port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9);
1596 struct in_addr dest_ip;
1599 /* SESSION RETARGET */
1600 putip((char *)&dest_ip,cli->inbuf+4);
1601 in_addr_to_sockaddr_storage(&cli->dest_ss, dest_ip);
1603 status = open_socket_out(&cli->dest_ss, port,
1604 LONG_CONNECT_TIMEOUT, &cli->fd);
1605 if (!NT_STATUS_IS_OK(status)) {
1609 DEBUG(3,("Retargeted\n"));
1611 set_socket_options(cli->fd, lp_socket_options());
1618 DEBUG(0,("Retarget recursion - failing\n"));
1622 ret = cli_session_request(cli, calling, called);
1626 } /* C. Hoch 9/14/95 End */
1628 if (CVAL(cli->inbuf,0) != 0x82) {
1629 /* This is the wrong place to put the error... JRA. */
1630 cli->rap_error = CVAL(cli->inbuf,4);
1636 static void smb_sock_connected(struct async_req *req)
1638 int *pfd = (int *)req->async.priv;
1642 status = open_socket_out_defer_recv(req, &fd);
1643 if (NT_STATUS_IS_OK(status)) {
1648 static NTSTATUS open_smb_socket(const struct sockaddr_storage *pss,
1649 uint16_t *port, int timeout, int *pfd)
1651 struct event_context *ev;
1652 struct async_req *r139, *r445;
1658 return open_socket_out(pss, *port, timeout, pfd);
1661 ev = event_context_init(talloc_tos());
1663 return NT_STATUS_NO_MEMORY;
1666 r445 = open_socket_out_defer_send(ev, ev, timeval_set(0, 0),
1668 r139 = open_socket_out_defer_send(ev, ev, timeval_set(0, 3000),
1670 if ((r445 == NULL) || (r139 == NULL)) {
1671 status = NT_STATUS_NO_MEMORY;
1674 r445->async.fn = smb_sock_connected;
1675 r445->async.priv = &fd445;
1676 r139->async.fn = smb_sock_connected;
1677 r139->async.priv = &fd139;
1679 while ((fd139 == -1) && (r139->state < ASYNC_REQ_DONE)
1680 && (fd445 == -1) && (r445->state < ASYNC_REQ_DONE)) {
1681 event_loop_once(ev);
1684 if ((fd139 != -1) && (fd445 != -1)) {
1692 status = NT_STATUS_OK;
1698 status = NT_STATUS_OK;
1702 status = open_socket_out_defer_recv(r445, &fd445);
1708 /****************************************************************************
1709 Open the client sockets.
1710 ****************************************************************************/
1712 NTSTATUS cli_connect(struct cli_state *cli,
1714 struct sockaddr_storage *dest_ss)
1717 int name_type = 0x20;
1718 TALLOC_CTX *frame = talloc_stackframe();
1719 unsigned int num_addrs = 0;
1721 struct sockaddr_storage *ss_arr = NULL;
1724 /* reasonable default hostname */
1726 host = STAR_SMBSERVER;
1729 fstrcpy(cli->desthost, host);
1731 /* allow hostnames of the form NAME#xx and do a netbios lookup */
1732 if ((p = strchr(cli->desthost, '#'))) {
1733 name_type = strtol(p+1, NULL, 16);
1737 if (!dest_ss || is_zero_addr((struct sockaddr *)dest_ss)) {
1738 NTSTATUS status =resolve_name_list(frame,
1743 if (!NT_STATUS_IS_OK(status)) {
1745 return NT_STATUS_BAD_NETWORK_NAME;
1749 ss_arr = TALLOC_P(frame, struct sockaddr_storage);
1752 return NT_STATUS_NO_MEMORY;
1757 for (i = 0; i < num_addrs; i++) {
1758 cli->dest_ss = ss_arr[i];
1759 if (getenv("LIBSMB_PROG")) {
1760 cli->fd = sock_exec(getenv("LIBSMB_PROG"));
1762 uint16_t port = cli->port;
1764 status = open_smb_socket(&cli->dest_ss, &port,
1765 cli->timeout, &cli->fd);
1766 if (NT_STATUS_IS_OK(status)) {
1770 if (cli->fd == -1) {
1771 char addr[INET6_ADDRSTRLEN];
1772 print_sockaddr(addr, sizeof(addr), &ss_arr[i]);
1773 DEBUG(2,("Error connecting to %s (%s)\n",
1774 dest_ss?addr:host,strerror(errno)));
1776 /* Exit from loop on first connection. */
1781 if (cli->fd == -1) {
1783 return map_nt_error_from_unix(errno);
1787 *dest_ss = cli->dest_ss;
1790 set_socket_options(cli->fd, lp_socket_options());
1793 return NT_STATUS_OK;
1797 establishes a connection to after the negprot.
1798 @param output_cli A fully initialised cli structure, non-null only on success
1799 @param dest_host The netbios name of the remote host
1800 @param dest_ss (optional) The the destination IP, NULL for name based lookup
1801 @param port (optional) The destination port (0 for default)
1802 @param retry bool. Did this connection fail with a retryable error ?
1805 NTSTATUS cli_start_connection(struct cli_state **output_cli,
1806 const char *my_name,
1807 const char *dest_host,
1808 struct sockaddr_storage *dest_ss, int port,
1809 int signing_state, int flags,
1813 struct nmb_name calling;
1814 struct nmb_name called;
1815 struct cli_state *cli;
1816 struct sockaddr_storage ss;
1822 my_name = global_myname();
1824 if (!(cli = cli_initialise())) {
1825 return NT_STATUS_NO_MEMORY;
1828 make_nmb_name(&calling, my_name, 0x0);
1829 make_nmb_name(&called , dest_host, 0x20);
1831 cli_set_port(cli, port);
1832 cli_set_timeout(cli, 10000); /* 10 seconds. */
1842 DEBUG(3,("Connecting to host=%s\n", dest_host));
1844 nt_status = cli_connect(cli, dest_host, &ss);
1845 if (!NT_STATUS_IS_OK(nt_status)) {
1846 char addr[INET6_ADDRSTRLEN];
1847 print_sockaddr(addr, sizeof(addr), &ss);
1848 DEBUG(1,("cli_start_connection: failed to connect to %s (%s). Error %s\n",
1849 nmb_namestr(&called), addr, nt_errstr(nt_status) ));
1857 if (!cli_session_request(cli, &calling, &called)) {
1859 DEBUG(1,("session request to %s failed (%s)\n",
1860 called.name, cli_errstr(cli)));
1861 if ((p=strchr(called.name, '.')) && !is_ipaddress(called.name)) {
1865 if (strcmp(called.name, STAR_SMBSERVER)) {
1866 make_nmb_name(&called , STAR_SMBSERVER, 0x20);
1869 return NT_STATUS_BAD_NETWORK_NAME;
1872 cli_setup_signing_state(cli, signing_state);
1874 if (flags & CLI_FULL_CONNECTION_DONT_SPNEGO)
1875 cli->use_spnego = False;
1876 else if (flags & CLI_FULL_CONNECTION_USE_KERBEROS)
1877 cli->use_kerberos = True;
1879 if ((flags & CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS) &&
1880 cli->use_kerberos) {
1881 cli->fallback_after_kerberos = true;
1884 nt_status = cli_negprot(cli);
1885 if (!NT_STATUS_IS_OK(nt_status)) {
1886 DEBUG(1, ("failed negprot: %s\n", nt_errstr(nt_status)));
1892 return NT_STATUS_OK;
1897 establishes a connection right up to doing tconX, password specified.
1898 @param output_cli A fully initialised cli structure, non-null only on success
1899 @param dest_host The netbios name of the remote host
1900 @param dest_ip (optional) The the destination IP, NULL for name based lookup
1901 @param port (optional) The destination port (0 for default)
1902 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
1903 @param service_type The 'type' of serivice.
1904 @param user Username, unix string
1905 @param domain User's domain
1906 @param password User's password, unencrypted unix string.
1907 @param retry bool. Did this connection fail with a retryable error ?
1910 NTSTATUS cli_full_connection(struct cli_state **output_cli,
1911 const char *my_name,
1912 const char *dest_host,
1913 struct sockaddr_storage *dest_ss, int port,
1914 const char *service, const char *service_type,
1915 const char *user, const char *domain,
1916 const char *password, int flags,
1921 struct cli_state *cli = NULL;
1922 int pw_len = password ? strlen(password)+1 : 0;
1926 if (password == NULL) {
1930 nt_status = cli_start_connection(&cli, my_name, dest_host,
1931 dest_ss, port, signing_state,
1934 if (!NT_STATUS_IS_OK(nt_status)) {
1938 nt_status = cli_session_setup(cli, user, password, pw_len, password,
1940 if (!NT_STATUS_IS_OK(nt_status)) {
1942 if (!(flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
1943 DEBUG(1,("failed session setup with %s\n",
1944 nt_errstr(nt_status)));
1949 nt_status = cli_session_setup(cli, "", "", 0, "", 0, domain);
1950 if (!NT_STATUS_IS_OK(nt_status)) {
1951 DEBUG(1,("anonymous failed session setup with %s\n",
1952 nt_errstr(nt_status)));
1959 if (!cli_send_tconX(cli, service, service_type, password, pw_len)) {
1960 nt_status = cli_nt_error(cli);
1961 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status)));
1963 if (NT_STATUS_IS_OK(nt_status)) {
1964 nt_status = NT_STATUS_UNSUCCESSFUL;
1970 cli_init_creds(cli, user, domain, password);
1973 return NT_STATUS_OK;
1976 /****************************************************************************
1977 Attempt a NetBIOS session request, falling back to *SMBSERVER if needed.
1978 ****************************************************************************/
1980 bool attempt_netbios_session_request(struct cli_state **ppcli, const char *srchost, const char *desthost,
1981 struct sockaddr_storage *pdest_ss)
1983 struct nmb_name calling, called;
1985 make_nmb_name(&calling, srchost, 0x0);
1988 * If the called name is an IP address
1989 * then use *SMBSERVER immediately.
1992 if(is_ipaddress(desthost)) {
1993 make_nmb_name(&called, STAR_SMBSERVER, 0x20);
1995 make_nmb_name(&called, desthost, 0x20);
1998 if (!cli_session_request(*ppcli, &calling, &called)) {
2000 struct nmb_name smbservername;
2002 make_nmb_name(&smbservername, STAR_SMBSERVER, 0x20);
2005 * If the name wasn't *SMBSERVER then
2006 * try with *SMBSERVER if the first name fails.
2009 if (nmb_name_equal(&called, &smbservername)) {
2012 * The name used was *SMBSERVER, don't bother with another name.
2015 DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \
2016 with error %s.\n", desthost, cli_errstr(*ppcli) ));
2021 cli_shutdown(*ppcli);
2023 *ppcli = cli_initialise();
2025 /* Out of memory... */
2029 status = cli_connect(*ppcli, desthost, pdest_ss);
2030 if (!NT_STATUS_IS_OK(status) ||
2031 !cli_session_request(*ppcli, &calling, &smbservername)) {
2032 DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \
2033 name *SMBSERVER with error %s\n", desthost, cli_errstr(*ppcli) ));
2041 /****************************************************************************
2042 Send an old style tcon.
2043 ****************************************************************************/
2044 NTSTATUS cli_raw_tcon(struct cli_state *cli,
2045 const char *service, const char *pass, const char *dev,
2046 uint16 *max_xmit, uint16 *tid)
2050 if (!lp_client_plaintext_auth() && (*pass)) {
2051 DEBUG(1, ("Server requested plaintext password but 'client "
2052 "plaintext auth' is disabled\n"));
2053 return NT_STATUS_ACCESS_DENIED;
2056 memset(cli->outbuf,'\0',smb_size);
2057 memset(cli->inbuf,'\0',smb_size);
2059 cli_set_message(cli->outbuf, 0, 0, True);
2060 SCVAL(cli->outbuf,smb_com,SMBtcon);
2061 cli_setup_packet(cli);
2063 p = smb_buf(cli->outbuf);
2064 *p++ = 4; p += clistr_push(cli, p, service, -1, STR_TERMINATE | STR_NOALIGN);
2065 *p++ = 4; p += clistr_push(cli, p, pass, -1, STR_TERMINATE | STR_NOALIGN);
2066 *p++ = 4; p += clistr_push(cli, p, dev, -1, STR_TERMINATE | STR_NOALIGN);
2068 cli_setup_bcc(cli, p);
2071 if (!cli_receive_smb(cli)) {
2072 return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
2075 if (cli_is_error(cli)) {
2076 return cli_nt_error(cli);
2079 *max_xmit = SVAL(cli->inbuf, smb_vwv0);
2080 *tid = SVAL(cli->inbuf, smb_vwv1);
2082 return NT_STATUS_OK;
2085 /* Return a cli_state pointing at the IPC$ share for the given server */
2087 struct cli_state *get_ipc_connect(char *server,
2088 struct sockaddr_storage *server_ss,
2089 const struct user_auth_info *user_info)
2091 struct cli_state *cli;
2093 uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
2095 if (user_info->use_kerberos) {
2096 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
2099 nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC",
2100 user_info->username ? user_info->username : "",
2102 user_info->password ? user_info->password : "",
2106 if (NT_STATUS_IS_OK(nt_status)) {
2108 } else if (is_ipaddress(server)) {
2109 /* windows 9* needs a correct NMB name for connections */
2110 fstring remote_name;
2112 if (name_status_find("*", 0, 0, server_ss, remote_name)) {
2113 cli = get_ipc_connect(remote_name, server_ss, user_info);
2122 * Given the IP address of a master browser on the network, return its
2123 * workgroup and connect to it.
2125 * This function is provided to allow additional processing beyond what
2126 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
2127 * browsers and obtain each master browsers' list of domains (in case the
2128 * first master browser is recently on the network and has not yet
2129 * synchronized with other master browsers and therefore does not yet have the
2130 * entire network browse list)
2133 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
2134 struct ip_service *mb_ip,
2135 const struct user_auth_info *user_info,
2136 char **pp_workgroup_out)
2138 char addr[INET6_ADDRSTRLEN];
2140 struct cli_state *cli;
2141 struct sockaddr_storage server_ss;
2143 *pp_workgroup_out = NULL;
2145 print_sockaddr(addr, sizeof(addr), &mb_ip->ss);
2146 DEBUG(99, ("Looking up name of master browser %s\n",
2150 * Do a name status query to find out the name of the master browser.
2151 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
2152 * master browser will not respond to a wildcard query (or, at least,
2153 * an NT4 server acting as the domain master browser will not).
2155 * We might be able to use ONLY the query on MSBROWSE, but that's not
2156 * yet been tested with all Windows versions, so until it is, leave
2157 * the original wildcard query as the first choice and fall back to
2158 * MSBROWSE if the wildcard query fails.
2160 if (!name_status_find("*", 0, 0x1d, &mb_ip->ss, name) &&
2161 !name_status_find(MSBROWSE, 1, 0x1d, &mb_ip->ss, name)) {
2163 DEBUG(99, ("Could not retrieve name status for %s\n",
2168 if (!find_master_ip(name, &server_ss)) {
2169 DEBUG(99, ("Could not find master ip for %s\n", name));
2173 *pp_workgroup_out = talloc_strdup(ctx, name);
2175 DEBUG(4, ("found master browser %s, %s\n", name, addr));
2177 print_sockaddr(addr, sizeof(addr), &server_ss);
2178 cli = get_ipc_connect(addr, &server_ss, user_info);
2184 * Return the IP address and workgroup of a master browser on the network, and
2188 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
2189 const struct user_auth_info *user_info,
2190 char **pp_workgroup_out)
2192 struct ip_service *ip_list;
2193 struct cli_state *cli;
2196 *pp_workgroup_out = NULL;
2198 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
2200 /* Go looking for workgroups by broadcasting on the local network */
2202 if (!NT_STATUS_IS_OK(name_resolve_bcast(MSBROWSE, 1, &ip_list,
2204 DEBUG(99, ("No master browsers responded\n"));
2208 for (i = 0; i < count; i++) {
2209 char addr[INET6_ADDRSTRLEN];
2210 print_sockaddr(addr, sizeof(addr), &ip_list[i].ss);
2211 DEBUG(99, ("Found master browser %s\n", addr));
2213 cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
2214 user_info, pp_workgroup_out);