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", 5, NULL);
192 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Samba", 6, NULL);
198 result = cli_request_send(mem_ctx, ev, cli, SMBsesssetupX, 0,
199 13, vwv, 0, talloc_get_size(bytes), bytes);
204 NTSTATUS cli_session_setup_guest_recv(struct async_req *req)
206 struct cli_request *cli_req = talloc_get_type_abort(
207 req->private_data, struct cli_request);
208 struct cli_state *cli = cli_req->cli;
216 if (async_req_is_nterror(req, &status)) {
220 status = cli_pull_reply(req, &wct, &vwv, &num_bytes, &bytes);
221 if (!NT_STATUS_IS_OK(status)) {
227 cli->vuid = SVAL(cli_req->inbuf, smb_uid);
229 p += clistr_pull(cli_req->inbuf, cli->server_os, (char *)p,
230 sizeof(fstring), bytes+num_bytes-p, STR_TERMINATE);
231 p += clistr_pull(cli_req->inbuf, cli->server_type, (char *)p,
232 sizeof(fstring), bytes+num_bytes-p, STR_TERMINATE);
233 p += clistr_pull(cli_req->inbuf, cli->server_domain, (char *)p,
234 sizeof(fstring), bytes+num_bytes-p, STR_TERMINATE);
236 if (strstr(cli->server_type, "Samba")) {
237 cli->is_samba = True;
240 fstrcpy(cli->user_name, "");
245 static NTSTATUS cli_session_setup_guest(struct cli_state *cli)
247 TALLOC_CTX *frame = talloc_stackframe();
248 struct event_context *ev;
249 struct async_req *req;
252 if (cli->fd_event != NULL) {
254 * Can't use sync call while an async call is in flight
256 status = NT_STATUS_INVALID_PARAMETER;
260 ev = event_context_init(frame);
262 status = NT_STATUS_NO_MEMORY;
266 req = cli_session_setup_guest_send(frame, ev, cli);
268 status = NT_STATUS_NO_MEMORY;
272 while (req->state < ASYNC_REQ_DONE) {
276 status = cli_session_setup_guest_recv(req);
282 /****************************************************************************
283 Do a NT1 plaintext session setup.
284 ****************************************************************************/
286 static NTSTATUS cli_session_setup_plaintext(struct cli_state *cli,
287 const char *user, const char *pass,
288 const char *workgroup)
290 uint32 capabilities = cli_session_setup_capabilities(cli);
294 fstr_sprintf( lanman, "Samba %s", samba_version_string());
296 memset(cli->outbuf, '\0', smb_size);
297 cli_set_message(cli->outbuf,13,0,True);
298 SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
299 cli_setup_packet(cli);
301 SCVAL(cli->outbuf,smb_vwv0,0xFF);
302 SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
303 SSVAL(cli->outbuf,smb_vwv3,2);
304 SSVAL(cli->outbuf,smb_vwv4,cli->pid);
305 SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
306 SSVAL(cli->outbuf,smb_vwv8,0);
307 SIVAL(cli->outbuf,smb_vwv11,capabilities);
308 p = smb_buf(cli->outbuf);
310 /* check wether to send the ASCII or UNICODE version of the password */
312 if ( (capabilities & CAP_UNICODE) == 0 ) {
313 p += clistr_push(cli, p, pass, -1, STR_TERMINATE); /* password */
314 SSVAL(cli->outbuf,smb_vwv7,PTR_DIFF(p, smb_buf(cli->outbuf)));
317 /* For ucs2 passwords clistr_push calls ucs2_align, which causes
318 * the space taken by the unicode password to be one byte too
319 * long (as we're on an odd byte boundary here). Reduce the
320 * count by 1 to cope with this. Fixes smbclient against NetApp
321 * servers which can't cope. Fix from
322 * bryan.kolodziej@allenlund.com in bug #3840.
324 p += clistr_push(cli, p, pass, -1, STR_UNICODE|STR_TERMINATE); /* unicode password */
325 SSVAL(cli->outbuf,smb_vwv8,PTR_DIFF(p, smb_buf(cli->outbuf))-1);
328 p += clistr_push(cli, p, user, -1, STR_TERMINATE); /* username */
329 p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE); /* workgroup */
330 p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
331 p += clistr_push(cli, p, lanman, -1, STR_TERMINATE);
332 cli_setup_bcc(cli, p);
334 if (!cli_send_smb(cli) || !cli_receive_smb(cli)) {
335 return cli_nt_error(cli);
338 show_msg(cli->inbuf);
340 if (cli_is_error(cli)) {
341 return cli_nt_error(cli);
344 cli->vuid = SVAL(cli->inbuf,smb_uid);
345 p = smb_buf(cli->inbuf);
346 p += clistr_pull(cli->inbuf, cli->server_os, p, sizeof(fstring),
348 p += clistr_pull(cli->inbuf, cli->server_type, p, sizeof(fstring),
350 p += clistr_pull(cli->inbuf, cli->server_domain, p, sizeof(fstring),
352 fstrcpy(cli->user_name, user);
354 if (strstr(cli->server_type, "Samba")) {
355 cli->is_samba = True;
361 /****************************************************************************
362 do a NT1 NTLM/LM encrypted session setup - for when extended security
364 @param cli client state to create do session setup on
366 @param pass *either* cleartext password (passlen !=24) or LM response.
367 @param ntpass NT response, implies ntpasslen >=24, implies pass is not clear
368 @param workgroup The user's domain.
369 ****************************************************************************/
371 static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user,
372 const char *pass, size_t passlen,
373 const char *ntpass, size_t ntpasslen,
374 const char *workgroup)
376 uint32 capabilities = cli_session_setup_capabilities(cli);
377 DATA_BLOB lm_response = data_blob_null;
378 DATA_BLOB nt_response = data_blob_null;
379 DATA_BLOB session_key = data_blob_null;
385 /* do nothing - guest login */
386 } else if (passlen != 24) {
387 if (lp_client_ntlmv2_auth()) {
388 DATA_BLOB server_chal;
389 DATA_BLOB names_blob;
390 server_chal = data_blob(cli->secblob.data, MIN(cli->secblob.length, 8));
392 /* note that the 'workgroup' here is a best guess - we don't know
393 the server's domain at this point. The 'server name' is also
396 names_blob = NTLMv2_generate_names_blob(cli->called.name, workgroup);
398 if (!SMBNTLMv2encrypt(user, workgroup, pass, &server_chal,
400 &lm_response, &nt_response, &session_key)) {
401 data_blob_free(&names_blob);
402 data_blob_free(&server_chal);
403 return NT_STATUS_ACCESS_DENIED;
405 data_blob_free(&names_blob);
406 data_blob_free(&server_chal);
410 E_md4hash(pass, nt_hash);
413 nt_response = data_blob_null;
415 nt_response = data_blob(NULL, 24);
416 SMBNTencrypt(pass,cli->secblob.data,nt_response.data);
418 /* non encrypted password supplied. Ignore ntpass. */
419 if (lp_client_lanman_auth()) {
420 lm_response = data_blob(NULL, 24);
421 if (!SMBencrypt(pass,cli->secblob.data, lm_response.data)) {
422 /* Oops, the LM response is invalid, just put
423 the NT response there instead */
424 data_blob_free(&lm_response);
425 lm_response = data_blob(nt_response.data, nt_response.length);
428 /* LM disabled, place NT# in LM field instead */
429 lm_response = data_blob(nt_response.data, nt_response.length);
432 session_key = data_blob(NULL, 16);
434 E_deshash(pass, session_key.data);
435 memset(&session_key.data[8], '\0', 8);
437 SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data);
440 cli_temp_set_signing(cli);
442 /* pre-encrypted password supplied. Only used for
443 security=server, can't do
444 signing because we don't have original key */
446 lm_response = data_blob(pass, passlen);
447 nt_response = data_blob(ntpass, ntpasslen);
450 /* send a session setup command */
451 memset(cli->outbuf,'\0',smb_size);
453 cli_set_message(cli->outbuf,13,0,True);
454 SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
455 cli_setup_packet(cli);
457 SCVAL(cli->outbuf,smb_vwv0,0xFF);
458 SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
459 SSVAL(cli->outbuf,smb_vwv3,2);
460 SSVAL(cli->outbuf,smb_vwv4,cli->pid);
461 SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
462 SSVAL(cli->outbuf,smb_vwv7,lm_response.length);
463 SSVAL(cli->outbuf,smb_vwv8,nt_response.length);
464 SIVAL(cli->outbuf,smb_vwv11,capabilities);
465 p = smb_buf(cli->outbuf);
466 if (lm_response.length) {
467 memcpy(p,lm_response.data, lm_response.length); p += lm_response.length;
469 if (nt_response.length) {
470 memcpy(p,nt_response.data, nt_response.length); p += nt_response.length;
472 p += clistr_push(cli, p, user, -1, STR_TERMINATE);
474 /* Upper case here might help some NTLMv2 implementations */
475 p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE|STR_UPPER);
476 p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
477 p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE);
478 cli_setup_bcc(cli, p);
480 if (!cli_send_smb(cli) || !cli_receive_smb(cli)) {
481 result = cli_nt_error(cli);
485 /* show_msg(cli->inbuf); */
487 if (cli_is_error(cli)) {
488 result = cli_nt_error(cli);
493 ok = cli_simple_set_signing(cli, session_key, lm_response);
495 ok = cli_simple_set_signing(cli, session_key, nt_response);
498 /* 'resign' the last message, so we get the right sequence numbers
499 for checking the first reply from the server */
500 cli_calculate_sign_mac(cli, cli->outbuf);
502 if (!cli_check_sign_mac(cli, cli->inbuf)) {
503 result = NT_STATUS_ACCESS_DENIED;
508 /* use the returned vuid from now on */
509 cli->vuid = SVAL(cli->inbuf,smb_uid);
511 p = smb_buf(cli->inbuf);
512 p += clistr_pull(cli->inbuf, cli->server_os, p, sizeof(fstring),
514 p += clistr_pull(cli->inbuf, cli->server_type, p, sizeof(fstring),
516 p += clistr_pull(cli->inbuf, cli->server_domain, p, sizeof(fstring),
519 if (strstr(cli->server_type, "Samba")) {
520 cli->is_samba = True;
523 fstrcpy(cli->user_name, user);
525 if (session_key.data) {
526 /* Have plaintext orginal */
527 cli_set_session_key(cli, session_key);
530 result = NT_STATUS_OK;
532 data_blob_free(&lm_response);
533 data_blob_free(&nt_response);
534 data_blob_free(&session_key);
538 /****************************************************************************
539 Send a extended security session setup blob
540 ****************************************************************************/
542 static bool cli_session_setup_blob_send(struct cli_state *cli, DATA_BLOB blob)
544 uint32 capabilities = cli_session_setup_capabilities(cli);
547 capabilities |= CAP_EXTENDED_SECURITY;
549 /* send a session setup command */
550 memset(cli->outbuf,'\0',smb_size);
552 cli_set_message(cli->outbuf,12,0,True);
553 SCVAL(cli->outbuf,smb_com,SMBsesssetupX);
555 cli_setup_packet(cli);
557 SCVAL(cli->outbuf,smb_vwv0,0xFF);
558 SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
559 SSVAL(cli->outbuf,smb_vwv3,2);
560 SSVAL(cli->outbuf,smb_vwv4,1);
561 SIVAL(cli->outbuf,smb_vwv5,0);
562 SSVAL(cli->outbuf,smb_vwv7,blob.length);
563 SIVAL(cli->outbuf,smb_vwv10,capabilities);
564 p = smb_buf(cli->outbuf);
565 memcpy(p, blob.data, blob.length);
567 p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
568 p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE);
569 cli_setup_bcc(cli, p);
570 return cli_send_smb(cli);
573 /****************************************************************************
574 Send a extended security session setup blob, returning a reply blob.
575 ****************************************************************************/
577 static DATA_BLOB cli_session_setup_blob_receive(struct cli_state *cli)
579 DATA_BLOB blob2 = data_blob_null;
583 if (!cli_receive_smb(cli))
586 show_msg(cli->inbuf);
588 if (cli_is_error(cli) && !NT_STATUS_EQUAL(cli_nt_error(cli),
589 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
593 /* use the returned vuid from now on */
594 cli->vuid = SVAL(cli->inbuf,smb_uid);
596 p = smb_buf(cli->inbuf);
598 blob2 = data_blob(p, SVAL(cli->inbuf, smb_vwv3));
601 p += clistr_pull(cli->inbuf, cli->server_os, p, sizeof(fstring),
604 /* w2k with kerberos doesn't properly null terminate this field */
605 len = smb_bufrem(cli->inbuf, p);
606 p += clistr_pull(cli->inbuf, cli->server_type, p, sizeof(fstring),
613 /****************************************************************************
614 Send a extended security session setup blob, returning a reply blob.
615 ****************************************************************************/
617 /* The following is calculated from :
619 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() )
620 * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at
624 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22)
626 static bool cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob)
628 int32 remaining = blob.length;
630 DATA_BLOB send_blob = data_blob_null;
631 int32 max_blob_size = 0;
632 DATA_BLOB receive_blob = data_blob_null;
634 if (cli->max_xmit < BASE_SESSSETUP_BLOB_PACKET_SIZE + 1) {
635 DEBUG(0,("cli_session_setup_blob: cli->max_xmit too small "
636 "(was %u, need minimum %u)\n",
637 (unsigned int)cli->max_xmit,
638 BASE_SESSSETUP_BLOB_PACKET_SIZE));
639 cli_set_nt_error(cli, NT_STATUS_INVALID_PARAMETER);
643 max_blob_size = cli->max_xmit - BASE_SESSSETUP_BLOB_PACKET_SIZE;
645 while ( remaining > 0) {
646 if (remaining >= max_blob_size) {
647 send_blob.length = max_blob_size;
648 remaining -= max_blob_size;
650 send_blob.length = remaining;
654 send_blob.data = &blob.data[cur];
655 cur += send_blob.length;
657 DEBUG(10, ("cli_session_setup_blob: Remaining (%u) sending (%u) current (%u)\n",
658 (unsigned int)remaining,
659 (unsigned int)send_blob.length,
660 (unsigned int)cur ));
662 if (!cli_session_setup_blob_send(cli, send_blob)) {
663 DEBUG(0, ("cli_session_setup_blob: send failed\n"));
667 receive_blob = cli_session_setup_blob_receive(cli);
668 data_blob_free(&receive_blob);
670 if (cli_is_error(cli) &&
671 !NT_STATUS_EQUAL( cli_get_nt_error(cli),
672 NT_STATUS_MORE_PROCESSING_REQUIRED)) {
673 DEBUG(0, ("cli_session_setup_blob: receive failed "
674 "(%s)\n", nt_errstr(cli_get_nt_error(cli))));
683 /****************************************************************************
684 Use in-memory credentials cache
685 ****************************************************************************/
687 static void use_in_memory_ccache(void) {
688 setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1);
691 /****************************************************************************
692 Do a spnego/kerberos encrypted session setup.
693 ****************************************************************************/
695 static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli, const char *principal, const char *workgroup)
697 DATA_BLOB negTokenTarg;
698 DATA_BLOB session_key_krb5;
702 cli_temp_set_signing(cli);
704 DEBUG(2,("Doing kerberos session setup\n"));
706 /* generate the encapsulated kerberos5 ticket */
707 rc = spnego_gen_negTokenTarg(principal, 0, &negTokenTarg, &session_key_krb5, 0, NULL);
710 DEBUG(1, ("cli_session_setup_kerberos: spnego_gen_negTokenTarg failed: %s\n",
712 return ADS_ERROR_KRB5(rc);
716 file_save("negTokenTarg.dat", negTokenTarg.data, negTokenTarg.length);
719 if (!cli_session_setup_blob(cli, negTokenTarg)) {
720 nt_status = cli_nt_error(cli);
724 if (cli_is_error(cli)) {
725 nt_status = cli_nt_error(cli);
726 if (NT_STATUS_IS_OK(nt_status)) {
727 nt_status = NT_STATUS_UNSUCCESSFUL;
732 cli_set_session_key(cli, session_key_krb5);
734 if (cli_simple_set_signing(
735 cli, session_key_krb5, data_blob_null)) {
737 /* 'resign' the last message, so we get the right sequence numbers
738 for checking the first reply from the server */
739 cli_calculate_sign_mac(cli, cli->outbuf);
741 if (!cli_check_sign_mac(cli, cli->inbuf)) {
742 nt_status = NT_STATUS_ACCESS_DENIED;
747 data_blob_free(&negTokenTarg);
748 data_blob_free(&session_key_krb5);
750 return ADS_ERROR_NT(NT_STATUS_OK);
753 data_blob_free(&negTokenTarg);
754 data_blob_free(&session_key_krb5);
756 return ADS_ERROR_NT(nt_status);
758 #endif /* HAVE_KRB5 */
761 /****************************************************************************
762 Do a spnego/NTLMSSP encrypted session setup.
763 ****************************************************************************/
765 static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *user,
766 const char *pass, const char *domain)
768 struct ntlmssp_state *ntlmssp_state;
772 DATA_BLOB blob = data_blob_null;
773 DATA_BLOB blob_in = data_blob_null;
774 DATA_BLOB blob_out = data_blob_null;
776 cli_temp_set_signing(cli);
778 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_client_start(&ntlmssp_state))) {
781 ntlmssp_want_feature(ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY);
783 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) {
786 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) {
789 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_password(ntlmssp_state, pass))) {
794 nt_status = ntlmssp_update(ntlmssp_state,
796 data_blob_free(&blob_in);
797 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) || NT_STATUS_IS_OK(nt_status)) {
799 /* and wrap it in a SPNEGO wrapper */
800 msg1 = gen_negTokenInit(OID_NTLMSSP, blob_out);
802 /* wrap it in SPNEGO */
803 msg1 = spnego_gen_auth(blob_out);
806 /* now send that blob on its way */
807 if (!cli_session_setup_blob_send(cli, msg1)) {
808 DEBUG(3, ("Failed to send NTLMSSP/SPNEGO blob to server!\n"));
809 nt_status = NT_STATUS_UNSUCCESSFUL;
811 blob = cli_session_setup_blob_receive(cli);
813 nt_status = cli_nt_error(cli);
814 if (cli_is_error(cli) && NT_STATUS_IS_OK(nt_status)) {
815 if (cli->smb_rw_error == SMB_READ_BAD_SIG) {
816 nt_status = NT_STATUS_ACCESS_DENIED;
818 nt_status = NT_STATUS_UNSUCCESSFUL;
822 data_blob_free(&msg1);
826 if (NT_STATUS_IS_OK(nt_status)) {
827 nt_status = NT_STATUS_UNSUCCESSFUL;
829 } else if ((turn == 1) &&
830 NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
831 DATA_BLOB tmp_blob = data_blob_null;
832 /* the server might give us back two challenges */
833 if (!spnego_parse_challenge(blob, &blob_in,
835 DEBUG(3,("Failed to parse challenges\n"));
836 nt_status = NT_STATUS_INVALID_PARAMETER;
838 data_blob_free(&tmp_blob);
840 if (!spnego_parse_auth_response(blob, nt_status, OID_NTLMSSP,
842 DEBUG(3,("Failed to parse auth response\n"));
843 if (NT_STATUS_IS_OK(nt_status)
844 || NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED))
845 nt_status = NT_STATUS_INVALID_PARAMETER;
848 data_blob_free(&blob);
849 data_blob_free(&blob_out);
851 } while (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED));
853 data_blob_free(&blob_in);
855 if (NT_STATUS_IS_OK(nt_status)) {
857 fstrcpy(cli->server_domain, ntlmssp_state->server_domain);
858 cli_set_session_key(cli, ntlmssp_state->session_key);
860 if (cli_simple_set_signing(
861 cli, ntlmssp_state->session_key, data_blob_null)) {
863 /* 'resign' the last message, so we get the right sequence numbers
864 for checking the first reply from the server */
865 cli_calculate_sign_mac(cli, cli->outbuf);
867 if (!cli_check_sign_mac(cli, cli->inbuf)) {
868 nt_status = NT_STATUS_ACCESS_DENIED;
873 /* we have a reference conter on ntlmssp_state, if we are signing
874 then the state will be kept by the signing engine */
876 ntlmssp_end(&ntlmssp_state);
878 if (!NT_STATUS_IS_OK(nt_status)) {
884 /****************************************************************************
885 Do a spnego encrypted session setup.
887 user_domain: The shortname of the domain the user/machine is a member of.
888 dest_realm: The realm we're connecting to, if NULL we use our default realm.
889 ****************************************************************************/
891 ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user,
892 const char *pass, const char *user_domain,
893 const char * dest_realm)
895 char *principal = NULL;
896 char *OIDs[ASN1_MAX_OIDS];
899 const char *p = NULL;
900 char *account = NULL;
902 DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli->secblob.length));
904 /* the server might not even do spnego */
905 if (cli->secblob.length <= 16) {
906 DEBUG(3,("server didn't supply a full spnego negprot\n"));
911 file_save("negprot.dat", cli->secblob.data, cli->secblob.length);
914 /* there is 16 bytes of GUID before the real spnego packet starts */
915 blob = data_blob(cli->secblob.data+16, cli->secblob.length-16);
917 /* The server sent us the first part of the SPNEGO exchange in the
918 * negprot reply. It is WRONG to depend on the principal sent in the
919 * negprot reply, but right now we do it. If we don't receive one,
920 * we try to best guess, then fall back to NTLM. */
921 if (!spnego_parse_negTokenInit(blob, OIDs, &principal)) {
922 data_blob_free(&blob);
923 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
925 data_blob_free(&blob);
927 /* make sure the server understands kerberos */
928 for (i=0;OIDs[i];i++) {
929 DEBUG(3,("got OID=%s\n", OIDs[i]));
930 if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 ||
931 strcmp(OIDs[i], OID_KERBEROS5) == 0) {
932 cli->got_kerberos_mechanism = True;
934 talloc_free(OIDs[i]);
937 DEBUG(3,("got principal=%s\n", principal ? principal : "<null>"));
939 fstrcpy(cli->user_name, user);
942 /* If password is set we reauthenticate to kerberos server
943 * and do not store results */
945 if (cli->got_kerberos_mechanism && cli->use_kerberos) {
951 use_in_memory_ccache();
952 ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */, NULL);
955 TALLOC_FREE(principal);
956 DEBUG(0, ("Kinit failed: %s\n", error_message(ret)));
957 if (cli->fallback_after_kerberos)
959 return ADS_ERROR_KRB5(ret);
963 /* If we get a bad principal, try to guess it if
964 we have a valid host NetBIOS name.
966 if (strequal(principal, ADS_IGNORE_PRINCIPAL)) {
967 TALLOC_FREE(principal);
970 if (principal == NULL &&
971 !is_ipaddress(cli->desthost) &&
972 !strequal(STAR_SMBSERVER,
975 char *machine = NULL;
977 DEBUG(3,("cli_session_setup_spnego: got a "
978 "bad server principal, trying to guess ...\n"));
980 host = strchr_m(cli->desthost, '.');
982 machine = SMB_STRNDUP(cli->desthost,
983 host - cli->desthost);
985 machine = SMB_STRDUP(cli->desthost);
987 if (machine == NULL) {
988 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
992 realm = SMB_STRDUP(dest_realm);
995 realm = kerberos_get_default_realm_from_ccache();
997 if (realm && *realm) {
998 principal = talloc_asprintf(NULL, "%s$@%s",
1003 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1005 DEBUG(3,("cli_session_setup_spnego: guessed "
1006 "server principal=%s\n",
1007 principal ? principal : "<null>"));
1014 rc = cli_session_setup_kerberos(cli, principal,
1016 if (ADS_ERR_OK(rc) || !cli->fallback_after_kerberos) {
1017 TALLOC_FREE(principal);
1024 TALLOC_FREE(principal);
1028 account = talloc_strdup(talloc_tos(), user);
1030 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1033 /* when falling back to ntlmssp while authenticating with a machine
1034 * account strip off the realm - gd */
1036 if ((p = strchr_m(user, '@')) != NULL) {
1037 account[PTR_DIFF(p,user)] = '\0';
1040 return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, account, pass, user_domain));
1043 /****************************************************************************
1044 Send a session setup. The username and workgroup is in UNIX character
1045 format and must be converted to DOS codepage format before sending. If the
1046 password is in plaintext, the same should be done.
1047 ****************************************************************************/
1049 NTSTATUS cli_session_setup(struct cli_state *cli,
1051 const char *pass, int passlen,
1052 const char *ntpass, int ntpasslen,
1053 const char *workgroup)
1059 fstrcpy(user2, user);
1068 /* allow for workgroups as part of the username */
1069 if ((p=strchr_m(user2,'\\')) || (p=strchr_m(user2,'/')) ||
1070 (p=strchr_m(user2,*lp_winbind_separator()))) {
1076 if (cli->protocol < PROTOCOL_LANMAN1) {
1077 return NT_STATUS_OK;
1080 /* now work out what sort of session setup we are going to
1081 do. I have split this into separate functions to make the
1082 flow a bit easier to understand (tridge) */
1084 /* if its an older server then we have to use the older request format */
1086 if (cli->protocol < PROTOCOL_NT1) {
1087 if (!lp_client_lanman_auth() && passlen != 24 && (*pass)) {
1088 DEBUG(1, ("Server requested LM password but 'client lanman auth'"
1090 return NT_STATUS_ACCESS_DENIED;
1093 if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 &&
1094 !lp_client_plaintext_auth() && (*pass)) {
1095 DEBUG(1, ("Server requested plaintext password but "
1096 "'client plaintext auth' is disabled\n"));
1097 return NT_STATUS_ACCESS_DENIED;
1100 return cli_session_setup_lanman2(cli, user, pass, passlen,
1104 /* if no user is supplied then we have to do an anonymous connection.
1105 passwords are ignored */
1107 if (!user || !*user)
1108 return cli_session_setup_guest(cli);
1110 /* if the server is share level then send a plaintext null
1111 password at this point. The password is sent in the tree
1114 if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0)
1115 return cli_session_setup_plaintext(cli, user, "", workgroup);
1117 /* if the server doesn't support encryption then we have to use
1118 plaintext. The second password is ignored */
1120 if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {
1121 if (!lp_client_plaintext_auth() && (*pass)) {
1122 DEBUG(1, ("Server requested plaintext password but "
1123 "'client plaintext auth' is disabled\n"));
1124 return NT_STATUS_ACCESS_DENIED;
1126 return cli_session_setup_plaintext(cli, user, pass, workgroup);
1129 /* if the server supports extended security then use SPNEGO */
1131 if (cli->capabilities & CAP_EXTENDED_SECURITY) {
1132 ADS_STATUS status = cli_session_setup_spnego(cli, user, pass,
1134 if (!ADS_ERR_OK(status)) {
1135 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
1136 return ads_ntstatus(status);
1141 /* otherwise do a NT1 style session setup */
1142 status = cli_session_setup_nt1(cli, user, pass, passlen,
1143 ntpass, ntpasslen, workgroup);
1144 if (!NT_STATUS_IS_OK(status)) {
1145 DEBUG(3,("cli_session_setup: NT1 session setup "
1146 "failed: %s\n", nt_errstr(status)));
1151 if (strstr(cli->server_type, "Samba")) {
1152 cli->is_samba = True;
1155 return NT_STATUS_OK;
1158 /****************************************************************************
1160 *****************************************************************************/
1162 bool cli_ulogoff(struct cli_state *cli)
1164 memset(cli->outbuf,'\0',smb_size);
1165 cli_set_message(cli->outbuf,2,0,True);
1166 SCVAL(cli->outbuf,smb_com,SMBulogoffX);
1167 cli_setup_packet(cli);
1168 SSVAL(cli->outbuf,smb_vwv0,0xFF);
1169 SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */
1172 if (!cli_receive_smb(cli))
1175 if (cli_is_error(cli)) {
1183 /****************************************************************************
1185 ****************************************************************************/
1187 struct async_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
1188 struct event_context *ev,
1189 struct cli_state *cli,
1190 const char *share, const char *dev,
1191 const char *pass, int passlen)
1195 struct async_req *result;
1199 fstrcpy(cli->share, share);
1201 /* in user level security don't send a password now */
1202 if (cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
1205 } else if (pass == NULL) {
1206 DEBUG(1, ("Server not using user level security and no "
1207 "password supplied.\n"));
1211 if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
1212 *pass && passlen != 24) {
1213 if (!lp_client_lanman_auth()) {
1214 DEBUG(1, ("Server requested LANMAN password "
1215 "(share-level security) but "
1216 "'client lanman auth' is disabled\n"));
1221 * Non-encrypted passwords - convert to DOS codepage before
1225 SMBencrypt(pass, cli->secblob.data, (uchar *)pword);
1227 if((cli->sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL
1228 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE))
1230 if (!lp_client_plaintext_auth() && (*pass)) {
1231 DEBUG(1, ("Server requested plaintext "
1232 "password but 'client plaintext "
1233 "auth' is disabled\n"));
1238 * Non-encrypted passwords - convert to DOS codepage
1241 passlen = clistr_push(cli, pword, pass, sizeof(pword),
1243 if (passlen == -1) {
1244 DEBUG(1, ("clistr_push(pword) failed\n"));
1249 memcpy(pword, pass, passlen);
1254 SCVAL(vwv+0, 0, 0xFF);
1257 SSVAL(vwv+2, 0, TCONX_FLAG_EXTENDED_RESPONSE);
1258 SSVAL(vwv+3, 0, passlen);
1261 bytes = (uint8_t *)talloc_memdup(talloc_tos(), pword, passlen);
1263 bytes = talloc_array(talloc_tos(), uint8_t, 0);
1269 tmp = talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
1270 cli->desthost, share);
1275 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1,
1280 * Add the devicetype
1282 tmp = talloc_strdup_upper(talloc_tos(), dev);
1287 bytes = smb_bytes_push_str(bytes, false, tmp, strlen(tmp)+1, NULL);
1290 if (bytes == NULL) {
1294 result = cli_request_send(mem_ctx, ev, cli, SMBtconX, 0,
1295 4, vwv, 0, talloc_get_size(bytes), bytes);
1301 struct cli_request *state;
1302 if (!async_req_setup(mem_ctx, &result, &state,
1303 struct cli_request)) {
1306 if (async_post_ntstatus(result, ev, NT_STATUS_ACCESS_DENIED)) {
1311 TALLOC_FREE(result);
1315 NTSTATUS cli_tcon_andx_recv(struct async_req *req)
1317 struct cli_request *cli_req = talloc_get_type_abort(
1318 req->private_data, struct cli_request);
1319 struct cli_state *cli = cli_req->cli;
1326 if (async_req_is_nterror(req, &status)) {
1330 status = cli_pull_reply(req, &wct, &vwv, &num_bytes, &bytes);
1331 if (!NT_STATUS_IS_OK(status)) {
1335 clistr_pull(cli_req->inbuf, cli->dev, bytes, sizeof(fstring),
1336 num_bytes, STR_TERMINATE|STR_ASCII);
1338 if ((cli->protocol >= PROTOCOL_NT1) && (num_bytes == 3)) {
1339 /* almost certainly win95 - enable bug fixes */
1344 * Make sure that we have the optional support 16-bit field. WCT > 2.
1345 * Avoids issues when connecting to Win9x boxes sharing files
1348 cli->dfsroot = false;
1350 if ((wct > 2) && (cli->protocol >= PROTOCOL_LANMAN2)) {
1351 cli->dfsroot = ((SVAL(vwv+2, 0) & SMB_SHARE_IN_DFS) != 0);
1354 cli->cnum = SVAL(cli_req->inbuf,smb_tid);
1355 return NT_STATUS_OK;
1358 NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
1359 const char *dev, const char *pass, int passlen)
1361 TALLOC_CTX *frame = talloc_stackframe();
1362 struct event_context *ev;
1363 struct async_req *req;
1366 if (cli->fd_event != NULL) {
1368 * Can't use sync call while an async call is in flight
1370 status = NT_STATUS_INVALID_PARAMETER;
1374 ev = event_context_init(frame);
1376 status = NT_STATUS_NO_MEMORY;
1380 req = cli_tcon_andx_send(frame, ev, cli, share, dev, pass, passlen);
1382 status = NT_STATUS_NO_MEMORY;
1386 while (req->state < ASYNC_REQ_DONE) {
1387 event_loop_once(ev);
1390 status = cli_tcon_andx_recv(req);
1396 /****************************************************************************
1397 Send a tree disconnect.
1398 ****************************************************************************/
1400 bool cli_tdis(struct cli_state *cli)
1402 memset(cli->outbuf,'\0',smb_size);
1403 cli_set_message(cli->outbuf,0,0,True);
1404 SCVAL(cli->outbuf,smb_com,SMBtdis);
1405 SSVAL(cli->outbuf,smb_tid,cli->cnum);
1406 cli_setup_packet(cli);
1409 if (!cli_receive_smb(cli))
1412 if (cli_is_error(cli)) {
1420 /****************************************************************************
1421 Send a negprot command.
1422 ****************************************************************************/
1424 void cli_negprot_sendsync(struct cli_state *cli)
1429 if (cli->protocol < PROTOCOL_NT1)
1430 cli->use_spnego = False;
1432 memset(cli->outbuf,'\0',smb_size);
1434 /* setup the protocol strings */
1435 cli_set_message(cli->outbuf,0,0,True);
1437 p = smb_buf(cli->outbuf);
1438 for (numprots=0; numprots < ARRAY_SIZE(prots); numprots++) {
1439 if (prots[numprots].prot > cli->protocol) {
1443 p += clistr_push(cli, p, prots[numprots].name, -1, STR_TERMINATE);
1446 SCVAL(cli->outbuf,smb_com,SMBnegprot);
1447 cli_setup_bcc(cli, p);
1448 cli_setup_packet(cli);
1450 SCVAL(smb_buf(cli->outbuf),0,2);
1455 /****************************************************************************
1456 Send a negprot command.
1457 ****************************************************************************/
1459 struct async_req *cli_negprot_send(TALLOC_CTX *mem_ctx,
1460 struct event_context *ev,
1461 struct cli_state *cli)
1463 struct async_req *result;
1464 uint8_t *bytes = NULL;
1467 if (cli->protocol < PROTOCOL_NT1)
1468 cli->use_spnego = False;
1470 /* setup the protocol strings */
1471 for (numprots=0; numprots < ARRAY_SIZE(prots); numprots++) {
1473 if (prots[numprots].prot > cli->protocol) {
1476 bytes = (uint8_t *)talloc_append_blob(
1477 talloc_tos(), bytes, data_blob_const(&c, sizeof(c)));
1478 if (bytes == NULL) {
1481 bytes = smb_bytes_push_str(bytes, false,
1482 prots[numprots].name,
1483 strlen(prots[numprots].name)+1,
1485 if (bytes == NULL) {
1490 result = cli_request_send(mem_ctx, ev, cli, SMBnegprot, 0, 0, NULL, 0,
1491 talloc_get_size(bytes), bytes);
1496 NTSTATUS cli_negprot_recv(struct async_req *req)
1498 struct cli_request *cli_req = talloc_get_type_abort(
1499 req->private_data, struct cli_request);
1500 struct cli_state *cli = cli_req->cli;
1508 if (async_req_is_nterror(req, &status)) {
1512 status = cli_pull_reply(req, &wct, &vwv, &num_bytes, &bytes);
1513 if (!NT_STATUS_IS_OK(status)) {
1517 protnum = SVAL(vwv, 0);
1519 if ((protnum >= ARRAY_SIZE(prots))
1520 || (prots[protnum].prot > cli_req->cli->protocol)) {
1521 return NT_STATUS_INVALID_NETWORK_RESPONSE;
1524 cli->protocol = prots[protnum].prot;
1526 if ((cli->protocol < PROTOCOL_NT1) && cli->sign_info.mandatory_signing) {
1527 DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n"));
1528 return NT_STATUS_ACCESS_DENIED;
1531 if (cli->protocol >= PROTOCOL_NT1) {
1534 cli->sec_mode = CVAL(vwv + 1, 0);
1535 cli->max_mux = SVAL(vwv + 1, 1);
1536 cli->max_xmit = IVAL(vwv + 3, 1);
1537 cli->sesskey = IVAL(vwv + 7, 1);
1538 cli->serverzone = SVALS(vwv + 15, 1);
1539 cli->serverzone *= 60;
1540 /* this time arrives in real GMT */
1541 ts = interpret_long_date(((char *)(vwv+11))+1);
1542 cli->servertime = ts.tv_sec;
1543 cli->secblob = data_blob(bytes, num_bytes);
1544 cli->capabilities = IVAL(vwv + 9, 1);
1545 if (cli->capabilities & CAP_RAW_MODE) {
1546 cli->readbraw_supported = True;
1547 cli->writebraw_supported = True;
1549 /* work out if they sent us a workgroup */
1550 if (!(cli->capabilities & CAP_EXTENDED_SECURITY) &&
1551 smb_buflen(cli->inbuf) > 8) {
1552 clistr_pull(cli->inbuf, cli->server_domain,
1553 bytes+8, sizeof(cli->server_domain),
1555 STR_UNICODE|STR_NOALIGN);
1559 * As signing is slow we only turn it on if either the client or
1560 * the server require it. JRA.
1563 if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) {
1564 /* Fail if server says signing is mandatory and we don't want to support it. */
1565 if (!cli->sign_info.allow_smb_signing) {
1566 DEBUG(0,("cli_negprot: SMB signing is mandatory and we have disabled it.\n"));
1567 return NT_STATUS_ACCESS_DENIED;
1569 cli->sign_info.negotiated_smb_signing = True;
1570 cli->sign_info.mandatory_signing = True;
1571 } else if (cli->sign_info.mandatory_signing && cli->sign_info.allow_smb_signing) {
1572 /* Fail if client says signing is mandatory and the server doesn't support it. */
1573 if (!(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) {
1574 DEBUG(1,("cli_negprot: SMB signing is mandatory and the server doesn't support it.\n"));
1575 return NT_STATUS_ACCESS_DENIED;
1577 cli->sign_info.negotiated_smb_signing = True;
1578 cli->sign_info.mandatory_signing = True;
1579 } else if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
1580 cli->sign_info.negotiated_smb_signing = True;
1583 if (cli->capabilities & (CAP_LARGE_READX|CAP_LARGE_WRITEX)) {
1584 SAFE_FREE(cli->outbuf);
1585 SAFE_FREE(cli->inbuf);
1586 cli->outbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN);
1587 cli->inbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN);
1588 cli->bufsize = CLI_SAMBA_MAX_LARGE_READX_SIZE + LARGE_WRITEX_HDR_SIZE;
1591 } else if (cli->protocol >= PROTOCOL_LANMAN1) {
1592 cli->use_spnego = False;
1593 cli->sec_mode = SVAL(vwv + 1, 0);
1594 cli->max_xmit = SVAL(vwv + 2, 0);
1595 cli->max_mux = SVAL(vwv + 3, 0);
1596 cli->sesskey = IVAL(vwv + 6, 0);
1597 cli->serverzone = SVALS(vwv + 10, 0);
1598 cli->serverzone *= 60;
1599 /* this time is converted to GMT by make_unix_date */
1600 cli->servertime = cli_make_unix_date(
1601 cli, (char *)(vwv + 8));
1602 cli->readbraw_supported = ((SVAL(vwv + 5, 0) & 0x1) != 0);
1603 cli->writebraw_supported = ((SVAL(vwv + 5, 0) & 0x2) != 0);
1604 cli->secblob = data_blob(bytes, num_bytes);
1606 /* the old core protocol */
1607 cli->use_spnego = False;
1609 cli->serverzone = get_time_zone(time(NULL));
1612 cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE);
1614 /* a way to force ascii SMB */
1615 if (getenv("CLI_FORCE_ASCII"))
1616 cli->capabilities &= ~CAP_UNICODE;
1618 return NT_STATUS_OK;
1621 NTSTATUS cli_negprot(struct cli_state *cli)
1623 TALLOC_CTX *frame = talloc_stackframe();
1624 struct event_context *ev;
1625 struct async_req *req;
1626 NTSTATUS status = NT_STATUS_NO_MEMORY;
1628 if (cli->fd_event != NULL) {
1630 * Can't use sync call while an async call is in flight
1632 cli_set_error(cli, NT_STATUS_INVALID_PARAMETER);
1636 ev = event_context_init(frame);
1641 req = cli_negprot_send(frame, ev, cli);
1646 while (req->state < ASYNC_REQ_DONE) {
1647 event_loop_once(ev);
1650 status = cli_negprot_recv(req);
1656 /****************************************************************************
1657 Send a session request. See rfc1002.txt 4.3 and 4.3.2.
1658 ****************************************************************************/
1660 bool cli_session_request(struct cli_state *cli,
1661 struct nmb_name *calling, struct nmb_name *called)
1667 /* 445 doesn't have session request */
1668 if (cli->port == 445)
1671 memcpy(&(cli->calling), calling, sizeof(*calling));
1672 memcpy(&(cli->called ), called , sizeof(*called ));
1674 /* put in the destination name */
1676 tmp = name_mangle(talloc_tos(), cli->called.name,
1677 cli->called.name_type);
1682 p = cli->outbuf+len;
1683 memcpy(p, tmp, name_len(tmp));
1684 len += name_len(tmp);
1689 tmp = name_mangle(talloc_tos(), cli->calling.name,
1690 cli->calling.name_type);
1695 p = cli->outbuf+len;
1696 memcpy(p, tmp, name_len(tmp));
1697 len += name_len(tmp);
1700 /* send a session request (RFC 1002) */
1701 /* setup the packet length
1702 * Remove four bytes from the length count, since the length
1703 * field in the NBT Session Service header counts the number
1704 * of bytes which follow. The cli_send_smb() function knows
1705 * about this and accounts for those four bytes.
1709 _smb_setlen(cli->outbuf,len);
1710 SCVAL(cli->outbuf,0,0x81);
1713 DEBUG(5,("Sent session request\n"));
1715 if (!cli_receive_smb(cli))
1718 if (CVAL(cli->inbuf,0) == 0x84) {
1719 /* C. Hoch 9/14/95 Start */
1720 /* For information, here is the response structure.
1721 * We do the byte-twiddling to for portability.
1722 struct RetargetResponse{
1724 unsigned char flags;
1730 uint16_t port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9);
1731 struct in_addr dest_ip;
1734 /* SESSION RETARGET */
1735 putip((char *)&dest_ip,cli->inbuf+4);
1736 in_addr_to_sockaddr_storage(&cli->dest_ss, dest_ip);
1738 status = open_socket_out(&cli->dest_ss, port,
1739 LONG_CONNECT_TIMEOUT, &cli->fd);
1740 if (!NT_STATUS_IS_OK(status)) {
1744 DEBUG(3,("Retargeted\n"));
1746 set_socket_options(cli->fd, lp_socket_options());
1753 DEBUG(0,("Retarget recursion - failing\n"));
1757 ret = cli_session_request(cli, calling, called);
1761 } /* C. Hoch 9/14/95 End */
1763 if (CVAL(cli->inbuf,0) != 0x82) {
1764 /* This is the wrong place to put the error... JRA. */
1765 cli->rap_error = CVAL(cli->inbuf,4);
1771 static void smb_sock_connected(struct async_req *req)
1773 int *pfd = (int *)req->async.priv;
1777 status = open_socket_out_defer_recv(req, &fd);
1778 if (NT_STATUS_IS_OK(status)) {
1783 static NTSTATUS open_smb_socket(const struct sockaddr_storage *pss,
1784 uint16_t *port, int timeout, int *pfd)
1786 struct event_context *ev;
1787 struct async_req *r139, *r445;
1793 return open_socket_out(pss, *port, timeout, pfd);
1796 ev = event_context_init(talloc_tos());
1798 return NT_STATUS_NO_MEMORY;
1801 r445 = open_socket_out_defer_send(ev, ev, timeval_set(0, 0),
1803 r139 = open_socket_out_defer_send(ev, ev, timeval_set(0, 3000),
1805 if ((r445 == NULL) || (r139 == NULL)) {
1806 status = NT_STATUS_NO_MEMORY;
1809 r445->async.fn = smb_sock_connected;
1810 r445->async.priv = &fd445;
1811 r139->async.fn = smb_sock_connected;
1812 r139->async.priv = &fd139;
1814 while ((fd139 == -1) && (r139->state < ASYNC_REQ_DONE)
1815 && (fd445 == -1) && (r445->state < ASYNC_REQ_DONE)) {
1816 event_loop_once(ev);
1819 if ((fd139 != -1) && (fd445 != -1)) {
1827 status = NT_STATUS_OK;
1833 status = NT_STATUS_OK;
1837 status = open_socket_out_defer_recv(r445, &fd445);
1843 /****************************************************************************
1844 Open the client sockets.
1845 ****************************************************************************/
1847 NTSTATUS cli_connect(struct cli_state *cli,
1849 struct sockaddr_storage *dest_ss)
1852 int name_type = 0x20;
1853 TALLOC_CTX *frame = talloc_stackframe();
1854 unsigned int num_addrs = 0;
1856 struct sockaddr_storage *ss_arr = NULL;
1859 /* reasonable default hostname */
1861 host = STAR_SMBSERVER;
1864 fstrcpy(cli->desthost, host);
1866 /* allow hostnames of the form NAME#xx and do a netbios lookup */
1867 if ((p = strchr(cli->desthost, '#'))) {
1868 name_type = strtol(p+1, NULL, 16);
1872 if (!dest_ss || is_zero_addr((struct sockaddr *)dest_ss)) {
1873 NTSTATUS status =resolve_name_list(frame,
1878 if (!NT_STATUS_IS_OK(status)) {
1880 return NT_STATUS_BAD_NETWORK_NAME;
1884 ss_arr = TALLOC_P(frame, struct sockaddr_storage);
1887 return NT_STATUS_NO_MEMORY;
1892 for (i = 0; i < num_addrs; i++) {
1893 cli->dest_ss = ss_arr[i];
1894 if (getenv("LIBSMB_PROG")) {
1895 cli->fd = sock_exec(getenv("LIBSMB_PROG"));
1897 uint16_t port = cli->port;
1899 status = open_smb_socket(&cli->dest_ss, &port,
1900 cli->timeout, &cli->fd);
1901 if (NT_STATUS_IS_OK(status)) {
1905 if (cli->fd == -1) {
1906 char addr[INET6_ADDRSTRLEN];
1907 print_sockaddr(addr, sizeof(addr), &ss_arr[i]);
1908 DEBUG(2,("Error connecting to %s (%s)\n",
1909 dest_ss?addr:host,strerror(errno)));
1911 /* Exit from loop on first connection. */
1916 if (cli->fd == -1) {
1918 return map_nt_error_from_unix(errno);
1922 *dest_ss = cli->dest_ss;
1925 set_socket_options(cli->fd, lp_socket_options());
1928 return NT_STATUS_OK;
1932 establishes a connection to after the negprot.
1933 @param output_cli A fully initialised cli structure, non-null only on success
1934 @param dest_host The netbios name of the remote host
1935 @param dest_ss (optional) The the destination IP, NULL for name based lookup
1936 @param port (optional) The destination port (0 for default)
1937 @param retry bool. Did this connection fail with a retryable error ?
1940 NTSTATUS cli_start_connection(struct cli_state **output_cli,
1941 const char *my_name,
1942 const char *dest_host,
1943 struct sockaddr_storage *dest_ss, int port,
1944 int signing_state, int flags,
1948 struct nmb_name calling;
1949 struct nmb_name called;
1950 struct cli_state *cli;
1951 struct sockaddr_storage ss;
1957 my_name = global_myname();
1959 if (!(cli = cli_initialise_ex(signing_state))) {
1960 return NT_STATUS_NO_MEMORY;
1963 make_nmb_name(&calling, my_name, 0x0);
1964 make_nmb_name(&called , dest_host, 0x20);
1966 cli_set_port(cli, port);
1967 cli_set_timeout(cli, 10000); /* 10 seconds. */
1977 DEBUG(3,("Connecting to host=%s\n", dest_host));
1979 nt_status = cli_connect(cli, dest_host, &ss);
1980 if (!NT_STATUS_IS_OK(nt_status)) {
1981 char addr[INET6_ADDRSTRLEN];
1982 print_sockaddr(addr, sizeof(addr), &ss);
1983 DEBUG(1,("cli_start_connection: failed to connect to %s (%s). Error %s\n",
1984 nmb_namestr(&called), addr, nt_errstr(nt_status) ));
1992 if (!cli_session_request(cli, &calling, &called)) {
1994 DEBUG(1,("session request to %s failed (%s)\n",
1995 called.name, cli_errstr(cli)));
1996 if ((p=strchr(called.name, '.')) && !is_ipaddress(called.name)) {
2000 if (strcmp(called.name, STAR_SMBSERVER)) {
2001 make_nmb_name(&called , STAR_SMBSERVER, 0x20);
2004 return NT_STATUS_BAD_NETWORK_NAME;
2007 if (flags & CLI_FULL_CONNECTION_DONT_SPNEGO)
2008 cli->use_spnego = False;
2009 else if (flags & CLI_FULL_CONNECTION_USE_KERBEROS)
2010 cli->use_kerberos = True;
2012 if ((flags & CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS) &&
2013 cli->use_kerberos) {
2014 cli->fallback_after_kerberos = true;
2017 nt_status = cli_negprot(cli);
2018 if (!NT_STATUS_IS_OK(nt_status)) {
2019 DEBUG(1, ("failed negprot: %s\n", nt_errstr(nt_status)));
2025 return NT_STATUS_OK;
2030 establishes a connection right up to doing tconX, password specified.
2031 @param output_cli A fully initialised cli structure, non-null only on success
2032 @param dest_host The netbios name of the remote host
2033 @param dest_ip (optional) The the destination IP, NULL for name based lookup
2034 @param port (optional) The destination port (0 for default)
2035 @param service (optional) The share to make the connection to. Should be 'unqualified' in any way.
2036 @param service_type The 'type' of serivice.
2037 @param user Username, unix string
2038 @param domain User's domain
2039 @param password User's password, unencrypted unix string.
2040 @param retry bool. Did this connection fail with a retryable error ?
2043 NTSTATUS cli_full_connection(struct cli_state **output_cli,
2044 const char *my_name,
2045 const char *dest_host,
2046 struct sockaddr_storage *dest_ss, int port,
2047 const char *service, const char *service_type,
2048 const char *user, const char *domain,
2049 const char *password, int flags,
2054 struct cli_state *cli = NULL;
2055 int pw_len = password ? strlen(password)+1 : 0;
2059 if (password == NULL) {
2063 nt_status = cli_start_connection(&cli, my_name, dest_host,
2064 dest_ss, port, signing_state,
2067 if (!NT_STATUS_IS_OK(nt_status)) {
2071 nt_status = cli_session_setup(cli, user, password, pw_len, password,
2073 if (!NT_STATUS_IS_OK(nt_status)) {
2075 if (!(flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) {
2076 DEBUG(1,("failed session setup with %s\n",
2077 nt_errstr(nt_status)));
2082 nt_status = cli_session_setup(cli, "", "", 0, "", 0, domain);
2083 if (!NT_STATUS_IS_OK(nt_status)) {
2084 DEBUG(1,("anonymous failed session setup with %s\n",
2085 nt_errstr(nt_status)));
2092 nt_status = cli_tcon_andx(cli, service, service_type, password,
2094 if (!NT_STATUS_IS_OK(nt_status)) {
2095 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status)));
2097 if (NT_STATUS_IS_OK(nt_status)) {
2098 nt_status = NT_STATUS_UNSUCCESSFUL;
2104 cli_init_creds(cli, user, domain, password);
2107 return NT_STATUS_OK;
2110 /****************************************************************************
2111 Attempt a NetBIOS session request, falling back to *SMBSERVER if needed.
2112 ****************************************************************************/
2114 bool attempt_netbios_session_request(struct cli_state **ppcli, const char *srchost, const char *desthost,
2115 struct sockaddr_storage *pdest_ss)
2117 struct nmb_name calling, called;
2119 make_nmb_name(&calling, srchost, 0x0);
2122 * If the called name is an IP address
2123 * then use *SMBSERVER immediately.
2126 if(is_ipaddress(desthost)) {
2127 make_nmb_name(&called, STAR_SMBSERVER, 0x20);
2129 make_nmb_name(&called, desthost, 0x20);
2132 if (!cli_session_request(*ppcli, &calling, &called)) {
2134 struct nmb_name smbservername;
2136 make_nmb_name(&smbservername, STAR_SMBSERVER, 0x20);
2139 * If the name wasn't *SMBSERVER then
2140 * try with *SMBSERVER if the first name fails.
2143 if (nmb_name_equal(&called, &smbservername)) {
2146 * The name used was *SMBSERVER, don't bother with another name.
2149 DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \
2150 with error %s.\n", desthost, cli_errstr(*ppcli) ));
2155 cli_shutdown(*ppcli);
2157 *ppcli = cli_initialise();
2159 /* Out of memory... */
2163 status = cli_connect(*ppcli, desthost, pdest_ss);
2164 if (!NT_STATUS_IS_OK(status) ||
2165 !cli_session_request(*ppcli, &calling, &smbservername)) {
2166 DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \
2167 name *SMBSERVER with error %s\n", desthost, cli_errstr(*ppcli) ));
2175 /****************************************************************************
2176 Send an old style tcon.
2177 ****************************************************************************/
2178 NTSTATUS cli_raw_tcon(struct cli_state *cli,
2179 const char *service, const char *pass, const char *dev,
2180 uint16 *max_xmit, uint16 *tid)
2184 if (!lp_client_plaintext_auth() && (*pass)) {
2185 DEBUG(1, ("Server requested plaintext password but 'client "
2186 "plaintext auth' is disabled\n"));
2187 return NT_STATUS_ACCESS_DENIED;
2190 memset(cli->outbuf,'\0',smb_size);
2191 memset(cli->inbuf,'\0',smb_size);
2193 cli_set_message(cli->outbuf, 0, 0, True);
2194 SCVAL(cli->outbuf,smb_com,SMBtcon);
2195 cli_setup_packet(cli);
2197 p = smb_buf(cli->outbuf);
2198 *p++ = 4; p += clistr_push(cli, p, service, -1, STR_TERMINATE | STR_NOALIGN);
2199 *p++ = 4; p += clistr_push(cli, p, pass, -1, STR_TERMINATE | STR_NOALIGN);
2200 *p++ = 4; p += clistr_push(cli, p, dev, -1, STR_TERMINATE | STR_NOALIGN);
2202 cli_setup_bcc(cli, p);
2205 if (!cli_receive_smb(cli)) {
2206 return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
2209 if (cli_is_error(cli)) {
2210 return cli_nt_error(cli);
2213 *max_xmit = SVAL(cli->inbuf, smb_vwv0);
2214 *tid = SVAL(cli->inbuf, smb_vwv1);
2216 return NT_STATUS_OK;
2219 /* Return a cli_state pointing at the IPC$ share for the given server */
2221 struct cli_state *get_ipc_connect(char *server,
2222 struct sockaddr_storage *server_ss,
2223 const struct user_auth_info *user_info)
2225 struct cli_state *cli;
2227 uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
2229 if (user_info->use_kerberos) {
2230 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
2233 nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC",
2234 user_info->username ? user_info->username : "",
2236 user_info->password ? user_info->password : "",
2240 if (NT_STATUS_IS_OK(nt_status)) {
2242 } else if (is_ipaddress(server)) {
2243 /* windows 9* needs a correct NMB name for connections */
2244 fstring remote_name;
2246 if (name_status_find("*", 0, 0, server_ss, remote_name)) {
2247 cli = get_ipc_connect(remote_name, server_ss, user_info);
2256 * Given the IP address of a master browser on the network, return its
2257 * workgroup and connect to it.
2259 * This function is provided to allow additional processing beyond what
2260 * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master
2261 * browsers and obtain each master browsers' list of domains (in case the
2262 * first master browser is recently on the network and has not yet
2263 * synchronized with other master browsers and therefore does not yet have the
2264 * entire network browse list)
2267 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
2268 struct ip_service *mb_ip,
2269 const struct user_auth_info *user_info,
2270 char **pp_workgroup_out)
2272 char addr[INET6_ADDRSTRLEN];
2274 struct cli_state *cli;
2275 struct sockaddr_storage server_ss;
2277 *pp_workgroup_out = NULL;
2279 print_sockaddr(addr, sizeof(addr), &mb_ip->ss);
2280 DEBUG(99, ("Looking up name of master browser %s\n",
2284 * Do a name status query to find out the name of the master browser.
2285 * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain
2286 * master browser will not respond to a wildcard query (or, at least,
2287 * an NT4 server acting as the domain master browser will not).
2289 * We might be able to use ONLY the query on MSBROWSE, but that's not
2290 * yet been tested with all Windows versions, so until it is, leave
2291 * the original wildcard query as the first choice and fall back to
2292 * MSBROWSE if the wildcard query fails.
2294 if (!name_status_find("*", 0, 0x1d, &mb_ip->ss, name) &&
2295 !name_status_find(MSBROWSE, 1, 0x1d, &mb_ip->ss, name)) {
2297 DEBUG(99, ("Could not retrieve name status for %s\n",
2302 if (!find_master_ip(name, &server_ss)) {
2303 DEBUG(99, ("Could not find master ip for %s\n", name));
2307 *pp_workgroup_out = talloc_strdup(ctx, name);
2309 DEBUG(4, ("found master browser %s, %s\n", name, addr));
2311 print_sockaddr(addr, sizeof(addr), &server_ss);
2312 cli = get_ipc_connect(addr, &server_ss, user_info);
2318 * Return the IP address and workgroup of a master browser on the network, and
2322 struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx,
2323 const struct user_auth_info *user_info,
2324 char **pp_workgroup_out)
2326 struct ip_service *ip_list;
2327 struct cli_state *cli;
2330 *pp_workgroup_out = NULL;
2332 DEBUG(99, ("Do broadcast lookup for workgroups on local network\n"));
2334 /* Go looking for workgroups by broadcasting on the local network */
2336 if (!NT_STATUS_IS_OK(name_resolve_bcast(MSBROWSE, 1, &ip_list,
2338 DEBUG(99, ("No master browsers responded\n"));
2342 for (i = 0; i < count; i++) {
2343 char addr[INET6_ADDRSTRLEN];
2344 print_sockaddr(addr, sizeof(addr), &ip_list[i].ss);
2345 DEBUG(99, ("Found master browser %s\n", addr));
2347 cli = get_ipc_connect_master_ip(ctx, &ip_list[i],
2348 user_info, pp_workgroup_out);