Changeset 988 for vendor/current/source3/libsmb/cliconnect.c
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/libsmb/cliconnect.c
r919 r988 23 23 #include "includes.h" 24 24 #include "libsmb/libsmb.h" 25 #include " popt_common.h"25 #include "auth_info.h" 26 26 #include "../libcli/auth/libcli_auth.h" 27 27 #include "../libcli/auth/spnego.h" 28 28 #include "smb_krb5.h" 29 #include "../libcli/auth/ntlmssp.h" 29 #include "auth/credentials/credentials.h" 30 #include "auth/gensec/gensec.h" 31 #include "auth/ntlmssp/ntlmssp.h" 32 #include "auth_generic.h" 30 33 #include "libads/kerberos_proto.h" 31 34 #include "krb5_env.h" … … 33 36 #include "async_smb.h" 34 37 #include "libsmb/nmblib.h" 35 36 static const struct { 37 int prot; 38 const char name[24]; 39 } prots[10] = { 40 {PROTOCOL_CORE, "PC NETWORK PROGRAM 1.0"}, 41 {PROTOCOL_COREPLUS, "MICROSOFT NETWORKS 1.03"}, 42 {PROTOCOL_LANMAN1, "MICROSOFT NETWORKS 3.0"}, 43 {PROTOCOL_LANMAN1, "LANMAN1.0"}, 44 {PROTOCOL_LANMAN2, "LM1.2X002"}, 45 {PROTOCOL_LANMAN2, "DOS LANMAN2.1"}, 46 {PROTOCOL_LANMAN2, "LANMAN2.1"}, 47 {PROTOCOL_LANMAN2, "Samba"}, 48 {PROTOCOL_NT1, "NT LANMAN 1.0"}, 49 {PROTOCOL_NT1, "NT LM 0.12"}, 50 }; 38 #include "librpc/ndr/libndr.h" 39 #include "../libcli/smb/smbXcli_base.h" 51 40 52 41 #define STAR_SMBSERVER "*SMBSERVER" … … 59 48 *******************************************************/ 60 49 61 static NTSTATUS smb_bytes_talloc_string( struct cli_state *cli,62 c har *inbuf,50 static NTSTATUS smb_bytes_talloc_string(TALLOC_CTX *mem_ctx, 51 const uint8_t *hdr, 63 52 char **dest, 64 53 uint8_t *src, … … 66 55 ssize_t *destlen) 67 56 { 68 *destlen = clistr_pull_talloc( cli,69 inbuf,70 SVAL( inbuf, smb_flg2),57 *destlen = clistr_pull_talloc(mem_ctx, 58 (const char *)hdr, 59 SVAL(hdr, HDR_FLG2), 71 60 dest, 72 61 (char *)src, … … 78 67 79 68 if (*dest == NULL) { 80 *dest = talloc_strdup( cli, "");69 *dest = talloc_strdup(mem_ctx, ""); 81 70 if (*dest == NULL) { 82 71 return NT_STATUS_NO_MEMORY; … … 84 73 } 85 74 return NT_STATUS_OK; 86 }87 88 /**89 * Set the user session key for a connection90 * @param cli The cli structure to add it too91 * @param session_key The session key used. (A copy of this is taken for the cli struct)92 *93 */94 95 static void cli_set_session_key (struct cli_state *cli, const DATA_BLOB session_key)96 {97 cli->user_session_key = data_blob(NULL, 16);98 data_blob_clear(&cli->user_session_key);99 memcpy(cli->user_session_key.data, session_key.data, MIN(session_key.length, 16));100 75 } 101 76 … … 124 99 uint8_t *bytes; 125 100 char *tmp; 101 uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn); 126 102 127 103 req = tevent_req_create(mem_ctx, &state, … … 135 111 136 112 /* 137 * LANMAN servers predate NT status codes and Unicode and138 * ignore those smb flags so we must disable the corresponding139 * default capabilities that would otherwise cause the Unicode140 * and NT Status flags to be set (and even returned by the141 * server)142 */143 144 cli->capabilities &= ~(CAP_UNICODE | CAP_STATUS32);145 146 /*147 113 * if in share level security then don't send a password now 148 114 */ 149 if (!( cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) {115 if (!(sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) { 150 116 passlen = 0; 151 117 } 152 118 153 119 if (passlen > 0 154 && ( cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)120 && (sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) 155 121 && passlen != 24) { 156 122 /* … … 163 129 } 164 130 165 if (!SMBencrypt(pass, cli->secblob.data,131 if (!SMBencrypt(pass, smb1cli_conn_server_challenge(cli->conn), 166 132 (uint8_t *)lm_response.data)) { 167 133 DEBUG(1, ("Password is > 14 chars in length, and is " … … 171 137 return tevent_req_post(req, ev); 172 138 } 173 } else if (( cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)139 } else if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) 174 140 && passlen == 24) { 175 141 /* … … 188 154 */ 189 155 buf = talloc_array(talloc_tos(), uint8_t, 0); 190 buf = smb_bytes_push_str(buf, cli_ucs2(cli), pass, passlen+1,156 buf = smb_bytes_push_str(buf, smbXcli_conn_use_unicode(cli->conn), pass, passlen+1, 191 157 &converted_size); 192 158 if (tevent_req_nomem(buf, req)) { … … 206 172 SSVAL(vwv+3, 0, 2); 207 173 SSVAL(vwv+4, 0, 1); 208 SIVAL(vwv+5, 0, cli->sesskey);174 SIVAL(vwv+5, 0, smb1cli_conn_server_session_key(cli->conn)); 209 175 SSVAL(vwv+7, 0, lm_response.length); 210 176 … … 222 188 return tevent_req_post(req, ev); 223 189 } 224 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1,190 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), tmp, strlen(tmp)+1, 225 191 NULL); 226 192 TALLOC_FREE(tmp); … … 230 196 return tevent_req_post(req, ev); 231 197 } 232 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1,198 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), tmp, strlen(tmp)+1, 233 199 NULL); 234 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Unix", 5, NULL);235 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Samba", 6, NULL);200 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Unix", 5, NULL); 201 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Samba", 6, NULL); 236 202 237 203 if (tevent_req_nomem(bytes, req)) { … … 257 223 uint32_t num_bytes; 258 224 uint8_t *in; 259 char *inbuf;225 uint8_t *inhdr; 260 226 uint8_t *bytes; 261 227 uint8_t *p; … … 273 239 } 274 240 275 in buf = (char *)in;241 inhdr = in + NBT_HDR_SIZE; 276 242 p = bytes; 277 243 278 cli ->vuid = SVAL(inbuf, smb_uid);279 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);244 cli_state_set_uid(state->cli, SVAL(inhdr, HDR_UID)); 245 smb1cli_session_set_action(cli->smb1.session, SVAL(vwv+2, 0)); 280 246 281 247 status = smb_bytes_talloc_string(cli, 282 in buf,248 inhdr, 283 249 &cli->server_os, 284 250 p, … … 293 259 294 260 status = smb_bytes_talloc_string(cli, 295 in buf,261 inhdr, 296 262 &cli->server_type, 297 263 p, … … 306 272 307 273 status = smb_bytes_talloc_string(cli, 308 in buf,274 inhdr, 309 275 &cli->server_domain, 310 276 p, … … 318 284 p += ret; 319 285 320 if (strstr(cli->server_type, "Samba")) {321 cli->is_samba = True;322 }323 status = cli_set_username(cli, state->user);324 if (tevent_req_nterror(req, status)) {325 return;326 }327 286 tevent_req_done(req); 328 287 } … … 331 290 { 332 291 return tevent_req_simple_recv_ntstatus(req); 333 }334 335 static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli, const char *user,336 const char *pass, size_t passlen,337 const char *workgroup)338 {339 TALLOC_CTX *frame = talloc_stackframe();340 struct event_context *ev;341 struct tevent_req *req;342 NTSTATUS status = NT_STATUS_NO_MEMORY;343 344 if (cli_has_async_calls(cli)) {345 /*346 * Can't use sync call while an async call is in flight347 */348 status = NT_STATUS_INVALID_PARAMETER;349 goto fail;350 }351 ev = event_context_init(frame);352 if (ev == NULL) {353 goto fail;354 }355 req = cli_session_setup_lanman2_send(frame, ev, cli, user, pass, passlen,356 workgroup);357 if (req == NULL) {358 goto fail;359 }360 if (!tevent_req_poll_ntstatus(req, ev, &status)) {361 goto fail;362 }363 status = cli_session_setup_lanman2_recv(req);364 fail:365 TALLOC_FREE(frame);366 return status;367 292 } 368 293 … … 371 296 ****************************************************************************/ 372 297 373 static uint32 cli_session_setup_capabilities(struct cli_state *cli) 374 { 375 uint32 capabilities = CAP_NT_SMBS; 376 377 if (!cli->force_dos_errors) 378 capabilities |= CAP_STATUS32; 379 380 if (cli->use_level_II_oplocks) 381 capabilities |= CAP_LEVEL_II_OPLOCKS; 382 383 capabilities |= (cli->capabilities & (CAP_UNICODE|CAP_LARGE_FILES|CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_DFS)); 384 return capabilities; 298 static uint32_t cli_session_setup_capabilities(struct cli_state *cli, 299 uint32_t sesssetup_capabilities) 300 { 301 uint32_t client_capabilities = smb1cli_conn_capabilities(cli->conn); 302 303 /* 304 * We only send capabilities based on the mask for: 305 * - client only flags 306 * - flags used in both directions 307 * 308 * We do not echo the server only flags, except some legacy flags. 309 * 310 * SMB_CAP_LEGACY_CLIENT_MASK contains CAP_LARGE_READX and 311 * CAP_LARGE_WRITEX in order to allow us to do large reads 312 * against old Samba releases (<= 3.6.x). 313 */ 314 client_capabilities &= (SMB_CAP_BOTH_MASK | SMB_CAP_LEGACY_CLIENT_MASK); 315 316 /* 317 * Session Setup specific flags CAP_DYNAMIC_REAUTH 318 * and CAP_EXTENDED_SECURITY are passed by the caller. 319 * We need that in order to do guest logins even if 320 * CAP_EXTENDED_SECURITY is negotiated. 321 */ 322 client_capabilities &= ~(CAP_DYNAMIC_REAUTH|CAP_EXTENDED_SECURITY); 323 sesssetup_capabilities &= (CAP_DYNAMIC_REAUTH|CAP_EXTENDED_SECURITY); 324 client_capabilities |= sesssetup_capabilities; 325 326 return client_capabilities; 385 327 } 386 328 … … 398 340 399 341 struct tevent_req *cli_session_setup_guest_create(TALLOC_CTX *mem_ctx, 400 struct event_context *ev,342 struct tevent_context *ev, 401 343 struct cli_state *cli, 402 344 struct tevent_req **psmbreq) … … 420 362 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE); 421 363 SSVAL(vwv+3, 0, 2); 422 SSVAL(vwv+4, 0, cli ->pid);423 SIVAL(vwv+5, 0, cli->sesskey);364 SSVAL(vwv+4, 0, cli_state_get_vc_num(cli)); 365 SIVAL(vwv+5, 0, smb1cli_conn_server_session_key(cli->conn)); 424 366 SSVAL(vwv+7, 0, 0); 425 367 SSVAL(vwv+8, 0, 0); 426 368 SSVAL(vwv+9, 0, 0); 427 369 SSVAL(vwv+10, 0, 0); 428 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli ));370 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli, 0)); 429 371 430 372 bytes = talloc_array(state, uint8_t, 0); 431 373 432 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "", 1, /* username */374 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "", 1, /* username */ 433 375 NULL); 434 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "", 1, /* workgroup */376 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "", 1, /* workgroup */ 435 377 NULL); 436 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Unix", 5, NULL);437 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Samba", 6, NULL);378 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Unix", 5, NULL); 379 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Samba", 6, NULL); 438 380 439 381 if (bytes == NULL) { … … 457 399 458 400 struct tevent_req *cli_session_setup_guest_send(TALLOC_CTX *mem_ctx, 459 struct event_context *ev,401 struct tevent_context *ev, 460 402 struct cli_state *cli) 461 403 { … … 468 410 } 469 411 470 status = cli_smb_req_send(subreq);471 if ( NT_STATUS_IS_OK(status)) {412 status = smb1cli_req_chain_submit(&subreq, 1); 413 if (!NT_STATUS_IS_OK(status)) { 472 414 tevent_req_nterror(req, status); 473 415 return tevent_req_post(req, ev); … … 485 427 uint32_t num_bytes; 486 428 uint8_t *in; 487 char *inbuf;429 uint8_t *inhdr; 488 430 uint8_t *bytes; 489 431 uint8_t *p; … … 501 443 } 502 444 503 in buf = (char *)in;445 inhdr = in + NBT_HDR_SIZE; 504 446 p = bytes; 505 447 506 cli ->vuid = SVAL(inbuf, smb_uid);507 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);448 cli_state_set_uid(state->cli, SVAL(inhdr, HDR_UID)); 449 smb1cli_session_set_action(cli->smb1.session, SVAL(vwv+2, 0)); 508 450 509 451 status = smb_bytes_talloc_string(cli, 510 in buf,452 inhdr, 511 453 &cli->server_os, 512 454 p, … … 521 463 522 464 status = smb_bytes_talloc_string(cli, 523 in buf,465 inhdr, 524 466 &cli->server_type, 525 467 p, … … 534 476 535 477 status = smb_bytes_talloc_string(cli, 536 in buf,478 inhdr, 537 479 &cli->server_domain, 538 480 p, … … 546 488 p += ret; 547 489 548 if (strstr(cli->server_type, "Samba")) {549 cli->is_samba = True;550 }551 552 status = cli_set_username(cli, "");553 if (!NT_STATUS_IS_OK(status)) {554 tevent_req_nterror(req, status);555 return;556 }557 490 tevent_req_done(req); 558 491 } … … 561 494 { 562 495 return tevent_req_simple_recv_ntstatus(req); 563 }564 565 static NTSTATUS cli_session_setup_guest(struct cli_state *cli)566 {567 TALLOC_CTX *frame = talloc_stackframe();568 struct event_context *ev;569 struct tevent_req *req;570 NTSTATUS status = NT_STATUS_OK;571 572 if (cli_has_async_calls(cli)) {573 /*574 * Can't use sync call while an async call is in flight575 */576 status = NT_STATUS_INVALID_PARAMETER;577 goto fail;578 }579 580 ev = event_context_init(frame);581 if (ev == NULL) {582 status = NT_STATUS_NO_MEMORY;583 goto fail;584 }585 586 req = cli_session_setup_guest_send(frame, ev, cli);587 if (req == NULL) {588 status = NT_STATUS_NO_MEMORY;589 goto fail;590 }591 592 if (!tevent_req_poll(req, ev)) {593 status = map_nt_error_from_unix(errno);594 goto fail;595 }596 597 status = cli_session_setup_guest_recv(req);598 fail:599 TALLOC_FREE(frame);600 return status;601 496 } 602 497 … … 639 534 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE); 640 535 SSVAL(vwv+3, 0, 2); 641 SSVAL(vwv+4, 0, cli ->pid);642 SIVAL(vwv+5, 0, cli->sesskey);536 SSVAL(vwv+4, 0, cli_state_get_vc_num(cli)); 537 SIVAL(vwv+5, 0, smb1cli_conn_server_session_key(cli->conn)); 643 538 SSVAL(vwv+7, 0, 0); 644 539 SSVAL(vwv+8, 0, 0); 645 540 SSVAL(vwv+9, 0, 0); 646 541 SSVAL(vwv+10, 0, 0); 647 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli ));542 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli, 0)); 648 543 649 544 bytes = talloc_array(state, uint8_t, 0); 650 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), pass, strlen(pass)+1,545 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), pass, strlen(pass)+1, 651 546 &passlen); 652 547 if (tevent_req_nomem(bytes, req)) { 653 548 return tevent_req_post(req, ev); 654 549 } 655 SSVAL(vwv + ( cli_ucs2(cli) ? 8 : 7), 0, passlen);656 657 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),550 SSVAL(vwv + (smbXcli_conn_use_unicode(cli->conn) ? 8 : 7), 0, passlen); 551 552 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), 658 553 user, strlen(user)+1, NULL); 659 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),554 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), 660 555 workgroup, strlen(workgroup)+1, NULL); 661 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),556 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), 662 557 "Unix", 5, NULL); 663 558 … … 667 562 return tevent_req_post(req, ev); 668 563 } 669 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),564 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), 670 565 version, strlen(version)+1, NULL); 671 566 TALLOC_FREE(version); … … 693 588 uint32_t num_bytes; 694 589 uint8_t *in; 695 char *inbuf;590 uint8_t *inhdr; 696 591 uint8_t *bytes; 697 592 uint8_t *p; … … 708 603 } 709 604 710 in buf = (char *)in;605 inhdr = in + NBT_HDR_SIZE; 711 606 p = bytes; 712 607 713 cli ->vuid = SVAL(inbuf, smb_uid);714 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);608 cli_state_set_uid(state->cli, SVAL(inhdr, HDR_UID)); 609 smb1cli_session_set_action(cli->smb1.session, SVAL(vwv+2, 0)); 715 610 716 611 status = smb_bytes_talloc_string(cli, 717 in buf,612 inhdr, 718 613 &cli->server_os, 719 614 p, … … 728 623 729 624 status = smb_bytes_talloc_string(cli, 730 in buf,625 inhdr, 731 626 &cli->server_type, 732 627 p, … … 741 636 742 637 status = smb_bytes_talloc_string(cli, 743 in buf,638 inhdr, 744 639 &cli->server_domain, 745 640 p, … … 753 648 p += ret; 754 649 755 status = cli_set_username(cli, state->user);756 if (tevent_req_nterror(req, status)) {757 return;758 }759 if (strstr(cli->server_type, "Samba")) {760 cli->is_samba = True;761 }762 650 tevent_req_done(req); 763 651 } … … 766 654 { 767 655 return tevent_req_simple_recv_ntstatus(req); 768 }769 770 static NTSTATUS cli_session_setup_plain(struct cli_state *cli,771 const char *user, const char *pass,772 const char *workgroup)773 {774 TALLOC_CTX *frame = talloc_stackframe();775 struct event_context *ev;776 struct tevent_req *req;777 NTSTATUS status = NT_STATUS_NO_MEMORY;778 779 if (cli_has_async_calls(cli)) {780 /*781 * Can't use sync call while an async call is in flight782 */783 status = NT_STATUS_INVALID_PARAMETER;784 goto fail;785 }786 ev = event_context_init(frame);787 if (ev == NULL) {788 goto fail;789 }790 req = cli_session_setup_plain_send(frame, ev, cli, user, pass,791 workgroup);792 if (req == NULL) {793 goto fail;794 }795 if (!tevent_req_poll_ntstatus(req, ev, &status)) {796 goto fail;797 }798 status = cli_session_setup_plain_recv(req);799 fail:800 TALLOC_FREE(frame);801 return status;802 656 } 803 657 … … 854 708 DATA_BLOB names_blob; 855 709 856 server_chal = data_blob(cli->secblob.data, 857 MIN(cli->secblob.length, 8)); 858 if (tevent_req_nomem(server_chal.data, req)) { 859 return tevent_req_post(req, ev); 860 } 710 server_chal = 711 data_blob_const(smb1cli_conn_server_challenge(cli->conn), 712 8); 861 713 862 714 /* 863 715 * note that the 'workgroup' here is a best 864 716 * guess - we don't know the server's domain 865 * at this point. The 'server name' is also866 * dodgy...717 * at this point. Windows clients also don't 718 * use hostname... 867 719 */ 868 720 names_blob = NTLMv2_generate_names_blob( 869 NULL, cli->called.name, workgroup);721 NULL, NULL, workgroup); 870 722 871 723 if (tevent_req_nomem(names_blob.data, req)) { … … 878 730 NULL, &session_key)) { 879 731 data_blob_free(&names_blob); 880 data_blob_free(&server_chal);881 732 tevent_req_nterror( 882 733 req, NT_STATUS_ACCESS_DENIED); … … 884 735 } 885 736 data_blob_free(&names_blob); 886 data_blob_free(&server_chal);887 737 888 738 } else { … … 898 748 } 899 749 900 SMBNTencrypt(pass, cli->secblob.data,750 SMBNTencrypt(pass, smb1cli_conn_server_challenge(cli->conn), 901 751 nt_response.data); 902 752 #endif … … 909 759 } 910 760 911 if (!SMBencrypt(pass,cli->secblob.data, 761 if (!SMBencrypt(pass, 762 smb1cli_conn_server_challenge(cli->conn), 912 763 lm_response.data)) { 913 764 /* … … 945 796 #endif 946 797 } 947 cli_temp_set_signing(cli);948 798 } else { 949 799 /* pre-encrypted password supplied. Only used for … … 987 837 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE); 988 838 SSVAL(vwv+3, 0, 2); 989 SSVAL(vwv+4, 0, cli ->pid);990 SIVAL(vwv+5, 0, cli->sesskey);839 SSVAL(vwv+4, 0, cli_state_get_vc_num(cli)); 840 SIVAL(vwv+5, 0, smb1cli_conn_server_session_key(cli->conn)); 991 841 SSVAL(vwv+7, 0, lm_response.length); 992 842 SSVAL(vwv+8, 0, nt_response.length); 993 843 SSVAL(vwv+9, 0, 0); 994 844 SSVAL(vwv+10, 0, 0); 995 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli ));845 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli, 0)); 996 846 997 847 bytes = talloc_array(state, uint8_t, … … 1010 860 data_blob_free(&nt_response); 1011 861 1012 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),862 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), 1013 863 user, strlen(user)+1, NULL); 1014 864 … … 1020 870 return tevent_req_post(req, ev); 1021 871 } 1022 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),872 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), 1023 873 workgroup_upper, strlen(workgroup_upper)+1, 1024 874 NULL); 1025 875 TALLOC_FREE(workgroup_upper); 1026 876 1027 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Unix", 5, NULL);1028 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Samba", 6, NULL);877 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Unix", 5, NULL); 878 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), "Samba", 6, NULL); 1029 879 if (tevent_req_nomem(bytes, req)) { 1030 880 return tevent_req_post(req, ev); … … 1049 899 uint32_t num_bytes; 1050 900 uint8_t *in; 1051 char *inbuf;901 uint8_t *inhdr; 1052 902 uint8_t *bytes; 1053 903 uint8_t *p; … … 1065 915 } 1066 916 1067 in buf = (char *)in;917 inhdr = in + NBT_HDR_SIZE; 1068 918 p = bytes; 1069 919 1070 cli ->vuid = SVAL(inbuf, smb_uid);1071 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0);920 cli_state_set_uid(state->cli, SVAL(inhdr, HDR_UID)); 921 smb1cli_session_set_action(cli->smb1.session, SVAL(vwv+2, 0)); 1072 922 1073 923 status = smb_bytes_talloc_string(cli, 1074 in buf,924 inhdr, 1075 925 &cli->server_os, 1076 926 p, … … 1084 934 1085 935 status = smb_bytes_talloc_string(cli, 1086 in buf,936 inhdr, 1087 937 &cli->server_type, 1088 938 p, … … 1096 946 1097 947 status = smb_bytes_talloc_string(cli, 1098 in buf,948 inhdr, 1099 949 &cli->server_domain, 1100 950 p, … … 1107 957 p += ret; 1108 958 1109 if (strstr(cli->server_type, "Samba")) { 1110 cli->is_samba = True; 1111 } 1112 1113 status = cli_set_username(cli, state->user); 1114 if (tevent_req_nterror(req, status)) { 1115 return; 1116 } 1117 if (cli_simple_set_signing(cli, state->session_key, state->response) 1118 && !cli_check_sign_mac(cli, (char *)in, 1)) { 959 if (smb1cli_conn_activate_signing(cli->conn, state->session_key, state->response) 960 && !smb1cli_conn_check_signing(cli->conn, (uint8_t *)in, 1)) { 1119 961 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); 1120 962 return; 1121 963 } 1122 964 if (state->session_key.data) { 1123 /* Have plaintext orginal */ 1124 cli_set_session_key(cli, state->session_key); 965 struct smbXcli_session *session = state->cli->smb1.session; 966 967 status = smb1cli_session_set_session_key(session, 968 state->session_key); 969 if (tevent_req_nterror(req, status)) { 970 return; 971 } 1125 972 } 1126 973 tevent_req_done(req); … … 1130 977 { 1131 978 return tevent_req_simple_recv_ntstatus(req); 1132 }1133 1134 static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user,1135 const char *pass, size_t passlen,1136 const char *ntpass, size_t ntpasslen,1137 const char *workgroup)1138 {1139 TALLOC_CTX *frame = talloc_stackframe();1140 struct event_context *ev;1141 struct tevent_req *req;1142 NTSTATUS status = NT_STATUS_NO_MEMORY;1143 1144 if (cli_has_async_calls(cli)) {1145 /*1146 * Can't use sync call while an async call is in flight1147 */1148 status = NT_STATUS_INVALID_PARAMETER;1149 goto fail;1150 }1151 ev = event_context_init(frame);1152 if (ev == NULL) {1153 goto fail;1154 }1155 req = cli_session_setup_nt1_send(frame, ev, cli, user, pass, passlen,1156 ntpass, ntpasslen, workgroup);1157 if (req == NULL) {1158 goto fail;1159 }1160 if (!tevent_req_poll_ntstatus(req, ev, &status)) {1161 goto fail;1162 }1163 status = cli_session_setup_nt1_recv(req);1164 fail:1165 TALLOC_FREE(frame);1166 return status;1167 979 } 1168 980 … … 1184 996 uint8_t *buf; 1185 997 1186 NTSTATUS status; 1187 char *inbuf; 998 DATA_BLOB smb2_blob; 999 struct iovec *recv_iov; 1000 1001 NTSTATUS status; 1002 uint8_t *inbuf; 1188 1003 DATA_BLOB ret_blob; 1189 1004 }; … … 1200 1015 struct tevent_req *req, *subreq; 1201 1016 struct cli_sesssetup_blob_state *state; 1017 uint32_t usable_space; 1202 1018 1203 1019 req = tevent_req_create(mem_ctx, &state, … … 1210 1026 state->cli = cli; 1211 1027 1212 if (cli->max_xmit < BASE_SESSSETUP_BLOB_PACKET_SIZE + 1) { 1028 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) { 1029 usable_space = UINT16_MAX; 1030 } else { 1031 usable_space = cli_state_available_size(cli, 1032 BASE_SESSSETUP_BLOB_PACKET_SIZE); 1033 } 1034 1035 if (usable_space == 0) { 1213 1036 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small " 1214 "(was %u, need minimum %u)\n", 1215 (unsigned int)cli->max_xmit, 1216 BASE_SESSSETUP_BLOB_PACKET_SIZE)); 1037 "(not possible to send %u bytes)\n", 1038 BASE_SESSSETUP_BLOB_PACKET_SIZE + 1)); 1217 1039 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); 1218 1040 return tevent_req_post(req, ev); 1219 1041 } 1220 state->max_blob_size = 1221 MIN(cli->max_xmit - BASE_SESSSETUP_BLOB_PACKET_SIZE, 0xFFFF); 1042 state->max_blob_size = MIN(usable_space, 0xFFFF); 1222 1043 1223 1044 if (!cli_sesssetup_blob_next(state, &subreq)) { … … 1234 1055 struct tevent_req *subreq; 1235 1056 uint16_t thistime; 1057 1058 thistime = MIN(state->blob.length, state->max_blob_size); 1059 1060 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) { 1061 1062 state->smb2_blob.data = state->blob.data; 1063 state->smb2_blob.length = thistime; 1064 1065 state->blob.data += thistime; 1066 state->blob.length -= thistime; 1067 1068 subreq = smb2cli_session_setup_send(state, state->ev, 1069 state->cli->conn, 1070 state->cli->timeout, 1071 state->cli->smb2.session, 1072 0, /* in_flags */ 1073 SMB2_CAP_DFS, /* in_capabilities */ 1074 0, /* in_channel */ 1075 0, /* in_previous_session_id */ 1076 &state->smb2_blob); 1077 if (subreq == NULL) { 1078 return false; 1079 } 1080 *psubreq = subreq; 1081 return true; 1082 } 1236 1083 1237 1084 SCVAL(state->vwv+0, 0, 0xFF); … … 1243 1090 SIVAL(state->vwv+5, 0, 0); 1244 1091 1245 thistime = MIN(state->blob.length, state->max_blob_size);1246 1092 SSVAL(state->vwv+7, 0, thistime); 1247 1093 … … 1249 1095 SSVAL(state->vwv+9, 0, 0); 1250 1096 SIVAL(state->vwv+10, 0, 1251 cli_session_setup_capabilities(state->cli) 1252 | CAP_EXTENDED_SECURITY); 1097 cli_session_setup_capabilities(state->cli, CAP_EXTENDED_SECURITY)); 1253 1098 1254 1099 state->buf = (uint8_t *)talloc_memdup(state, state->blob.data, … … 1260 1105 state->blob.length -= thistime; 1261 1106 1262 state->buf = smb_bytes_push_str(state->buf, cli_ucs2(state->cli),1107 state->buf = smb_bytes_push_str(state->buf, smbXcli_conn_use_unicode(state->cli->conn), 1263 1108 "Unix", 5, NULL); 1264 state->buf = smb_bytes_push_str(state->buf, cli_ucs2(state->cli),1109 state->buf = smb_bytes_push_str(state->buf, smbXcli_conn_use_unicode(state->cli->conn), 1265 1110 "Samba", 6, NULL); 1266 1111 if (state->buf == NULL) { … … 1291 1136 uint8_t *p; 1292 1137 uint16_t blob_length; 1293 uint8_t *inbuf; 1138 uint8_t *in; 1139 uint8_t *inhdr; 1294 1140 ssize_t ret; 1295 1141 1296 status = cli_smb_recv(subreq, state, &inbuf, 4, &wct, &vwv, 1297 &num_bytes, &bytes); 1142 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) { 1143 status = smb2cli_session_setup_recv(subreq, state, 1144 &state->recv_iov, 1145 &state->ret_blob); 1146 } else { 1147 status = cli_smb_recv(subreq, state, &in, 4, &wct, &vwv, 1148 &num_bytes, &bytes); 1149 TALLOC_FREE(state->buf); 1150 } 1298 1151 TALLOC_FREE(subreq); 1299 1152 if (!NT_STATUS_IS_OK(status) … … 1304 1157 1305 1158 state->status = status; 1306 TALLOC_FREE(state->buf); 1307 1308 state->inbuf = (char *)inbuf; 1309 cli->vuid = SVAL(state->inbuf, smb_uid); 1310 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0); 1159 1160 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) { 1161 goto next; 1162 } 1163 1164 state->inbuf = in; 1165 inhdr = in + NBT_HDR_SIZE; 1166 cli_state_set_uid(state->cli, SVAL(inhdr, HDR_UID)); 1167 smb1cli_session_set_action(cli->smb1.session, SVAL(vwv+2, 0)); 1311 1168 1312 1169 blob_length = SVAL(vwv+3, 0); … … 1320 1177 1321 1178 status = smb_bytes_talloc_string(cli, 1322 (char *)inbuf,1179 inhdr, 1323 1180 &cli->server_os, 1324 1181 p, … … 1333 1190 1334 1191 status = smb_bytes_talloc_string(cli, 1335 (char *)inbuf,1192 inhdr, 1336 1193 &cli->server_type, 1337 1194 p, … … 1346 1203 1347 1204 status = smb_bytes_talloc_string(cli, 1348 (char *)inbuf,1205 inhdr, 1349 1206 &cli->server_domain, 1350 1207 p, … … 1358 1215 p += ret; 1359 1216 1360 if (strstr(cli->server_type, "Samba")) { 1361 cli->is_samba = True; 1362 } 1363 1217 next: 1364 1218 if (state->blob.length != 0) { 1365 1219 /* … … 1367 1221 */ 1368 1222 if (!cli_sesssetup_blob_next(state, &subreq)) { 1369 tevent_req_ nomem(NULL,req);1223 tevent_req_oom(req); 1370 1224 return; 1371 1225 } … … 1379 1233 TALLOC_CTX *mem_ctx, 1380 1234 DATA_BLOB *pblob, 1381 char **pinbuf) 1235 uint8_t **pinbuf, 1236 struct iovec **precv_iov) 1382 1237 { 1383 1238 struct cli_sesssetup_blob_state *state = tevent_req_data( 1384 1239 req, struct cli_sesssetup_blob_state); 1385 1240 NTSTATUS status; 1386 char *inbuf; 1241 uint8_t *inbuf; 1242 struct iovec *recv_iov; 1387 1243 1388 1244 if (tevent_req_is_nterror(req, &status)) { 1389 state->cli->vuid = 0; 1245 TALLOC_FREE(state->cli->smb2.session); 1246 cli_state_set_uid(state->cli, UID_FIELD_INVALID); 1390 1247 return status; 1391 1248 } 1392 1249 1393 1250 inbuf = talloc_move(mem_ctx, &state->inbuf); 1251 recv_iov = talloc_move(mem_ctx, &state->recv_iov); 1394 1252 if (pblob != NULL) { 1395 1253 *pblob = state->ret_blob; … … 1397 1255 if (pinbuf != NULL) { 1398 1256 *pinbuf = inbuf; 1257 } 1258 if (precv_iov != NULL) { 1259 *precv_iov = recv_iov; 1399 1260 } 1400 1261 /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */ … … 1412 1273 } 1413 1274 1414 /****************************************************************************1415 Do a spnego/kerberos encrypted session setup.1416 ****************************************************************************/1417 1418 struct cli_session_setup_kerberos_state {1419 struct cli_state *cli;1420 DATA_BLOB negTokenTarg;1421 DATA_BLOB session_key_krb5;1422 ADS_STATUS ads_status;1423 };1424 1425 static void cli_session_setup_kerberos_done(struct tevent_req *subreq);1426 1427 static struct tevent_req *cli_session_setup_kerberos_send(1428 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,1429 const char *principal, const char *workgroup)1430 {1431 struct tevent_req *req, *subreq;1432 struct cli_session_setup_kerberos_state *state;1433 int rc;1434 1435 DEBUG(2,("Doing kerberos session setup\n"));1436 1437 req = tevent_req_create(mem_ctx, &state,1438 struct cli_session_setup_kerberos_state);1439 if (req == NULL) {1440 return NULL;1441 }1442 state->cli = cli;1443 state->ads_status = ADS_SUCCESS;1444 1445 cli_temp_set_signing(cli);1446 1447 /*1448 * Ok, this is cheating: spnego_gen_krb5_negTokenInit can block if1449 * we have to acquire a ticket. To be fixed later :-)1450 */1451 rc = spnego_gen_krb5_negTokenInit(state, principal, 0, &state->negTokenTarg,1452 &state->session_key_krb5, 0, NULL);1453 if (rc) {1454 DEBUG(1, ("cli_session_setup_kerberos: "1455 "spnego_gen_krb5_negTokenInit failed: %s\n",1456 error_message(rc)));1457 state->ads_status = ADS_ERROR_KRB5(rc);1458 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);1459 return tevent_req_post(req, ev);1460 }1461 1462 #if 01463 file_save("negTokenTarg.dat", state->negTokenTarg.data,1464 state->negTokenTarg.length);1465 #endif1466 1467 subreq = cli_sesssetup_blob_send(state, ev, cli, state->negTokenTarg);1468 if (tevent_req_nomem(subreq, req)) {1469 return tevent_req_post(req, ev);1470 }1471 tevent_req_set_callback(subreq, cli_session_setup_kerberos_done, req);1472 return req;1473 }1474 1475 static void cli_session_setup_kerberos_done(struct tevent_req *subreq)1476 {1477 struct tevent_req *req = tevent_req_callback_data(1478 subreq, struct tevent_req);1479 struct cli_session_setup_kerberos_state *state = tevent_req_data(1480 req, struct cli_session_setup_kerberos_state);1481 char *inbuf = NULL;1482 NTSTATUS status;1483 1484 status = cli_sesssetup_blob_recv(subreq, talloc_tos(), NULL, &inbuf);1485 if (!NT_STATUS_IS_OK(status)) {1486 TALLOC_FREE(subreq);1487 tevent_req_nterror(req, status);1488 return;1489 }1490 1491 cli_set_session_key(state->cli, state->session_key_krb5);1492 1493 if (cli_simple_set_signing(state->cli, state->session_key_krb5,1494 data_blob_null)1495 && !cli_check_sign_mac(state->cli, inbuf, 1)) {1496 TALLOC_FREE(subreq);1497 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);1498 return;1499 }1500 TALLOC_FREE(subreq);1501 tevent_req_done(req);1502 }1503 1504 static ADS_STATUS cli_session_setup_kerberos_recv(struct tevent_req *req)1505 {1506 struct cli_session_setup_kerberos_state *state = tevent_req_data(1507 req, struct cli_session_setup_kerberos_state);1508 NTSTATUS status;1509 1510 if (tevent_req_is_nterror(req, &status)) {1511 return ADS_ERROR_NT(status);1512 }1513 return state->ads_status;1514 }1515 1516 static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli,1517 const char *principal,1518 const char *workgroup)1519 {1520 struct tevent_context *ev;1521 struct tevent_req *req;1522 ADS_STATUS status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);1523 1524 if (cli_has_async_calls(cli)) {1525 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);1526 }1527 ev = tevent_context_init(talloc_tos());1528 if (ev == NULL) {1529 goto fail;1530 }1531 req = cli_session_setup_kerberos_send(ev, ev, cli, principal,1532 workgroup);1533 if (req == NULL) {1534 goto fail;1535 }1536 if (!tevent_req_poll(req, ev)) {1537 status = ADS_ERROR_SYSTEM(errno);1538 goto fail;1539 }1540 status = cli_session_setup_kerberos_recv(req);1541 fail:1542 TALLOC_FREE(ev);1543 return status;1544 }1545 1275 #endif /* HAVE_KRB5 */ 1546 1276 … … 1549 1279 ****************************************************************************/ 1550 1280 1551 struct cli_session_setup_ ntlmssp_state {1281 struct cli_session_setup_gensec_state { 1552 1282 struct tevent_context *ev; 1553 1283 struct cli_state *cli; 1554 struct ntlmssp_state *ntlmssp_state; 1555 int turn; 1284 struct auth_generic_state *auth_generic; 1285 bool is_anonymous; 1286 DATA_BLOB blob_in; 1287 uint8_t *inbuf; 1288 struct iovec *recv_iov; 1556 1289 DATA_BLOB blob_out; 1290 bool local_ready; 1291 bool remote_ready; 1292 DATA_BLOB session_key; 1557 1293 }; 1558 1294 1559 static int cli_session_setup_ntlmssp_state_destructor( 1560 struct cli_session_setup_ntlmssp_state *state) 1561 { 1562 if (state->ntlmssp_state != NULL) { 1563 TALLOC_FREE(state->ntlmssp_state); 1564 } 1295 static int cli_session_setup_gensec_state_destructor( 1296 struct cli_session_setup_gensec_state *state) 1297 { 1298 TALLOC_FREE(state->auth_generic); 1299 data_blob_clear_free(&state->session_key); 1565 1300 return 0; 1566 1301 } 1567 1302 1568 static void cli_session_setup_ntlmssp_done(struct tevent_req *req); 1569 1570 static struct tevent_req *cli_session_setup_ntlmssp_send( 1303 static void cli_session_setup_gensec_local_next(struct tevent_req *req); 1304 static void cli_session_setup_gensec_local_done(struct tevent_req *subreq); 1305 static void cli_session_setup_gensec_remote_next(struct tevent_req *req); 1306 static void cli_session_setup_gensec_remote_done(struct tevent_req *subreq); 1307 static void cli_session_setup_gensec_ready(struct tevent_req *req); 1308 1309 static struct tevent_req *cli_session_setup_gensec_send( 1571 1310 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli, 1572 const char *user, const char *pass, const char *domain) 1573 { 1574 struct tevent_req *req, *subreq; 1575 struct cli_session_setup_ntlmssp_state *state; 1576 NTSTATUS status; 1577 DATA_BLOB blob_out; 1578 const char *OIDs_ntlm[] = {OID_NTLMSSP, NULL}; 1311 const char *user, const char *pass, const char *domain, 1312 enum credentials_use_kerberos krb5_state, 1313 const char *target_service, 1314 const char *target_hostname, 1315 const char *target_principal) 1316 { 1317 struct tevent_req *req; 1318 struct cli_session_setup_gensec_state *state; 1319 NTSTATUS status; 1320 bool use_spnego_principal = lp_client_use_spnego_principal(); 1579 1321 1580 1322 req = tevent_req_create(mem_ctx, &state, 1581 struct cli_session_setup_ ntlmssp_state);1323 struct cli_session_setup_gensec_state); 1582 1324 if (req == NULL) { 1583 1325 return NULL; … … 1585 1327 state->ev = ev; 1586 1328 state->cli = cli; 1587 state->turn = 1; 1588 1589 state->ntlmssp_state = NULL; 1329 1590 1330 talloc_set_destructor( 1591 state, cli_session_setup_ntlmssp_state_destructor); 1592 1593 cli_temp_set_signing(cli); 1594 1595 status = ntlmssp_client_start(state, 1596 global_myname(), 1597 lp_workgroup(), 1598 lp_client_ntlmv2_auth(), 1599 &state->ntlmssp_state); 1600 if (!NT_STATUS_IS_OK(status)) { 1601 goto fail; 1602 } 1603 ntlmssp_want_feature(state->ntlmssp_state, 1604 NTLMSSP_FEATURE_SESSION_KEY); 1331 state, cli_session_setup_gensec_state_destructor); 1332 1333 if (user == NULL || strlen(user) == 0) { 1334 if (pass != NULL && strlen(pass) == 0) { 1335 /* 1336 * some callers pass "" as no password 1337 * 1338 * gensec only handles NULL as no password. 1339 */ 1340 pass = NULL; 1341 } 1342 } 1343 1344 status = auth_generic_client_prepare(state, &state->auth_generic); 1345 if (tevent_req_nterror(req, status)) { 1346 return tevent_req_post(req, ev); 1347 } 1348 1349 gensec_want_feature(state->auth_generic->gensec_security, 1350 GENSEC_FEATURE_SESSION_KEY); 1605 1351 if (cli->use_ccache) { 1606 ntlmssp_want_feature(state->ntlmssp_state, 1607 NTLMSSP_FEATURE_CCACHE); 1608 } 1609 status = ntlmssp_set_username(state->ntlmssp_state, user); 1610 if (!NT_STATUS_IS_OK(status)) { 1611 goto fail; 1612 } 1613 status = ntlmssp_set_domain(state->ntlmssp_state, domain); 1614 if (!NT_STATUS_IS_OK(status)) { 1615 goto fail; 1616 } 1617 status = ntlmssp_set_password(state->ntlmssp_state, pass); 1618 if (!NT_STATUS_IS_OK(status)) { 1619 goto fail; 1620 } 1621 status = ntlmssp_update(state->ntlmssp_state, data_blob_null, 1622 &blob_out); 1623 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 1624 goto fail; 1625 } 1626 1627 state->blob_out = spnego_gen_negTokenInit(state, OIDs_ntlm, &blob_out, NULL); 1628 data_blob_free(&blob_out); 1629 1630 subreq = cli_sesssetup_blob_send(state, ev, cli, state->blob_out); 1352 gensec_want_feature(state->auth_generic->gensec_security, 1353 GENSEC_FEATURE_NTLM_CCACHE); 1354 if (pass != NULL && strlen(pass) == 0) { 1355 /* 1356 * some callers pass "" as no password 1357 * 1358 * GENSEC_FEATURE_NTLM_CCACHE only handles 1359 * NULL as no password. 1360 */ 1361 pass = NULL; 1362 } 1363 } 1364 1365 status = auth_generic_set_username(state->auth_generic, user); 1366 if (tevent_req_nterror(req, status)) { 1367 return tevent_req_post(req, ev); 1368 } 1369 1370 status = auth_generic_set_domain(state->auth_generic, domain); 1371 if (tevent_req_nterror(req, status)) { 1372 return tevent_req_post(req, ev); 1373 } 1374 1375 if (cli->pw_nt_hash) { 1376 struct samr_Password nt_hash; 1377 size_t converted; 1378 bool ok; 1379 1380 if (pass == NULL) { 1381 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX); 1382 return tevent_req_post(req, ev); 1383 } 1384 1385 converted = strhex_to_str((char *)nt_hash.hash, 1386 sizeof(nt_hash.hash), 1387 pass, strlen(pass)); 1388 if (converted != sizeof(nt_hash.hash)) { 1389 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX); 1390 return tevent_req_post(req, ev); 1391 } 1392 1393 ok = cli_credentials_set_nt_hash(state->auth_generic->credentials, 1394 &nt_hash, CRED_SPECIFIED); 1395 if (!ok) { 1396 tevent_req_oom(req); 1397 return tevent_req_post(req, ev); 1398 } 1399 } else { 1400 status = auth_generic_set_password(state->auth_generic, pass); 1401 if (tevent_req_nterror(req, status)) { 1402 return tevent_req_post(req, ev); 1403 } 1404 } 1405 1406 cli_credentials_set_kerberos_state(state->auth_generic->credentials, 1407 krb5_state); 1408 1409 if (krb5_state == CRED_DONT_USE_KERBEROS) { 1410 use_spnego_principal = false; 1411 } 1412 1413 if (target_service != NULL) { 1414 status = gensec_set_target_service( 1415 state->auth_generic->gensec_security, 1416 target_service); 1417 if (tevent_req_nterror(req, status)) { 1418 return tevent_req_post(req, ev); 1419 } 1420 } 1421 1422 if (target_hostname != NULL) { 1423 status = gensec_set_target_hostname( 1424 state->auth_generic->gensec_security, 1425 target_hostname); 1426 if (tevent_req_nterror(req, status)) { 1427 return tevent_req_post(req, ev); 1428 } 1429 } 1430 1431 if (target_principal != NULL) { 1432 status = gensec_set_target_principal( 1433 state->auth_generic->gensec_security, 1434 target_principal); 1435 if (tevent_req_nterror(req, status)) { 1436 return tevent_req_post(req, ev); 1437 } 1438 use_spnego_principal = false; 1439 } else if (target_service != NULL && target_hostname != NULL) { 1440 use_spnego_principal = false; 1441 } 1442 1443 if (use_spnego_principal) { 1444 const DATA_BLOB *b; 1445 b = smbXcli_conn_server_gss_blob(cli->conn); 1446 if (b != NULL) { 1447 state->blob_in = *b; 1448 } 1449 } 1450 1451 state->is_anonymous = cli_credentials_is_anonymous(state->auth_generic->credentials); 1452 1453 status = auth_generic_client_start(state->auth_generic, 1454 GENSEC_OID_SPNEGO); 1455 if (tevent_req_nterror(req, status)) { 1456 return tevent_req_post(req, ev); 1457 } 1458 1459 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) { 1460 state->cli->smb2.session = smbXcli_session_create(cli, 1461 cli->conn); 1462 if (tevent_req_nomem(state->cli->smb2.session, req)) { 1463 return tevent_req_post(req, ev); 1464 } 1465 } 1466 1467 cli_session_setup_gensec_local_next(req); 1468 if (!tevent_req_is_in_progress(req)) { 1469 return tevent_req_post(req, ev); 1470 } 1471 1472 return req; 1473 } 1474 1475 static void cli_session_setup_gensec_local_next(struct tevent_req *req) 1476 { 1477 struct cli_session_setup_gensec_state *state = 1478 tevent_req_data(req, 1479 struct cli_session_setup_gensec_state); 1480 struct tevent_req *subreq = NULL; 1481 1482 if (state->local_ready) { 1483 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); 1484 return; 1485 } 1486 1487 subreq = gensec_update_send(state, state->ev, 1488 state->auth_generic->gensec_security, 1489 state->blob_in); 1631 1490 if (tevent_req_nomem(subreq, req)) { 1632 return tevent_req_post(req, ev); 1633 } 1634 tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req); 1635 return req; 1636 fail: 1637 tevent_req_nterror(req, status); 1638 return tevent_req_post(req, ev); 1639 } 1640 1641 static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq) 1642 { 1643 struct tevent_req *req = tevent_req_callback_data( 1644 subreq, struct tevent_req); 1645 struct cli_session_setup_ntlmssp_state *state = tevent_req_data( 1646 req, struct cli_session_setup_ntlmssp_state); 1647 DATA_BLOB blob_in, msg_in, blob_out; 1648 char *inbuf = NULL; 1649 bool parse_ret; 1650 NTSTATUS status; 1651 1652 status = cli_sesssetup_blob_recv(subreq, talloc_tos(), &blob_in, 1653 &inbuf); 1491 return; 1492 } 1493 tevent_req_set_callback(subreq, cli_session_setup_gensec_local_done, req); 1494 } 1495 1496 static void cli_session_setup_gensec_local_done(struct tevent_req *subreq) 1497 { 1498 struct tevent_req *req = 1499 tevent_req_callback_data(subreq, 1500 struct tevent_req); 1501 struct cli_session_setup_gensec_state *state = 1502 tevent_req_data(req, 1503 struct cli_session_setup_gensec_state); 1504 NTSTATUS status; 1505 1506 status = gensec_update_recv(subreq, state, &state->blob_out); 1507 TALLOC_FREE(subreq); 1508 state->blob_in = data_blob_null; 1509 if (!NT_STATUS_IS_OK(status) && 1510 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) 1511 { 1512 tevent_req_nterror(req, status); 1513 return; 1514 } 1515 1516 if (NT_STATUS_IS_OK(status)) { 1517 state->local_ready = true; 1518 } 1519 1520 if (state->local_ready && state->remote_ready) { 1521 cli_session_setup_gensec_ready(req); 1522 return; 1523 } 1524 1525 cli_session_setup_gensec_remote_next(req); 1526 } 1527 1528 static void cli_session_setup_gensec_remote_next(struct tevent_req *req) 1529 { 1530 struct cli_session_setup_gensec_state *state = 1531 tevent_req_data(req, 1532 struct cli_session_setup_gensec_state); 1533 struct tevent_req *subreq = NULL; 1534 1535 if (state->remote_ready) { 1536 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); 1537 return; 1538 } 1539 1540 subreq = cli_sesssetup_blob_send(state, state->ev, 1541 state->cli, state->blob_out); 1542 if (tevent_req_nomem(subreq, req)) { 1543 return; 1544 } 1545 tevent_req_set_callback(subreq, 1546 cli_session_setup_gensec_remote_done, 1547 req); 1548 } 1549 1550 static void cli_session_setup_gensec_remote_done(struct tevent_req *subreq) 1551 { 1552 struct tevent_req *req = 1553 tevent_req_callback_data(subreq, 1554 struct tevent_req); 1555 struct cli_session_setup_gensec_state *state = 1556 tevent_req_data(req, 1557 struct cli_session_setup_gensec_state); 1558 NTSTATUS status; 1559 1560 TALLOC_FREE(state->inbuf); 1561 TALLOC_FREE(state->recv_iov); 1562 1563 status = cli_sesssetup_blob_recv(subreq, state, &state->blob_in, 1564 &state->inbuf, &state->recv_iov); 1654 1565 TALLOC_FREE(subreq); 1655 1566 data_blob_free(&state->blob_out); 1567 if (!NT_STATUS_IS_OK(status) && 1568 !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) 1569 { 1570 tevent_req_nterror(req, status); 1571 return; 1572 } 1656 1573 1657 1574 if (NT_STATUS_IS_OK(status)) { 1658 if (state->cli->server_domain[0] == '\0') { 1659 TALLOC_FREE(state->cli->server_domain); 1660 state->cli->server_domain = talloc_strdup(state->cli, 1661 state->ntlmssp_state->server.netbios_domain); 1662 if (state->cli->server_domain == NULL) { 1663 TALLOC_FREE(subreq); 1664 tevent_req_nterror(req, NT_STATUS_NO_MEMORY); 1575 struct smbXcli_session *session = NULL; 1576 bool is_guest = false; 1577 1578 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) { 1579 session = state->cli->smb2.session; 1580 } else { 1581 session = state->cli->smb1.session; 1582 } 1583 1584 is_guest = smbXcli_session_is_guest(session); 1585 if (is_guest) { 1586 /* 1587 * We can't finish the gensec handshake, we don't 1588 * have a negotiated session key. 1589 * 1590 * So just pretend we are completely done. 1591 */ 1592 state->blob_in = data_blob_null; 1593 state->local_ready = true; 1594 } 1595 1596 state->remote_ready = true; 1597 } 1598 1599 if (state->local_ready && state->remote_ready) { 1600 cli_session_setup_gensec_ready(req); 1601 return; 1602 } 1603 1604 cli_session_setup_gensec_local_next(req); 1605 } 1606 1607 static void cli_session_setup_gensec_ready(struct tevent_req *req) 1608 { 1609 struct cli_session_setup_gensec_state *state = 1610 tevent_req_data(req, 1611 struct cli_session_setup_gensec_state); 1612 const char *server_domain = NULL; 1613 NTSTATUS status; 1614 1615 if (state->blob_in.length != 0) { 1616 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); 1617 return; 1618 } 1619 1620 if (state->blob_out.length != 0) { 1621 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); 1622 return; 1623 } 1624 1625 /* 1626 * gensec_ntlmssp_server_domain() returns NULL 1627 * if NTLMSSP is not used. 1628 * 1629 * We can remove this later 1630 * and leave the server domain empty for SMB2 and above 1631 * in future releases. 1632 */ 1633 server_domain = gensec_ntlmssp_server_domain( 1634 state->auth_generic->gensec_security); 1635 1636 if (state->cli->server_domain[0] == '\0' && server_domain != NULL) { 1637 TALLOC_FREE(state->cli->server_domain); 1638 state->cli->server_domain = talloc_strdup(state->cli, 1639 server_domain); 1640 if (state->cli->server_domain == NULL) { 1641 tevent_req_nterror(req, NT_STATUS_NO_MEMORY); 1642 return; 1643 } 1644 } 1645 1646 if (state->is_anonymous) { 1647 /* 1648 * Windows server does not set the 1649 * SMB2_SESSION_FLAG_IS_NULL flag. 1650 * 1651 * This fix makes sure we do not try 1652 * to verify a signature on the final 1653 * session setup response. 1654 */ 1655 tevent_req_done(req); 1656 return; 1657 } 1658 1659 status = gensec_session_key(state->auth_generic->gensec_security, 1660 state, &state->session_key); 1661 if (tevent_req_nterror(req, status)) { 1662 return; 1663 } 1664 1665 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) { 1666 struct smbXcli_session *session = state->cli->smb2.session; 1667 1668 status = smb2cli_session_set_session_key(session, 1669 state->session_key, 1670 state->recv_iov); 1671 if (tevent_req_nterror(req, status)) { 1672 return; 1673 } 1674 } else { 1675 struct smbXcli_session *session = state->cli->smb1.session; 1676 bool active; 1677 1678 status = smb1cli_session_set_session_key(session, 1679 state->session_key); 1680 if (tevent_req_nterror(req, status)) { 1681 return; 1682 } 1683 1684 active = smb1cli_conn_activate_signing(state->cli->conn, 1685 state->session_key, 1686 data_blob_null); 1687 if (active) { 1688 bool ok; 1689 1690 ok = smb1cli_conn_check_signing(state->cli->conn, 1691 state->inbuf, 1); 1692 if (!ok) { 1693 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); 1665 1694 return; 1666 1695 } 1667 1696 } 1668 cli_set_session_key( 1669 state->cli, state->ntlmssp_state->session_key); 1670 1671 if (cli_simple_set_signing( 1672 state->cli, state->ntlmssp_state->session_key, 1673 data_blob_null) 1674 && !cli_check_sign_mac(state->cli, inbuf, 1)) { 1675 TALLOC_FREE(subreq); 1676 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); 1677 return; 1678 } 1679 TALLOC_FREE(subreq); 1680 TALLOC_FREE(state->ntlmssp_state); 1681 tevent_req_done(req); 1682 return; 1683 } 1684 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 1685 tevent_req_nterror(req, status); 1686 return; 1687 } 1688 1689 if (blob_in.length == 0) { 1690 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL); 1691 return; 1692 } 1693 1694 if ((state->turn == 1) 1695 && NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 1696 DATA_BLOB tmp_blob = data_blob_null; 1697 /* the server might give us back two challenges */ 1698 parse_ret = spnego_parse_challenge(state, blob_in, &msg_in, 1699 &tmp_blob); 1700 data_blob_free(&tmp_blob); 1697 } 1698 1699 tevent_req_done(req); 1700 } 1701 1702 static NTSTATUS cli_session_setup_gensec_recv(struct tevent_req *req) 1703 { 1704 struct cli_session_setup_gensec_state *state = 1705 tevent_req_data(req, 1706 struct cli_session_setup_gensec_state); 1707 NTSTATUS status; 1708 1709 if (tevent_req_is_nterror(req, &status)) { 1710 cli_state_set_uid(state->cli, UID_FIELD_INVALID); 1711 return status; 1712 } 1713 return NT_STATUS_OK; 1714 } 1715 1716 #ifdef HAVE_KRB5 1717 1718 static char *cli_session_setup_get_principal( 1719 TALLOC_CTX *mem_ctx, const char *spnego_principal, 1720 const char *remote_name, const char *dest_realm) 1721 { 1722 char *principal = NULL; 1723 1724 if (!lp_client_use_spnego_principal() || 1725 strequal(spnego_principal, ADS_IGNORE_PRINCIPAL)) { 1726 spnego_principal = NULL; 1727 } 1728 if (spnego_principal != NULL) { 1729 DEBUG(3, ("cli_session_setup_spnego: using spnego provided " 1730 "principal %s\n", spnego_principal)); 1731 return talloc_strdup(mem_ctx, spnego_principal); 1732 } 1733 if (is_ipaddress(remote_name) || 1734 strequal(remote_name, STAR_SMBSERVER)) { 1735 return NULL; 1736 } 1737 1738 DEBUG(3, ("cli_session_setup_spnego: using target " 1739 "hostname not SPNEGO principal\n")); 1740 1741 if (dest_realm) { 1742 char *realm = strupper_talloc(talloc_tos(), dest_realm); 1743 if (realm == NULL) { 1744 return NULL; 1745 } 1746 principal = talloc_asprintf(talloc_tos(), "cifs/%s@%s", 1747 remote_name, realm); 1748 TALLOC_FREE(realm); 1701 1749 } else { 1702 parse_ret = spnego_parse_auth_response(state, blob_in, status, 1703 OID_NTLMSSP, &msg_in); 1704 } 1705 state->turn += 1; 1706 1707 if (!parse_ret) { 1708 DEBUG(3,("Failed to parse auth response\n")); 1709 if (NT_STATUS_IS_OK(status) 1710 || NT_STATUS_EQUAL(status, 1711 NT_STATUS_MORE_PROCESSING_REQUIRED)) { 1712 tevent_req_nterror( 1713 req, NT_STATUS_INVALID_NETWORK_RESPONSE); 1714 return; 1715 } 1716 } 1717 1718 status = ntlmssp_update(state->ntlmssp_state, msg_in, &blob_out); 1719 1720 if (!NT_STATUS_IS_OK(status) 1721 && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 1722 TALLOC_FREE(subreq); 1723 TALLOC_FREE(state->ntlmssp_state); 1724 tevent_req_nterror(req, status); 1725 return; 1726 } 1727 1728 state->blob_out = spnego_gen_auth(state, blob_out); 1729 TALLOC_FREE(subreq); 1730 if (tevent_req_nomem(state->blob_out.data, req)) { 1731 return; 1732 } 1733 1734 subreq = cli_sesssetup_blob_send(state, state->ev, state->cli, 1735 state->blob_out); 1736 if (tevent_req_nomem(subreq, req)) { 1737 return; 1738 } 1739 tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req); 1740 } 1741 1742 static NTSTATUS cli_session_setup_ntlmssp_recv(struct tevent_req *req) 1743 { 1744 struct cli_session_setup_ntlmssp_state *state = tevent_req_data( 1745 req, struct cli_session_setup_ntlmssp_state); 1746 NTSTATUS status; 1747 1748 if (tevent_req_is_nterror(req, &status)) { 1749 state->cli->vuid = 0; 1750 return status; 1751 } 1752 return NT_STATUS_OK; 1753 } 1754 1755 static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, 1756 const char *user, 1757 const char *pass, 1758 const char *domain) 1759 { 1760 struct tevent_context *ev; 1761 struct tevent_req *req; 1762 NTSTATUS status = NT_STATUS_NO_MEMORY; 1763 1764 if (cli_has_async_calls(cli)) { 1765 return NT_STATUS_INVALID_PARAMETER; 1766 } 1767 ev = tevent_context_init(talloc_tos()); 1768 if (ev == NULL) { 1769 goto fail; 1770 } 1771 req = cli_session_setup_ntlmssp_send(ev, ev, cli, user, pass, domain); 1772 if (req == NULL) { 1773 goto fail; 1774 } 1775 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 1776 goto fail; 1777 } 1778 status = cli_session_setup_ntlmssp_recv(req); 1779 fail: 1780 TALLOC_FREE(ev); 1781 return status; 1750 principal = kerberos_get_principal_from_service_hostname( 1751 talloc_tos(), "cifs", remote_name, lp_realm()); 1752 } 1753 DEBUG(3, ("cli_session_setup_spnego: guessed server principal=%s\n", 1754 principal ? principal : "<null>")); 1755 1756 return principal; 1757 } 1758 #endif 1759 1760 static char *cli_session_setup_get_account(TALLOC_CTX *mem_ctx, 1761 const char *principal) 1762 { 1763 char *account, *p; 1764 1765 account = talloc_strdup(mem_ctx, principal); 1766 if (account == NULL) { 1767 return NULL; 1768 } 1769 p = strchr_m(account, '@'); 1770 if (p != NULL) { 1771 *p = '\0'; 1772 } 1773 return account; 1782 1774 } 1783 1775 … … 1789 1781 ****************************************************************************/ 1790 1782 1791 ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, 1792 const char *pass, const char *user_domain, 1793 const char * dest_realm) 1794 { 1783 struct cli_session_setup_spnego_state { 1784 struct tevent_context *ev; 1785 struct cli_state *cli; 1786 const char *target_hostname; 1787 const char *user; 1788 const char *account; 1789 const char *pass; 1790 const char *user_domain; 1791 const char *dest_realm; 1792 ADS_STATUS result; 1793 }; 1794 1795 #ifdef HAVE_KRB5 1796 static void cli_session_setup_spnego_done_krb(struct tevent_req *subreq); 1797 #endif 1798 1799 static void cli_session_setup_spnego_done_ntlmssp(struct tevent_req *subreq); 1800 1801 static struct tevent_req *cli_session_setup_spnego_send( 1802 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli, 1803 const char *user, const char *pass, const char *user_domain) 1804 { 1805 struct tevent_req *req, *subreq; 1806 struct cli_session_setup_spnego_state *state; 1795 1807 char *principal = NULL; 1796 1808 char *OIDs[ASN1_MAX_OIDS]; 1797 1809 int i; 1798 DATA_BLOB blob; 1799 const char *p = NULL; 1800 char *account = NULL; 1801 NTSTATUS status; 1802 1803 DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli->secblob.length)); 1810 const char *dest_realm = cli_state_remote_realm(cli); 1811 const DATA_BLOB *server_blob; 1812 1813 req = tevent_req_create(mem_ctx, &state, 1814 struct cli_session_setup_spnego_state); 1815 if (req == NULL) { 1816 return NULL; 1817 } 1818 state->ev = ev; 1819 state->cli = cli; 1820 state->user = user; 1821 state->pass = pass; 1822 state->user_domain = user_domain; 1823 state->dest_realm = dest_realm; 1824 1825 state->account = cli_session_setup_get_account(state, user); 1826 if (tevent_req_nomem(state->account, req)) { 1827 return tevent_req_post(req, ev); 1828 } 1829 1830 state->target_hostname = smbXcli_conn_remote_name(cli->conn); 1831 server_blob = smbXcli_conn_server_gss_blob(cli->conn); 1832 1833 DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", 1834 (unsigned long)server_blob->length)); 1804 1835 1805 1836 /* the server might not even do spnego */ 1806 if ( cli->secblob.length <= 16) {1837 if (server_blob->length == 0) { 1807 1838 DEBUG(3,("server didn't supply a full spnego negprot\n")); 1808 1839 goto ntlmssp; … … 1812 1843 file_save("negprot.dat", cli->secblob.data, cli->secblob.length); 1813 1844 #endif 1814 1815 /* there is 16 bytes of GUID before the real spnego packet starts */1816 blob = data_blob(cli->secblob.data+16, cli->secblob.length-16);1817 1845 1818 1846 /* The server sent us the first part of the SPNEGO exchange in the … … 1820 1848 * negprot reply, but right now we do it. If we don't receive one, 1821 1849 * we try to best guess, then fall back to NTLM. */ 1822 if (!spnego_parse_negTokenInit(talloc_tos(), blob, OIDs, &principal, NULL) || 1850 if (!spnego_parse_negTokenInit(state, *server_blob, OIDs, 1851 &principal, NULL) || 1823 1852 OIDs[0] == NULL) { 1824 data_blob_free(&blob);1825 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);1826 }1827 data_blob_free(&blob);1853 state->result = ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); 1854 tevent_req_done(req); 1855 return tevent_req_post(req, ev); 1856 } 1828 1857 1829 1858 /* make sure the server understands kerberos */ … … 1842 1871 DEBUG(3,("got principal=%s\n", principal ? principal : "<null>")); 1843 1872 1844 status = cli_set_username(cli, user);1845 if (!NT_STATUS_IS_OK(status)) {1846 TALLOC_FREE(principal);1847 return ADS_ERROR_NT(status);1848 }1849 1850 1873 #ifdef HAVE_KRB5 1851 1874 /* If password is set we reauthenticate to kerberos server 1852 1875 * and do not store results */ 1853 1876 1854 if (cli->got_kerberos_mechanism && cli->use_kerberos) { 1855 ADS_STATUS rc; 1877 if (user && *user && cli->got_kerberos_mechanism && cli->use_kerberos) { 1878 char *tmp; 1879 1880 tmp = cli_session_setup_get_principal( 1881 talloc_tos(), principal, state->target_hostname, dest_realm); 1882 TALLOC_FREE(principal); 1883 principal = tmp; 1856 1884 1857 1885 if (pass && *pass) { … … 1862 1890 1863 1891 if (ret){ 1892 DEBUG(0, ("Kinit for %s to access %s failed: %s\n", user, principal, error_message(ret))); 1864 1893 TALLOC_FREE(principal); 1865 DEBUG(0, ("Kinit failed: %s\n", error_message(ret)));1866 1894 if (cli->fallback_after_kerberos) 1867 1895 goto ntlmssp; 1868 return ADS_ERROR_KRB5(ret); 1896 state->result = ADS_ERROR_KRB5(ret); 1897 tevent_req_done(req); 1898 return tevent_req_post(req, ev); 1869 1899 } 1870 1900 } 1871 1901 1872 /* We may not be allowed to use the server-supplied SPNEGO principal, or it may not have been supplied to us 1873 */ 1874 if (!lp_client_use_spnego_principal() || strequal(principal, ADS_IGNORE_PRINCIPAL)) { 1875 TALLOC_FREE(principal); 1876 } 1877 1878 if (principal == NULL && 1879 !is_ipaddress(cli->desthost) && 1880 !strequal(STAR_SMBSERVER, 1881 cli->desthost)) { 1882 char *realm = NULL; 1883 char *host = NULL; 1884 DEBUG(3,("cli_session_setup_spnego: using target " 1885 "hostname not SPNEGO principal\n")); 1886 1887 host = strchr_m(cli->desthost, '.'); 1888 if (dest_realm) { 1889 realm = SMB_STRDUP(dest_realm); 1890 if (!realm) { 1891 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); 1892 } 1893 strupper_m(realm); 1894 } else { 1895 if (host) { 1896 /* DNS name. */ 1897 realm = kerberos_get_realm_from_hostname(cli->desthost); 1898 } else { 1899 /* NetBIOS name - use our realm. */ 1900 realm = kerberos_get_default_realm_from_ccache(); 1901 } 1902 if (principal) { 1903 subreq = cli_session_setup_gensec_send( 1904 state, ev, cli, 1905 state->account, pass, user_domain, 1906 CRED_MUST_USE_KERBEROS, 1907 "cifs", state->target_hostname, principal); 1908 if (tevent_req_nomem(subreq, req)) { 1909 return tevent_req_post(req, ev); 1902 1910 } 1903 1904 if (realm == NULL || *realm == '\0') { 1905 realm = SMB_STRDUP(lp_realm()); 1906 if (!realm) { 1907 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); 1908 } 1909 strupper_m(realm); 1910 DEBUG(3,("cli_session_setup_spnego: cannot " 1911 "get realm from dest_realm %s, " 1912 "desthost %s. Using default " 1913 "smb.conf realm %s\n", 1914 dest_realm ? dest_realm : "<null>", 1915 cli->desthost, 1916 realm)); 1917 } 1918 1919 principal = talloc_asprintf(talloc_tos(), 1920 "cifs/%s@%s", 1921 cli->desthost, 1922 realm); 1923 if (!principal) { 1924 SAFE_FREE(realm); 1925 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); 1926 } 1927 DEBUG(3,("cli_session_setup_spnego: guessed " 1928 "server principal=%s\n", 1929 principal ? principal : "<null>")); 1930 1931 SAFE_FREE(realm); 1932 } 1933 1934 if (principal) { 1935 rc = cli_session_setup_kerberos(cli, principal, 1936 dest_realm); 1937 if (ADS_ERR_OK(rc) || !cli->fallback_after_kerberos) { 1938 TALLOC_FREE(principal); 1939 return rc; 1940 } 1911 tevent_req_set_callback( 1912 subreq, cli_session_setup_spnego_done_krb, 1913 req); 1914 return req; 1941 1915 } 1942 1916 } 1943 1917 #endif 1944 1918 1945 TALLOC_FREE(principal);1946 1947 1919 ntlmssp: 1948 1949 account = talloc_strdup(talloc_tos(), user); 1950 if (!account) { 1951 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); 1952 } 1953 1954 /* when falling back to ntlmssp while authenticating with a machine 1955 * account strip off the realm - gd */ 1956 1957 if ((p = strchr_m(user, '@')) != NULL) { 1958 account[PTR_DIFF(p,user)] = '\0'; 1959 } 1960 1961 return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, account, pass, user_domain)); 1962 } 1920 subreq = cli_session_setup_gensec_send( 1921 state, state->ev, state->cli, 1922 state->account, state->pass, state->user_domain, 1923 CRED_DONT_USE_KERBEROS, 1924 "cifs", state->target_hostname, NULL); 1925 if (tevent_req_nomem(subreq, req)) { 1926 return tevent_req_post(req, ev); 1927 } 1928 tevent_req_set_callback( 1929 subreq, cli_session_setup_spnego_done_ntlmssp, req); 1930 return req; 1931 } 1932 1933 #ifdef HAVE_KRB5 1934 static void cli_session_setup_spnego_done_krb(struct tevent_req *subreq) 1935 { 1936 struct tevent_req *req = tevent_req_callback_data( 1937 subreq, struct tevent_req); 1938 struct cli_session_setup_spnego_state *state = tevent_req_data( 1939 req, struct cli_session_setup_spnego_state); 1940 NTSTATUS status; 1941 1942 status = cli_session_setup_gensec_recv(subreq); 1943 TALLOC_FREE(subreq); 1944 state->result = ADS_ERROR_NT(status); 1945 1946 if (ADS_ERR_OK(state->result) || 1947 !state->cli->fallback_after_kerberos) { 1948 tevent_req_done(req); 1949 return; 1950 } 1951 1952 subreq = cli_session_setup_gensec_send( 1953 state, state->ev, state->cli, 1954 state->account, state->pass, state->user_domain, 1955 CRED_DONT_USE_KERBEROS, 1956 "cifs", state->target_hostname, NULL); 1957 if (tevent_req_nomem(subreq, req)) { 1958 return; 1959 } 1960 tevent_req_set_callback(subreq, cli_session_setup_spnego_done_ntlmssp, 1961 req); 1962 } 1963 #endif 1964 1965 static void cli_session_setup_spnego_done_ntlmssp(struct tevent_req *subreq) 1966 { 1967 struct tevent_req *req = tevent_req_callback_data( 1968 subreq, struct tevent_req); 1969 struct cli_session_setup_spnego_state *state = tevent_req_data( 1970 req, struct cli_session_setup_spnego_state); 1971 NTSTATUS status; 1972 1973 status = cli_session_setup_gensec_recv(subreq); 1974 TALLOC_FREE(subreq); 1975 state->result = ADS_ERROR_NT(status); 1976 tevent_req_done(req); 1977 } 1978 1979 static ADS_STATUS cli_session_setup_spnego_recv(struct tevent_req *req) 1980 { 1981 struct cli_session_setup_spnego_state *state = tevent_req_data( 1982 req, struct cli_session_setup_spnego_state); 1983 1984 return state->result; 1985 } 1986 1987 struct cli_session_setup_state { 1988 uint8_t dummy; 1989 }; 1990 1991 static void cli_session_setup_done_lanman2(struct tevent_req *subreq); 1992 static void cli_session_setup_done_spnego(struct tevent_req *subreq); 1993 static void cli_session_setup_done_guest(struct tevent_req *subreq); 1994 static void cli_session_setup_done_plain(struct tevent_req *subreq); 1995 static void cli_session_setup_done_nt1(struct tevent_req *subreq); 1963 1996 1964 1997 /**************************************************************************** … … 1968 2001 ****************************************************************************/ 1969 2002 1970 NTSTATUS cli_session_setup(struct cli_state *cli, 1971 const char *user, 1972 const char *pass, int passlen, 1973 const char *ntpass, int ntpasslen, 1974 const char *workgroup) 1975 { 2003 struct tevent_req *cli_session_setup_send(TALLOC_CTX *mem_ctx, 2004 struct tevent_context *ev, 2005 struct cli_state *cli, 2006 const char *user, 2007 const char *pass, int passlen, 2008 const char *ntpass, int ntpasslen, 2009 const char *workgroup) 2010 { 2011 struct tevent_req *req, *subreq; 2012 struct cli_session_setup_state *state; 1976 2013 char *p; 1977 2014 char *user2; 2015 uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn); 2016 2017 req = tevent_req_create(mem_ctx, &state, 2018 struct cli_session_setup_state); 2019 if (req == NULL) { 2020 return NULL; 2021 } 1978 2022 1979 2023 if (user) { 1980 user2 = talloc_strdup( talloc_tos(), user);2024 user2 = talloc_strdup(state, user); 1981 2025 } else { 1982 user2 = talloc_strdup( talloc_tos(), "");2026 user2 = talloc_strdup(state, ""); 1983 2027 } 1984 2028 if (user2 == NULL) { 1985 return NT_STATUS_NO_MEMORY; 2029 tevent_req_oom(req); 2030 return tevent_req_post(req, ev); 1986 2031 } 1987 2032 … … 1995 2040 *p = 0; 1996 2041 user = p+1; 1997 strupper_m(user2); 2042 if (!strupper_m(user2)) { 2043 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); 2044 return tevent_req_post(req, ev); 2045 } 1998 2046 workgroup = user2; 1999 2047 } 2000 2048 2001 if (cli->protocol < PROTOCOL_LANMAN1) { 2002 /* 2003 * Ensure cli->server_domain, 2004 * cli->server_os and cli->server_type 2005 * are valid pointers. 2006 */ 2007 cli->server_domain = talloc_strdup(cli, ""); 2008 cli->server_os = talloc_strdup(cli, ""); 2009 cli->server_type = talloc_strdup(cli, ""); 2010 if (cli->server_domain == NULL || 2011 cli->server_os == NULL || 2012 cli->server_type == NULL) { 2013 return NT_STATUS_NO_MEMORY; 2014 } 2015 return NT_STATUS_OK; 2049 if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_LANMAN1) { 2050 tevent_req_done(req); 2051 return tevent_req_post(req, ev); 2016 2052 } 2017 2053 … … 2022 2058 /* if its an older server then we have to use the older request format */ 2023 2059 2024 if ( cli->protocol< PROTOCOL_NT1) {2060 if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_NT1) { 2025 2061 if (!lp_client_lanman_auth() && passlen != 24 && (*pass)) { 2026 2062 DEBUG(1, ("Server requested LM password but 'client lanman auth = no'" 2027 2063 " or 'client ntlmv2 auth = yes'\n")); 2028 return NT_STATUS_ACCESS_DENIED; 2029 } 2030 2031 if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 && 2064 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); 2065 return tevent_req_post(req, ev); 2066 } 2067 2068 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 && 2032 2069 !lp_client_plaintext_auth() && (*pass)) { 2033 DEBUG(1, ("Server requested LMpassword but 'client plaintext auth = no'"2070 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'" 2034 2071 " or 'client ntlmv2 auth = yes'\n")); 2035 return NT_STATUS_ACCESS_DENIED; 2036 } 2037 2038 return cli_session_setup_lanman2(cli, user, pass, passlen, 2039 workgroup); 2072 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); 2073 return tevent_req_post(req, ev); 2074 } 2075 2076 subreq = cli_session_setup_lanman2_send( 2077 state, ev, cli, user, pass, passlen, workgroup); 2078 if (tevent_req_nomem(subreq, req)) { 2079 return tevent_req_post(req, ev); 2080 } 2081 tevent_req_set_callback(subreq, cli_session_setup_done_lanman2, 2082 req); 2083 return req; 2084 } 2085 2086 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) { 2087 subreq = cli_session_setup_spnego_send( 2088 state, ev, cli, user, pass, workgroup); 2089 if (tevent_req_nomem(subreq, req)) { 2090 return tevent_req_post(req, ev); 2091 } 2092 tevent_req_set_callback(subreq, cli_session_setup_done_spnego, 2093 req); 2094 return req; 2095 } 2096 2097 /* 2098 * if the server supports extended security then use SPNEGO 2099 * even for anonymous connections. 2100 */ 2101 if (smb1cli_conn_capabilities(cli->conn) & CAP_EXTENDED_SECURITY) { 2102 subreq = cli_session_setup_spnego_send( 2103 state, ev, cli, user, pass, workgroup); 2104 if (tevent_req_nomem(subreq, req)) { 2105 return tevent_req_post(req, ev); 2106 } 2107 tevent_req_set_callback(subreq, cli_session_setup_done_spnego, 2108 req); 2109 return req; 2040 2110 } 2041 2111 … … 2043 2113 passwords are ignored */ 2044 2114 2045 if (!user || !*user) 2046 return cli_session_setup_guest(cli); 2115 if (!user || !*user) { 2116 subreq = cli_session_setup_guest_send(state, ev, cli); 2117 if (tevent_req_nomem(subreq, req)) { 2118 return tevent_req_post(req, ev); 2119 } 2120 tevent_req_set_callback(subreq, cli_session_setup_done_guest, 2121 req); 2122 return req; 2123 } 2047 2124 2048 2125 /* if the server is share level then send a plaintext null … … 2050 2127 connect */ 2051 2128 2052 if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) 2053 return cli_session_setup_plain(cli, user, "", workgroup); 2129 if ((sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) { 2130 subreq = cli_session_setup_plain_send( 2131 state, ev, cli, user, "", workgroup); 2132 if (tevent_req_nomem(subreq, req)) { 2133 return tevent_req_post(req, ev); 2134 } 2135 tevent_req_set_callback(subreq, cli_session_setup_done_plain, 2136 req); 2137 return req; 2138 } 2054 2139 2055 2140 /* if the server doesn't support encryption then we have to use 2056 2141 plaintext. The second password is ignored */ 2057 2142 2058 if (( cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) {2143 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) { 2059 2144 if (!lp_client_plaintext_auth() && (*pass)) { 2060 DEBUG(1, ("Server requested LMpassword but 'client plaintext auth = no'"2145 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'" 2061 2146 " or 'client ntlmv2 auth = yes'\n")); 2062 return NT_STATUS_ACCESS_DENIED; 2063 } 2064 return cli_session_setup_plain(cli, user, pass, workgroup); 2065 } 2066 2067 /* if the server supports extended security then use SPNEGO */ 2068 2069 if (cli->capabilities & CAP_EXTENDED_SECURITY) { 2070 ADS_STATUS status = cli_session_setup_spnego(cli, user, pass, 2071 workgroup, NULL); 2072 if (!ADS_ERR_OK(status)) { 2073 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status))); 2074 return ads_ntstatus(status); 2075 } 2076 } else { 2077 NTSTATUS status; 2078 2147 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); 2148 return tevent_req_post(req, ev); 2149 } 2150 subreq = cli_session_setup_plain_send( 2151 state, ev, cli, user, pass, workgroup); 2152 if (tevent_req_nomem(subreq, req)) { 2153 return tevent_req_post(req, ev); 2154 } 2155 tevent_req_set_callback(subreq, cli_session_setup_done_plain, 2156 req); 2157 return req; 2158 } 2159 2160 { 2079 2161 /* otherwise do a NT1 style session setup */ 2080 2162 if (lp_client_ntlmv2_auth() && lp_client_use_spnego()) { … … 2086 2168 " but 'client use spnego = yes" 2087 2169 " and 'client ntlmv2 auth = yes'\n")); 2088 return NT_STATUS_ACCESS_DENIED; 2089 } 2090 2091 status = cli_session_setup_nt1(cli, user, pass, passlen, 2092 ntpass, ntpasslen, workgroup); 2093 if (!NT_STATUS_IS_OK(status)) { 2094 DEBUG(3,("cli_session_setup: NT1 session setup " 2095 "failed: %s\n", nt_errstr(status))); 2096 return status; 2097 } 2098 } 2099 2100 if (strstr(cli->server_type, "Samba")) { 2101 cli->is_samba = True; 2102 } 2103 2104 return NT_STATUS_OK; 2170 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); 2171 return tevent_req_post(req, ev); 2172 } 2173 2174 subreq = cli_session_setup_nt1_send( 2175 state, ev, cli, user, pass, passlen, ntpass, ntpasslen, 2176 workgroup); 2177 if (tevent_req_nomem(subreq, req)) { 2178 return tevent_req_post(req, ev); 2179 } 2180 tevent_req_set_callback(subreq, cli_session_setup_done_nt1, 2181 req); 2182 return req; 2183 } 2184 2185 tevent_req_done(req); 2186 return tevent_req_post(req, ev); 2187 } 2188 2189 static void cli_session_setup_done_lanman2(struct tevent_req *subreq) 2190 { 2191 struct tevent_req *req = tevent_req_callback_data( 2192 subreq, struct tevent_req); 2193 NTSTATUS status; 2194 2195 status = cli_session_setup_lanman2_recv(subreq); 2196 TALLOC_FREE(subreq); 2197 if (!NT_STATUS_IS_OK(status)) { 2198 tevent_req_nterror(req, status); 2199 return; 2200 } 2201 tevent_req_done(req); 2202 } 2203 2204 static void cli_session_setup_done_spnego(struct tevent_req *subreq) 2205 { 2206 struct tevent_req *req = tevent_req_callback_data( 2207 subreq, struct tevent_req); 2208 ADS_STATUS status; 2209 2210 status = cli_session_setup_spnego_recv(subreq); 2211 TALLOC_FREE(subreq); 2212 if (!ADS_ERR_OK(status)) { 2213 DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status))); 2214 tevent_req_nterror(req, ads_ntstatus(status)); 2215 return; 2216 } 2217 tevent_req_done(req); 2218 } 2219 2220 static void cli_session_setup_done_guest(struct tevent_req *subreq) 2221 { 2222 struct tevent_req *req = tevent_req_callback_data( 2223 subreq, struct tevent_req); 2224 NTSTATUS status; 2225 2226 status = cli_session_setup_guest_recv(subreq); 2227 TALLOC_FREE(subreq); 2228 if (!NT_STATUS_IS_OK(status)) { 2229 tevent_req_nterror(req, status); 2230 return; 2231 } 2232 tevent_req_done(req); 2233 } 2234 2235 static void cli_session_setup_done_plain(struct tevent_req *subreq) 2236 { 2237 struct tevent_req *req = tevent_req_callback_data( 2238 subreq, struct tevent_req); 2239 NTSTATUS status; 2240 2241 status = cli_session_setup_plain_recv(subreq); 2242 TALLOC_FREE(subreq); 2243 if (!NT_STATUS_IS_OK(status)) { 2244 tevent_req_nterror(req, status); 2245 return; 2246 } 2247 tevent_req_done(req); 2248 } 2249 2250 static void cli_session_setup_done_nt1(struct tevent_req *subreq) 2251 { 2252 struct tevent_req *req = tevent_req_callback_data( 2253 subreq, struct tevent_req); 2254 NTSTATUS status; 2255 2256 status = cli_session_setup_nt1_recv(subreq); 2257 TALLOC_FREE(subreq); 2258 if (!NT_STATUS_IS_OK(status)) { 2259 DEBUG(3, ("cli_session_setup: NT1 session setup " 2260 "failed: %s\n", nt_errstr(status))); 2261 tevent_req_nterror(req, status); 2262 return; 2263 } 2264 tevent_req_done(req); 2265 } 2266 2267 NTSTATUS cli_session_setup_recv(struct tevent_req *req) 2268 { 2269 return tevent_req_simple_recv_ntstatus(req); 2270 } 2271 2272 NTSTATUS cli_session_setup(struct cli_state *cli, 2273 const char *user, 2274 const char *pass, int passlen, 2275 const char *ntpass, int ntpasslen, 2276 const char *workgroup) 2277 { 2278 struct tevent_context *ev; 2279 struct tevent_req *req; 2280 NTSTATUS status = NT_STATUS_NO_MEMORY; 2281 2282 if (smbXcli_conn_has_async_calls(cli->conn)) { 2283 return NT_STATUS_INVALID_PARAMETER; 2284 } 2285 ev = samba_tevent_context_init(talloc_tos()); 2286 if (ev == NULL) { 2287 goto fail; 2288 } 2289 req = cli_session_setup_send(ev, ev, cli, user, pass, passlen, 2290 ntpass, ntpasslen, workgroup); 2291 if (req == NULL) { 2292 goto fail; 2293 } 2294 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 2295 goto fail; 2296 } 2297 status = cli_session_setup_recv(req); 2298 fail: 2299 TALLOC_FREE(ev); 2300 return status; 2105 2301 } 2106 2302 … … 2116 2312 static void cli_ulogoff_done(struct tevent_req *subreq); 2117 2313 2118 st ruct tevent_req *cli_ulogoff_send(TALLOC_CTX *mem_ctx,2314 static struct tevent_req *cli_ulogoff_send(TALLOC_CTX *mem_ctx, 2119 2315 struct tevent_context *ev, 2120 2316 struct cli_state *cli) … … 2155 2351 return; 2156 2352 } 2157 state->cli->vuid = -1;2353 cli_state_set_uid(state->cli, UID_FIELD_INVALID); 2158 2354 tevent_req_done(req); 2159 2355 } 2160 2356 2161 NTSTATUS cli_ulogoff_recv(struct tevent_req *req)2357 static NTSTATUS cli_ulogoff_recv(struct tevent_req *req) 2162 2358 { 2163 2359 return tevent_req_simple_recv_ntstatus(req); … … 2170 2366 NTSTATUS status = NT_STATUS_NO_MEMORY; 2171 2367 2172 if (cli_has_async_calls(cli)) { 2368 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) { 2369 status = smb2cli_logoff(cli->conn, 2370 cli->timeout, 2371 cli->smb2.session); 2372 if (!NT_STATUS_IS_OK(status)) { 2373 return status; 2374 } 2375 smb2cli_session_set_id_and_flags(cli->smb2.session, 2376 UINT64_MAX, 0); 2377 return NT_STATUS_OK; 2378 } 2379 2380 if (smbXcli_conn_has_async_calls(cli->conn)) { 2173 2381 return NT_STATUS_INVALID_PARAMETER; 2174 2382 } 2175 ev = tevent_context_init(talloc_tos());2383 ev = samba_tevent_context_init(talloc_tos()); 2176 2384 if (ev == NULL) { 2177 2385 goto fail; … … 2203 2411 2204 2412 struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx, 2205 struct event_context *ev,2413 struct tevent_context *ev, 2206 2414 struct cli_state *cli, 2207 2415 const char *share, const char *dev, … … 2215 2423 char *tmp = NULL; 2216 2424 uint8_t *bytes; 2425 uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn); 2426 uint16_t tcon_flags = 0; 2217 2427 2218 2428 *psmbreq = NULL; … … 2231 2441 2232 2442 /* in user level security don't send a password now */ 2233 if ( cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {2443 if (sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) { 2234 2444 passlen = 1; 2235 2445 pass = ""; … … 2240 2450 } 2241 2451 2242 if (( cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&2452 if ((sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && 2243 2453 *pass && passlen != 24) { 2244 2454 if (!lp_client_lanman_auth()) { … … 2253 2463 * encryption. 2254 2464 */ 2255 SMBencrypt(pass, cli->secblob.data, p24);2465 SMBencrypt(pass, smb1cli_conn_server_challenge(cli->conn), p24); 2256 2466 passlen = 24; 2257 2467 pass = (const char *)p24; 2258 2468 } else { 2259 if(( cli->sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL2469 if((sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL 2260 2470 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)) 2261 2471 == 0) { 2262 char*tmp_pass;2472 uint8_t *tmp_pass; 2263 2473 2264 2474 if (!lp_client_plaintext_auth() && (*pass)) { 2265 DEBUG(1, ("Server requested plaintext"2475 DEBUG(1, ("Server requested PLAINTEXT " 2266 2476 "password but " 2267 "'client lanmanauth = no' or 'client ntlmv2 auth = yes'\n"));2477 "'client plaintext auth = no' or 'client ntlmv2 auth = yes'\n")); 2268 2478 goto access_denied; 2269 2479 } … … 2273 2483 * before using. 2274 2484 */ 2275 tmp_pass = talloc_array(talloc_tos(), char, 128); 2276 if (tmp_pass == NULL) { 2277 tevent_req_nterror(req, NT_STATUS_NO_MEMORY); 2485 tmp_pass = talloc_array(talloc_tos(), uint8_t, 0); 2486 if (tevent_req_nomem(tmp_pass, req)) { 2278 2487 return tevent_req_post(req, ev); 2279 2488 } 2280 passlen = clistr_push(cli, 2281 tmp_pass, 2282 pass, 2283 talloc_get_size(tmp_pass), 2284 STR_TERMINATE); 2285 if (passlen == -1) { 2286 tevent_req_nterror(req, NT_STATUS_NO_MEMORY); 2489 tmp_pass = trans2_bytes_push_str(tmp_pass, 2490 false, /* always DOS */ 2491 pass, 2492 passlen, 2493 NULL); 2494 if (tevent_req_nomem(tmp_pass, req)) { 2287 2495 return tevent_req_post(req, ev); 2288 2496 } 2289 pass = tmp_pass; 2290 } 2291 } 2497 pass = (const char *)tmp_pass; 2498 passlen = talloc_get_size(tmp_pass); 2499 } 2500 } 2501 2502 tcon_flags |= TCONX_FLAG_EXTENDED_RESPONSE; 2503 tcon_flags |= TCONX_FLAG_EXTENDED_SIGNATURES; 2292 2504 2293 2505 SCVAL(vwv+0, 0, 0xFF); 2294 2506 SCVAL(vwv+0, 1, 0); 2295 2507 SSVAL(vwv+1, 0, 0); 2296 SSVAL(vwv+2, 0, TCONX_FLAG_EXTENDED_RESPONSE);2508 SSVAL(vwv+2, 0, tcon_flags); 2297 2509 SSVAL(vwv+3, 0, passlen); 2298 2510 … … 2307 2519 */ 2308 2520 tmp = talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s", 2309 cli->desthost, share);2521 smbXcli_conn_remote_name(cli->conn), share); 2310 2522 if (tmp == NULL) { 2311 2523 TALLOC_FREE(req); 2312 2524 return NULL; 2313 2525 } 2314 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1,2526 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), tmp, strlen(tmp)+1, 2315 2527 NULL); 2316 2528 TALLOC_FREE(tmp); … … 2351 2563 2352 2564 struct tevent_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx, 2353 struct event_context *ev,2565 struct tevent_context *ev, 2354 2566 struct cli_state *cli, 2355 2567 const char *share, const char *dev, … … 2367 2579 return req; 2368 2580 } 2369 status = cli_smb_req_send(subreq);2581 status = smb1cli_req_chain_submit(&subreq, 1); 2370 2582 if (!NT_STATUS_IS_OK(status)) { 2371 2583 tevent_req_nterror(req, status); … … 2383 2595 struct cli_state *cli = state->cli; 2384 2596 uint8_t *in; 2385 char *inbuf;2597 uint8_t *inhdr; 2386 2598 uint8_t wct; 2387 2599 uint16_t *vwv; … … 2389 2601 uint8_t *bytes; 2390 2602 NTSTATUS status; 2603 uint16_t optional_support = 0; 2391 2604 2392 2605 status = cli_smb_recv(subreq, state, &in, 0, &wct, &vwv, … … 2398 2611 } 2399 2612 2400 in buf = (char *)in;2613 inhdr = in + NBT_HDR_SIZE; 2401 2614 2402 2615 if (num_bytes) { 2403 2616 if (clistr_pull_talloc(cli, 2404 inbuf,2405 SVAL(in buf, smb_flg2),2617 (const char *)inhdr, 2618 SVAL(inhdr, HDR_FLG2), 2406 2619 &cli->dev, 2407 2620 bytes, … … 2419 2632 } 2420 2633 2421 if (( cli->protocol>= PROTOCOL_NT1) && (num_bytes == 3)) {2634 if ((smbXcli_conn_protocol(cli->conn) >= PROTOCOL_NT1) && (num_bytes == 3)) { 2422 2635 /* almost certainly win95 - enable bug fixes */ 2423 2636 cli->win95 = True; … … 2429 2642 */ 2430 2643 2431 cli->dfsroot = false; 2432 2433 if ((wct > 2) && (cli->protocol >= PROTOCOL_LANMAN2)) { 2434 cli->dfsroot = ((SVAL(vwv+2, 0) & SMB_SHARE_IN_DFS) != 0); 2435 } 2436 2437 cli->cnum = SVAL(inbuf,smb_tid); 2644 if ((wct > 2) && (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN2)) { 2645 optional_support = SVAL(vwv+2, 0); 2646 } 2647 2648 if (optional_support & SMB_EXTENDED_SIGNATURES) { 2649 smb1cli_session_protect_session_key(cli->smb1.session); 2650 } 2651 2652 smb1cli_tcon_set_values(state->cli->smb1.tcon, 2653 SVAL(inhdr, HDR_TID), 2654 optional_support, 2655 0, /* maximal_access */ 2656 0, /* guest_maximal_access */ 2657 NULL, /* service */ 2658 NULL); /* fs_type */ 2659 2438 2660 tevent_req_done(req); 2439 2661 } … … 2448 2670 { 2449 2671 TALLOC_CTX *frame = talloc_stackframe(); 2450 struct event_context *ev;2672 struct tevent_context *ev; 2451 2673 struct tevent_req *req; 2452 NTSTATUS status = NT_STATUS_ OK;2453 2454 if ( cli_has_async_calls(cli)) {2674 NTSTATUS status = NT_STATUS_NO_MEMORY; 2675 2676 if (smbXcli_conn_has_async_calls(cli->conn)) { 2455 2677 /* 2456 2678 * Can't use sync call while an async call is in flight … … 2460 2682 } 2461 2683 2462 ev = event_context_init(frame);2684 ev = samba_tevent_context_init(frame); 2463 2685 if (ev == NULL) { 2464 status = NT_STATUS_NO_MEMORY;2465 2686 goto fail; 2466 2687 } … … 2468 2689 req = cli_tcon_andx_send(frame, ev, cli, share, dev, pass, passlen); 2469 2690 if (req == NULL) { 2470 status = NT_STATUS_NO_MEMORY;2471 2691 goto fail; 2472 2692 } 2473 2693 2474 if (!tevent_req_poll(req, ev)) { 2475 status = map_nt_error_from_unix(errno); 2694 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 2476 2695 goto fail; 2477 2696 } … … 2483 2702 } 2484 2703 2704 struct cli_tree_connect_state { 2705 struct cli_state *cli; 2706 }; 2707 2708 static struct tevent_req *cli_raw_tcon_send( 2709 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli, 2710 const char *service, const char *pass, const char *dev); 2711 static NTSTATUS cli_raw_tcon_recv(struct tevent_req *req, 2712 uint16_t *max_xmit, uint16_t *tid); 2713 2714 static void cli_tree_connect_smb2_done(struct tevent_req *subreq); 2715 static void cli_tree_connect_andx_done(struct tevent_req *subreq); 2716 static void cli_tree_connect_raw_done(struct tevent_req *subreq); 2717 2718 static struct tevent_req *cli_tree_connect_send( 2719 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli, 2720 const char *share, const char *dev, const char *pass, int passlen) 2721 { 2722 struct tevent_req *req, *subreq; 2723 struct cli_tree_connect_state *state; 2724 2725 req = tevent_req_create(mem_ctx, &state, 2726 struct cli_tree_connect_state); 2727 if (req == NULL) { 2728 return NULL; 2729 } 2730 state->cli = cli; 2731 2732 cli->share = talloc_strdup(cli, share); 2733 if (tevent_req_nomem(cli->share, req)) { 2734 return tevent_req_post(req, ev); 2735 } 2736 2737 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) { 2738 char *unc; 2739 2740 cli->smb2.tcon = smbXcli_tcon_create(cli); 2741 if (tevent_req_nomem(cli->smb2.tcon, req)) { 2742 return tevent_req_post(req, ev); 2743 } 2744 2745 unc = talloc_asprintf(state, "\\\\%s\\%s", 2746 smbXcli_conn_remote_name(cli->conn), 2747 share); 2748 if (tevent_req_nomem(unc, req)) { 2749 return tevent_req_post(req, ev); 2750 } 2751 2752 subreq = smb2cli_tcon_send(state, ev, cli->conn, cli->timeout, 2753 cli->smb2.session, cli->smb2.tcon, 2754 0, /* flags */ 2755 unc); 2756 if (tevent_req_nomem(subreq, req)) { 2757 return tevent_req_post(req, ev); 2758 } 2759 tevent_req_set_callback(subreq, cli_tree_connect_smb2_done, 2760 req); 2761 return req; 2762 } 2763 2764 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN1) { 2765 subreq = cli_tcon_andx_send(state, ev, cli, share, dev, 2766 pass, passlen); 2767 if (tevent_req_nomem(subreq, req)) { 2768 return tevent_req_post(req, ev); 2769 } 2770 tevent_req_set_callback(subreq, cli_tree_connect_andx_done, 2771 req); 2772 return req; 2773 } 2774 2775 subreq = cli_raw_tcon_send(state, ev, cli, share, pass, dev); 2776 if (tevent_req_nomem(subreq, req)) { 2777 return tevent_req_post(req, ev); 2778 } 2779 tevent_req_set_callback(subreq, cli_tree_connect_raw_done, req); 2780 2781 return req; 2782 } 2783 2784 static void cli_tree_connect_smb2_done(struct tevent_req *subreq) 2785 { 2786 tevent_req_simple_finish_ntstatus( 2787 subreq, smb2cli_tcon_recv(subreq)); 2788 } 2789 2790 static void cli_tree_connect_andx_done(struct tevent_req *subreq) 2791 { 2792 tevent_req_simple_finish_ntstatus( 2793 subreq, cli_tcon_andx_recv(subreq)); 2794 } 2795 2796 static void cli_tree_connect_raw_done(struct tevent_req *subreq) 2797 { 2798 struct tevent_req *req = tevent_req_callback_data( 2799 subreq, struct tevent_req); 2800 struct cli_tree_connect_state *state = tevent_req_data( 2801 req, struct cli_tree_connect_state); 2802 NTSTATUS status; 2803 uint16_t max_xmit = 0; 2804 uint16_t tid = 0; 2805 2806 status = cli_raw_tcon_recv(subreq, &max_xmit, &tid); 2807 if (tevent_req_nterror(req, status)) { 2808 return; 2809 } 2810 2811 smb1cli_tcon_set_values(state->cli->smb1.tcon, 2812 tid, 2813 0, /* optional_support */ 2814 0, /* maximal_access */ 2815 0, /* guest_maximal_access */ 2816 NULL, /* service */ 2817 NULL); /* fs_type */ 2818 2819 tevent_req_done(req); 2820 } 2821 2822 static NTSTATUS cli_tree_connect_recv(struct tevent_req *req) 2823 { 2824 return tevent_req_simple_recv_ntstatus(req); 2825 } 2826 2827 NTSTATUS cli_tree_connect(struct cli_state *cli, const char *share, 2828 const char *dev, const char *pass, int passlen) 2829 { 2830 struct tevent_context *ev; 2831 struct tevent_req *req; 2832 NTSTATUS status = NT_STATUS_NO_MEMORY; 2833 2834 if (smbXcli_conn_has_async_calls(cli->conn)) { 2835 return NT_STATUS_INVALID_PARAMETER; 2836 } 2837 ev = samba_tevent_context_init(talloc_tos()); 2838 if (ev == NULL) { 2839 goto fail; 2840 } 2841 req = cli_tree_connect_send(ev, ev, cli, share, dev, pass, passlen); 2842 if (req == NULL) { 2843 goto fail; 2844 } 2845 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 2846 goto fail; 2847 } 2848 status = cli_tree_connect_recv(req); 2849 fail: 2850 TALLOC_FREE(ev); 2851 return status; 2852 } 2853 2485 2854 /**************************************************************************** 2486 2855 Send a tree disconnect. … … 2493 2862 static void cli_tdis_done(struct tevent_req *subreq); 2494 2863 2495 st ruct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx,2864 static struct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx, 2496 2865 struct tevent_context *ev, 2497 2866 struct cli_state *cli) … … 2528 2897 return; 2529 2898 } 2530 state->cli->cnum = -1;2899 cli_state_set_tid(state->cli, UINT16_MAX); 2531 2900 tevent_req_done(req); 2532 2901 } 2533 2902 2534 NTSTATUS cli_tdis_recv(struct tevent_req *req)2903 static NTSTATUS cli_tdis_recv(struct tevent_req *req) 2535 2904 { 2536 2905 return tevent_req_simple_recv_ntstatus(req); … … 2543 2912 NTSTATUS status = NT_STATUS_NO_MEMORY; 2544 2913 2545 if (cli_has_async_calls(cli)) { 2914 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) { 2915 return smb2cli_tdis(cli->conn, 2916 cli->timeout, 2917 cli->smb2.session, 2918 cli->smb2.tcon); 2919 } 2920 2921 if (smbXcli_conn_has_async_calls(cli->conn)) { 2546 2922 return NT_STATUS_INVALID_PARAMETER; 2547 2923 } 2548 ev = tevent_context_init(talloc_tos());2924 ev = samba_tevent_context_init(talloc_tos()); 2549 2925 if (ev == NULL) { 2550 2926 goto fail; … … 2563 2939 } 2564 2940 2565 /**************************************************************************** 2566 Send a negprot command. 2567 ****************************************************************************/ 2568 2569 struct cli_negprot_state { 2941 struct cli_connect_sock_state { 2942 const char **called_names; 2943 const char **calling_names; 2944 int *called_types; 2945 int fd; 2946 uint16_t port; 2947 }; 2948 2949 static void cli_connect_sock_done(struct tevent_req *subreq); 2950 2951 /* 2952 * Async only if we don't have to look up the name, i.e. "pss" is set with a 2953 * nonzero address. 2954 */ 2955 2956 static struct tevent_req *cli_connect_sock_send( 2957 TALLOC_CTX *mem_ctx, struct tevent_context *ev, 2958 const char *host, int name_type, const struct sockaddr_storage *pss, 2959 const char *myname, uint16_t port) 2960 { 2961 struct tevent_req *req, *subreq; 2962 struct cli_connect_sock_state *state; 2963 const char *prog; 2964 struct sockaddr_storage *addrs; 2965 unsigned i, num_addrs; 2966 NTSTATUS status; 2967 2968 req = tevent_req_create(mem_ctx, &state, 2969 struct cli_connect_sock_state); 2970 if (req == NULL) { 2971 return NULL; 2972 } 2973 2974 prog = getenv("LIBSMB_PROG"); 2975 if (prog != NULL) { 2976 state->fd = sock_exec(prog); 2977 if (state->fd == -1) { 2978 status = map_nt_error_from_unix(errno); 2979 tevent_req_nterror(req, status); 2980 } else { 2981 state->port = 0; 2982 tevent_req_done(req); 2983 } 2984 return tevent_req_post(req, ev); 2985 } 2986 2987 if ((pss == NULL) || is_zero_addr(pss)) { 2988 2989 /* 2990 * Here we cheat. resolve_name_list is not async at all. So 2991 * this call will only be really async if the name lookup has 2992 * been done externally. 2993 */ 2994 2995 status = resolve_name_list(state, host, name_type, 2996 &addrs, &num_addrs); 2997 if (!NT_STATUS_IS_OK(status)) { 2998 tevent_req_nterror(req, status); 2999 return tevent_req_post(req, ev); 3000 } 3001 } else { 3002 addrs = talloc_array(state, struct sockaddr_storage, 1); 3003 if (tevent_req_nomem(addrs, req)) { 3004 return tevent_req_post(req, ev); 3005 } 3006 addrs[0] = *pss; 3007 num_addrs = 1; 3008 } 3009 3010 state->called_names = talloc_array(state, const char *, num_addrs); 3011 if (tevent_req_nomem(state->called_names, req)) { 3012 return tevent_req_post(req, ev); 3013 } 3014 state->called_types = talloc_array(state, int, num_addrs); 3015 if (tevent_req_nomem(state->called_types, req)) { 3016 return tevent_req_post(req, ev); 3017 } 3018 state->calling_names = talloc_array(state, const char *, num_addrs); 3019 if (tevent_req_nomem(state->calling_names, req)) { 3020 return tevent_req_post(req, ev); 3021 } 3022 for (i=0; i<num_addrs; i++) { 3023 state->called_names[i] = host; 3024 state->called_types[i] = name_type; 3025 state->calling_names[i] = myname; 3026 } 3027 3028 subreq = smbsock_any_connect_send( 3029 state, ev, addrs, state->called_names, state->called_types, 3030 state->calling_names, NULL, num_addrs, port); 3031 if (tevent_req_nomem(subreq, req)) { 3032 return tevent_req_post(req, ev); 3033 } 3034 tevent_req_set_callback(subreq, cli_connect_sock_done, req); 3035 return req; 3036 } 3037 3038 static void cli_connect_sock_done(struct tevent_req *subreq) 3039 { 3040 struct tevent_req *req = tevent_req_callback_data( 3041 subreq, struct tevent_req); 3042 struct cli_connect_sock_state *state = tevent_req_data( 3043 req, struct cli_connect_sock_state); 3044 NTSTATUS status; 3045 3046 status = smbsock_any_connect_recv(subreq, &state->fd, NULL, 3047 &state->port); 3048 TALLOC_FREE(subreq); 3049 if (tevent_req_nterror(req, status)) { 3050 return; 3051 } 3052 set_socket_options(state->fd, lp_socket_options()); 3053 tevent_req_done(req); 3054 } 3055 3056 static NTSTATUS cli_connect_sock_recv(struct tevent_req *req, 3057 int *pfd, uint16_t *pport) 3058 { 3059 struct cli_connect_sock_state *state = tevent_req_data( 3060 req, struct cli_connect_sock_state); 3061 NTSTATUS status; 3062 3063 if (tevent_req_is_nterror(req, &status)) { 3064 return status; 3065 } 3066 *pfd = state->fd; 3067 *pport = state->port; 3068 return NT_STATUS_OK; 3069 } 3070 3071 struct cli_connect_nb_state { 3072 const char *desthost; 3073 int signing_state; 3074 int flags; 2570 3075 struct cli_state *cli; 2571 3076 }; 2572 3077 2573 static void cli_negprot_done(struct tevent_req *subreq); 2574 2575 struct tevent_req *cli_negprot_send(TALLOC_CTX *mem_ctx, 2576 struct event_context *ev, 2577 struct cli_state *cli) 3078 static void cli_connect_nb_done(struct tevent_req *subreq); 3079 3080 static struct tevent_req *cli_connect_nb_send( 3081 TALLOC_CTX *mem_ctx, struct tevent_context *ev, 3082 const char *host, const struct sockaddr_storage *dest_ss, 3083 uint16_t port, int name_type, const char *myname, 3084 int signing_state, int flags) 2578 3085 { 2579 3086 struct tevent_req *req, *subreq; 2580 struct cli_negprot_state *state; 2581 uint8_t *bytes = NULL; 2582 int numprots; 2583 uint16_t cnum; 2584 2585 req = tevent_req_create(mem_ctx, &state, struct cli_negprot_state); 3087 struct cli_connect_nb_state *state; 3088 3089 req = tevent_req_create(mem_ctx, &state, struct cli_connect_nb_state); 2586 3090 if (req == NULL) { 2587 3091 return NULL; 2588 3092 } 2589 state->cli = cli; 2590 2591 if (cli->protocol < PROTOCOL_NT1) 2592 cli->use_spnego = False; 2593 2594 /* setup the protocol strings */ 2595 for (numprots=0; numprots < ARRAY_SIZE(prots); numprots++) { 2596 uint8_t c = 2; 2597 if (prots[numprots].prot > cli->protocol) { 2598 break; 2599 } 2600 bytes = (uint8_t *)talloc_append_blob( 2601 state, bytes, data_blob_const(&c, sizeof(c))); 2602 if (tevent_req_nomem(bytes, req)) { 3093 state->signing_state = signing_state; 3094 state->flags = flags; 3095 3096 if (host != NULL) { 3097 char *p = strchr(host, '#'); 3098 3099 if (p != NULL) { 3100 name_type = strtol(p+1, NULL, 16); 3101 host = talloc_strndup(state, host, p - host); 3102 if (tevent_req_nomem(host, req)) { 3103 return tevent_req_post(req, ev); 3104 } 3105 } 3106 3107 state->desthost = host; 3108 } else { 3109 state->desthost = print_canonical_sockaddr(state, dest_ss); 3110 if (tevent_req_nomem(state->desthost, req)) { 2603 3111 return tevent_req_post(req, ev); 2604 3112 } 2605 bytes = smb_bytes_push_str(bytes, false, 2606 prots[numprots].name, 2607 strlen(prots[numprots].name)+1, 2608 NULL); 2609 if (tevent_req_nomem(bytes, req)) { 2610 return tevent_req_post(req, ev); 2611 } 2612 } 2613 2614 cnum = cli->cnum; 2615 2616 cli->cnum = 0; 2617 subreq = cli_smb_send(state, ev, cli, SMBnegprot, 0, 0, NULL, 2618 talloc_get_size(bytes), bytes); 2619 cli->cnum = cnum; 2620 3113 } 3114 3115 subreq = cli_connect_sock_send(state, ev, host, name_type, dest_ss, 3116 myname, port); 2621 3117 if (tevent_req_nomem(subreq, req)) { 2622 3118 return tevent_req_post(req, ev); 2623 3119 } 2624 tevent_req_set_callback(subreq, cli_ negprot_done, req);3120 tevent_req_set_callback(subreq, cli_connect_nb_done, req); 2625 3121 return req; 2626 3122 } 2627 3123 2628 static void cli_ negprot_done(struct tevent_req *subreq)3124 static void cli_connect_nb_done(struct tevent_req *subreq) 2629 3125 { 2630 3126 struct tevent_req *req = tevent_req_callback_data( 2631 3127 subreq, struct tevent_req); 2632 struct cli_negprot_state *state = tevent_req_data( 2633 req, struct cli_negprot_state); 2634 struct cli_state *cli = state->cli; 2635 uint8_t wct; 2636 uint16_t *vwv; 2637 uint32_t num_bytes; 2638 uint8_t *bytes; 2639 NTSTATUS status; 2640 uint16_t protnum; 2641 uint8_t *inbuf; 2642 2643 status = cli_smb_recv(subreq, state, &inbuf, 1, &wct, &vwv, 2644 &num_bytes, &bytes); 3128 struct cli_connect_nb_state *state = tevent_req_data( 3129 req, struct cli_connect_nb_state); 3130 NTSTATUS status; 3131 int fd = 0; 3132 uint16_t port; 3133 3134 status = cli_connect_sock_recv(subreq, &fd, &port); 2645 3135 TALLOC_FREE(subreq); 2646 if (!NT_STATUS_IS_OK(status)) { 2647 tevent_req_nterror(req, status); 2648 return; 2649 } 2650 2651 protnum = SVAL(vwv, 0); 2652 2653 if ((protnum >= ARRAY_SIZE(prots)) 2654 || (prots[protnum].prot > cli->protocol)) { 2655 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); 2656 return; 2657 } 2658 2659 cli->protocol = prots[protnum].prot; 2660 2661 if ((cli->protocol < PROTOCOL_NT1) && 2662 client_is_signing_mandatory(cli)) { 2663 DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n")); 2664 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); 2665 return; 2666 } 2667 2668 if (cli->protocol >= PROTOCOL_NT1) { 2669 struct timespec ts; 2670 bool negotiated_smb_signing = false; 2671 DATA_BLOB blob = data_blob_null; 2672 2673 if (wct != 0x11) { 2674 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); 2675 return; 2676 } 2677 2678 /* NT protocol */ 2679 cli->sec_mode = CVAL(vwv + 1, 0); 2680 cli->max_mux = SVAL(vwv + 1, 1); 2681 cli->max_xmit = IVAL(vwv + 3, 1); 2682 cli->sesskey = IVAL(vwv + 7, 1); 2683 cli->serverzone = SVALS(vwv + 15, 1); 2684 cli->serverzone *= 60; 2685 /* this time arrives in real GMT */ 2686 ts = interpret_long_date(((char *)(vwv+11))+1); 2687 cli->servertime = ts.tv_sec; 2688 cli->secblob = data_blob(bytes, num_bytes); 2689 cli->capabilities = IVAL(vwv + 9, 1); 2690 if (cli->capabilities & CAP_RAW_MODE) { 2691 cli->readbraw_supported = True; 2692 cli->writebraw_supported = True; 2693 } 2694 /* work out if they sent us a workgroup */ 2695 if (!(cli->capabilities & CAP_EXTENDED_SECURITY) && 2696 smb_buflen(inbuf) > 8) { 2697 blob = data_blob_const(bytes + 8, num_bytes - 8); 2698 } 2699 2700 if (blob.length > 0) { 2701 ssize_t ret; 2702 char *server_domain = NULL; 2703 2704 ret = clistr_pull_talloc(cli, 2705 (const char *)inbuf, 2706 SVAL(inbuf, smb_flg2), 2707 &server_domain, 2708 (char *)blob.data, 2709 blob.length, 2710 STR_TERMINATE| 2711 STR_UNICODE| 2712 STR_NOALIGN); 2713 if (ret == -1) { 2714 tevent_req_nterror(req, NT_STATUS_NO_MEMORY); 2715 return; 2716 } 2717 if (server_domain) { 2718 cli->server_domain = server_domain; 2719 } 2720 } 2721 2722 /* 2723 * As signing is slow we only turn it on if either the client or 2724 * the server require it. JRA. 2725 */ 2726 2727 if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) { 2728 /* Fail if server says signing is mandatory and we don't want to support it. */ 2729 if (!client_is_signing_allowed(cli)) { 2730 DEBUG(0,("cli_negprot: SMB signing is mandatory and we have disabled it.\n")); 2731 tevent_req_nterror(req, 2732 NT_STATUS_ACCESS_DENIED); 2733 return; 2734 } 2735 negotiated_smb_signing = true; 2736 } else if (client_is_signing_mandatory(cli) && client_is_signing_allowed(cli)) { 2737 /* Fail if client says signing is mandatory and the server doesn't support it. */ 2738 if (!(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) { 2739 DEBUG(1,("cli_negprot: SMB signing is mandatory and the server doesn't support it.\n")); 2740 tevent_req_nterror(req, 2741 NT_STATUS_ACCESS_DENIED); 2742 return; 2743 } 2744 negotiated_smb_signing = true; 2745 } else if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) { 2746 negotiated_smb_signing = true; 2747 } 2748 2749 if (negotiated_smb_signing) { 2750 cli_set_signing_negotiated(cli); 2751 } 2752 2753 if (cli->capabilities & (CAP_LARGE_READX|CAP_LARGE_WRITEX)) { 2754 SAFE_FREE(cli->outbuf); 2755 SAFE_FREE(cli->inbuf); 2756 cli->outbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN); 2757 cli->inbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN); 2758 if (!cli->outbuf || !cli->inbuf) { 2759 tevent_req_nterror(req, 2760 NT_STATUS_NO_MEMORY); 2761 return; 2762 } 2763 cli->bufsize = CLI_SAMBA_MAX_LARGE_READX_SIZE + LARGE_WRITEX_HDR_SIZE; 2764 } 2765 2766 } else if (cli->protocol >= PROTOCOL_LANMAN1) { 2767 if (wct != 0x0D) { 2768 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); 2769 return; 2770 } 2771 2772 cli->use_spnego = False; 2773 cli->sec_mode = SVAL(vwv + 1, 0); 2774 cli->max_xmit = SVAL(vwv + 2, 0); 2775 cli->max_mux = SVAL(vwv + 3, 0); 2776 cli->sesskey = IVAL(vwv + 6, 0); 2777 cli->serverzone = SVALS(vwv + 10, 0); 2778 cli->serverzone *= 60; 2779 /* this time is converted to GMT by make_unix_date */ 2780 cli->servertime = make_unix_date( 2781 (char *)(vwv + 8), cli->serverzone); 2782 cli->readbraw_supported = ((SVAL(vwv + 5, 0) & 0x1) != 0); 2783 cli->writebraw_supported = ((SVAL(vwv + 5, 0) & 0x2) != 0); 2784 cli->secblob = data_blob(bytes, num_bytes); 2785 } else { 2786 /* the old core protocol */ 2787 cli->use_spnego = False; 2788 cli->sec_mode = 0; 2789 cli->serverzone = get_time_zone(time(NULL)); 2790 } 2791 2792 cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE); 2793 2794 /* a way to force ascii SMB */ 2795 if (getenv("CLI_FORCE_ASCII")) 2796 cli->capabilities &= ~CAP_UNICODE; 2797 3136 if (tevent_req_nterror(req, status)) { 3137 return; 3138 } 3139 3140 state->cli = cli_state_create(state, fd, state->desthost, NULL, 3141 state->signing_state, state->flags); 3142 if (tevent_req_nomem(state->cli, req)) { 3143 close(fd); 3144 return; 3145 } 2798 3146 tevent_req_done(req); 2799 3147 } 2800 3148 2801 NTSTATUS cli_negprot_recv(struct tevent_req *req) 2802 { 2803 return tevent_req_simple_recv_ntstatus(req); 2804 } 2805 2806 NTSTATUS cli_negprot(struct cli_state *cli) 2807 { 2808 TALLOC_CTX *frame = talloc_stackframe(); 2809 struct event_context *ev; 3149 static NTSTATUS cli_connect_nb_recv(struct tevent_req *req, 3150 struct cli_state **pcli) 3151 { 3152 struct cli_connect_nb_state *state = tevent_req_data( 3153 req, struct cli_connect_nb_state); 3154 NTSTATUS status; 3155 3156 if (tevent_req_is_nterror(req, &status)) { 3157 return status; 3158 } 3159 *pcli = talloc_move(NULL, &state->cli); 3160 return NT_STATUS_OK; 3161 } 3162 3163 NTSTATUS cli_connect_nb(const char *host, const struct sockaddr_storage *dest_ss, 3164 uint16_t port, int name_type, const char *myname, 3165 int signing_state, int flags, struct cli_state **pcli) 3166 { 3167 struct tevent_context *ev; 2810 3168 struct tevent_req *req; 2811 NTSTATUS status = NT_STATUS_OK; 2812 2813 if (cli_has_async_calls(cli)) { 2814 /* 2815 * Can't use sync call while an async call is in flight 2816 */ 2817 status = NT_STATUS_INVALID_PARAMETER; 3169 NTSTATUS status = NT_STATUS_NO_MEMORY; 3170 3171 ev = samba_tevent_context_init(talloc_tos()); 3172 if (ev == NULL) { 2818 3173 goto fail; 2819 3174 } 2820 2821 ev = event_context_init(frame); 2822 if (ev == NULL) { 2823 status = NT_STATUS_NO_MEMORY; 3175 req = cli_connect_nb_send(ev, ev, host, dest_ss, port, name_type, 3176 myname, signing_state, flags); 3177 if (req == NULL) { 2824 3178 goto fail; 2825 3179 } 2826 2827 req = cli_negprot_send(frame, ev, cli); 2828 if (req == NULL) { 2829 status = NT_STATUS_NO_MEMORY; 3180 if (!tevent_req_set_endtime(req, ev, timeval_current_ofs(20, 0))) { 2830 3181 goto fail; 2831 3182 } 2832 2833 if (!tevent_req_poll(req, ev)) { 2834 status = map_nt_error_from_unix(errno); 3183 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 2835 3184 goto fail; 2836 3185 } 2837 2838 status = cli_negprot_recv(req); 2839 fail: 2840 TALLOC_FREE(frame); 2841 return status; 2842 } 2843 2844 /**************************************************************************** 2845 Send a session request. See rfc1002.txt 4.3 and 4.3.2. 2846 ****************************************************************************/ 2847 2848 bool cli_session_request(struct cli_state *cli, 2849 struct nmb_name *calling, struct nmb_name *called) 2850 { 2851 char *p; 2852 int len = 4; 2853 int namelen = 0; 2854 char *tmp; 2855 2856 /* 445 doesn't have session request */ 2857 if (cli->port == 445) 2858 return True; 2859 2860 memcpy(&(cli->calling), calling, sizeof(*calling)); 2861 memcpy(&(cli->called ), called , sizeof(*called )); 2862 2863 /* put in the destination name */ 2864 2865 tmp = name_mangle(talloc_tos(), cli->called.name, 2866 cli->called.name_type); 2867 if (tmp == NULL) { 2868 return false; 2869 } 2870 2871 p = cli->outbuf+len; 2872 namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp)); 2873 if (namelen > 0) { 2874 memcpy(p, tmp, namelen); 2875 len += namelen; 2876 } 2877 TALLOC_FREE(tmp); 2878 2879 /* and my name */ 2880 2881 tmp = name_mangle(talloc_tos(), cli->calling.name, 2882 cli->calling.name_type); 2883 if (tmp == NULL) { 2884 return false; 2885 } 2886 2887 p = cli->outbuf+len; 2888 namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp)); 2889 if (namelen > 0) { 2890 memcpy(p, tmp, namelen); 2891 len += namelen; 2892 } 2893 TALLOC_FREE(tmp); 2894 2895 /* send a session request (RFC 1002) */ 2896 /* setup the packet length 2897 * Remove four bytes from the length count, since the length 2898 * field in the NBT Session Service header counts the number 2899 * of bytes which follow. The cli_send_smb() function knows 2900 * about this and accounts for those four bytes. 2901 * CRH. 2902 */ 2903 len -= 4; 2904 _smb_setlen(cli->outbuf,len); 2905 SCVAL(cli->outbuf,0,0x81); 2906 2907 cli_send_smb(cli); 2908 DEBUG(5,("Sent session request\n")); 2909 2910 if (!cli_receive_smb(cli)) 2911 return False; 2912 2913 if (CVAL(cli->inbuf,0) == 0x84) { 2914 /* C. Hoch 9/14/95 Start */ 2915 /* For information, here is the response structure. 2916 * We do the byte-twiddling to for portability. 2917 struct RetargetResponse{ 2918 unsigned char type; 2919 unsigned char flags; 2920 int16 length; 2921 int32 ip_addr; 2922 int16 port; 2923 }; 2924 */ 2925 uint16_t port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9); 2926 struct in_addr dest_ip; 2927 NTSTATUS status; 2928 2929 /* SESSION RETARGET */ 2930 putip((char *)&dest_ip,cli->inbuf+4); 2931 in_addr_to_sockaddr_storage(&cli->dest_ss, dest_ip); 2932 2933 status = open_socket_out(&cli->dest_ss, port, 2934 LONG_CONNECT_TIMEOUT, &cli->fd); 2935 if (!NT_STATUS_IS_OK(status)) { 2936 return False; 2937 } 2938 2939 DEBUG(3,("Retargeted\n")); 2940 2941 set_socket_options(cli->fd, lp_socket_options()); 2942 2943 /* Try again */ 2944 { 2945 static int depth; 2946 bool ret; 2947 if (depth > 4) { 2948 DEBUG(0,("Retarget recursion - failing\n")); 2949 return False; 2950 } 2951 depth++; 2952 ret = cli_session_request(cli, calling, called); 2953 depth--; 2954 return ret; 2955 } 2956 } /* C. Hoch 9/14/95 End */ 2957 2958 if (CVAL(cli->inbuf,0) != 0x82) { 2959 /* This is the wrong place to put the error... JRA. */ 2960 cli->rap_error = CVAL(cli->inbuf,4); 2961 return False; 2962 } 2963 return(True); 2964 } 2965 2966 struct fd_struct { 2967 int fd; 2968 }; 2969 2970 static void smb_sock_connected(struct tevent_req *req) 2971 { 2972 struct fd_struct *pfd = tevent_req_callback_data( 2973 req, struct fd_struct); 2974 int fd; 2975 NTSTATUS status; 2976 2977 status = open_socket_out_defer_recv(req, &fd); 2978 if (NT_STATUS_IS_OK(status)) { 2979 pfd->fd = fd; 2980 } 2981 } 2982 2983 static NTSTATUS open_smb_socket(const struct sockaddr_storage *pss, 2984 uint16_t *port, int timeout, int *pfd) 2985 { 2986 struct event_context *ev; 2987 struct tevent_req *r139, *r445; 2988 struct fd_struct *fd139, *fd445; 2989 NTSTATUS status = NT_STATUS_NO_MEMORY; 2990 2991 if (*port != 0) { 2992 return open_socket_out(pss, *port, timeout, pfd); 2993 } 2994 2995 ev = event_context_init(talloc_tos()); 2996 if (ev == NULL) { 2997 return NT_STATUS_NO_MEMORY; 2998 } 2999 3000 fd139 = talloc(ev, struct fd_struct); 3001 if (fd139 == NULL) { 3002 goto done; 3003 } 3004 fd139->fd = -1; 3005 3006 fd445 = talloc(ev, struct fd_struct); 3007 if (fd445 == NULL) { 3008 goto done; 3009 } 3010 fd445->fd = -1; 3011 3012 r445 = open_socket_out_defer_send(ev, ev, timeval_set(0, 0), 3013 pss, 445, timeout); 3014 r139 = open_socket_out_defer_send(ev, ev, timeval_set(0, 3000), 3015 pss, 139, timeout); 3016 if ((r445 == NULL) || (r139 == NULL)) { 3017 goto done; 3018 } 3019 tevent_req_set_callback(r445, smb_sock_connected, fd445); 3020 tevent_req_set_callback(r139, smb_sock_connected, fd139); 3021 3022 while ((fd445->fd == -1) && (fd139->fd == -1) 3023 && (tevent_req_is_in_progress(r139) 3024 || tevent_req_is_in_progress(r445))) { 3025 event_loop_once(ev); 3026 } 3027 3028 if ((fd139->fd != -1) && (fd445->fd != -1)) { 3029 close(fd139->fd); 3030 fd139->fd = -1; 3031 } 3032 3033 if (fd445->fd != -1) { 3034 *port = 445; 3035 *pfd = fd445->fd; 3036 status = NT_STATUS_OK; 3037 goto done; 3038 } 3039 if (fd139->fd != -1) { 3040 *port = 139; 3041 *pfd = fd139->fd; 3042 status = NT_STATUS_OK; 3043 goto done; 3044 } 3045 3046 status = open_socket_out_defer_recv(r445, &fd445->fd); 3047 done: 3186 status = cli_connect_nb_recv(req, pcli); 3187 fail: 3048 3188 TALLOC_FREE(ev); 3049 3189 return status; 3050 3190 } 3051 3191 3052 /**************************************************************************** 3053 Open the client sockets. 3054 ****************************************************************************/ 3055 3056 NTSTATUS cli_connect(struct cli_state *cli, 3057 const char *host, 3058 struct sockaddr_storage *dest_ss) 3059 3060 { 3061 int name_type = 0x20; 3062 TALLOC_CTX *frame = talloc_stackframe(); 3063 unsigned int num_addrs = 0; 3064 unsigned int i = 0; 3065 struct sockaddr_storage *ss_arr = NULL; 3066 char *p = NULL; 3067 3068 /* reasonable default hostname */ 3069 if (!host) { 3070 host = STAR_SMBSERVER; 3071 } 3072 3073 cli->desthost = talloc_strdup(cli, host); 3074 if (cli->desthost == NULL) { 3075 return NT_STATUS_NO_MEMORY; 3076 } 3077 3078 /* allow hostnames of the form NAME#xx and do a netbios lookup */ 3079 if ((p = strchr(cli->desthost, '#'))) { 3080 name_type = strtol(p+1, NULL, 16); 3081 *p = 0; 3082 } 3083 3084 if (!dest_ss || is_zero_addr(dest_ss)) { 3085 NTSTATUS status =resolve_name_list(frame, 3086 cli->desthost, 3087 name_type, 3088 &ss_arr, 3089 &num_addrs); 3090 if (!NT_STATUS_IS_OK(status)) { 3091 TALLOC_FREE(frame); 3092 return NT_STATUS_BAD_NETWORK_NAME; 3093 } 3094 } else { 3095 num_addrs = 1; 3096 ss_arr = TALLOC_P(frame, struct sockaddr_storage); 3097 if (!ss_arr) { 3098 TALLOC_FREE(frame); 3099 return NT_STATUS_NO_MEMORY; 3100 } 3101 *ss_arr = *dest_ss; 3102 } 3103 3104 for (i = 0; i < num_addrs; i++) { 3105 cli->dest_ss = ss_arr[i]; 3106 if (getenv("LIBSMB_PROG")) { 3107 cli->fd = sock_exec(getenv("LIBSMB_PROG")); 3108 } else { 3109 uint16_t port = cli->port; 3110 NTSTATUS status; 3111 status = open_smb_socket(&cli->dest_ss, &port, 3112 cli->timeout, &cli->fd); 3113 if (NT_STATUS_IS_OK(status)) { 3114 cli->port = port; 3115 } 3116 } 3117 if (cli->fd == -1) { 3118 char addr[INET6_ADDRSTRLEN]; 3119 print_sockaddr(addr, sizeof(addr), &ss_arr[i]); 3120 DEBUG(2,("Error connecting to %s (%s)\n", 3121 dest_ss?addr:host,strerror(errno))); 3122 } else { 3123 /* Exit from loop on first connection. */ 3124 break; 3125 } 3126 } 3127 3128 if (cli->fd == -1) { 3129 TALLOC_FREE(frame); 3130 return map_nt_error_from_unix(errno); 3131 } 3132 3133 if (dest_ss) { 3134 *dest_ss = cli->dest_ss; 3135 } 3136 3137 set_socket_options(cli->fd, lp_socket_options()); 3138 3139 TALLOC_FREE(frame); 3140 return NT_STATUS_OK; 3141 } 3192 struct cli_start_connection_state { 3193 struct tevent_context *ev; 3194 struct cli_state *cli; 3195 int min_protocol; 3196 int max_protocol; 3197 }; 3198 3199 static void cli_start_connection_connected(struct tevent_req *subreq); 3200 static void cli_start_connection_done(struct tevent_req *subreq); 3142 3201 3143 3202 /** … … 3148 3207 @param port (optional) The destination port (0 for default) 3149 3208 */ 3209 3210 static struct tevent_req *cli_start_connection_send( 3211 TALLOC_CTX *mem_ctx, struct tevent_context *ev, 3212 const char *my_name, const char *dest_host, 3213 const struct sockaddr_storage *dest_ss, int port, 3214 int signing_state, int flags) 3215 { 3216 struct tevent_req *req, *subreq; 3217 struct cli_start_connection_state *state; 3218 3219 req = tevent_req_create(mem_ctx, &state, 3220 struct cli_start_connection_state); 3221 if (req == NULL) { 3222 return NULL; 3223 } 3224 state->ev = ev; 3225 3226 if (signing_state == SMB_SIGNING_IPC_DEFAULT) { 3227 state->min_protocol = lp_client_ipc_min_protocol(); 3228 state->max_protocol = lp_client_ipc_max_protocol(); 3229 } else { 3230 state->min_protocol = lp_client_min_protocol(); 3231 state->max_protocol = lp_client_max_protocol(); 3232 } 3233 3234 subreq = cli_connect_nb_send(state, ev, dest_host, dest_ss, port, 3235 0x20, my_name, signing_state, flags); 3236 if (tevent_req_nomem(subreq, req)) { 3237 return tevent_req_post(req, ev); 3238 } 3239 tevent_req_set_callback(subreq, cli_start_connection_connected, req); 3240 return req; 3241 } 3242 3243 static void cli_start_connection_connected(struct tevent_req *subreq) 3244 { 3245 struct tevent_req *req = tevent_req_callback_data( 3246 subreq, struct tevent_req); 3247 struct cli_start_connection_state *state = tevent_req_data( 3248 req, struct cli_start_connection_state); 3249 NTSTATUS status; 3250 3251 status = cli_connect_nb_recv(subreq, &state->cli); 3252 TALLOC_FREE(subreq); 3253 if (tevent_req_nterror(req, status)) { 3254 return; 3255 } 3256 3257 subreq = smbXcli_negprot_send(state, state->ev, state->cli->conn, 3258 state->cli->timeout, 3259 state->min_protocol, 3260 state->max_protocol); 3261 if (tevent_req_nomem(subreq, req)) { 3262 return; 3263 } 3264 tevent_req_set_callback(subreq, cli_start_connection_done, req); 3265 } 3266 3267 static void cli_start_connection_done(struct tevent_req *subreq) 3268 { 3269 struct tevent_req *req = tevent_req_callback_data( 3270 subreq, struct tevent_req); 3271 struct cli_start_connection_state *state = tevent_req_data( 3272 req, struct cli_start_connection_state); 3273 NTSTATUS status; 3274 3275 status = smbXcli_negprot_recv(subreq); 3276 TALLOC_FREE(subreq); 3277 if (tevent_req_nterror(req, status)) { 3278 return; 3279 } 3280 3281 if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) { 3282 /* Ensure we ask for some initial credits. */ 3283 smb2cli_conn_set_max_credits(state->cli->conn, 3284 DEFAULT_SMB2_MAX_CREDITS); 3285 } 3286 3287 tevent_req_done(req); 3288 } 3289 3290 static NTSTATUS cli_start_connection_recv(struct tevent_req *req, 3291 struct cli_state **output_cli) 3292 { 3293 struct cli_start_connection_state *state = tevent_req_data( 3294 req, struct cli_start_connection_state); 3295 NTSTATUS status; 3296 3297 if (tevent_req_is_nterror(req, &status)) { 3298 return status; 3299 } 3300 *output_cli = state->cli; 3301 3302 return NT_STATUS_OK; 3303 } 3304 3150 3305 NTSTATUS cli_start_connection(struct cli_state **output_cli, 3151 3306 const char *my_name, 3152 3307 const char *dest_host, 3153 struct sockaddr_storage *dest_ss, int port,3308 const struct sockaddr_storage *dest_ss, int port, 3154 3309 int signing_state, int flags) 3155 3310 { 3156 NTSTATUS nt_status; 3157 struct nmb_name calling; 3158 struct nmb_name called; 3159 struct cli_state *cli; 3160 struct sockaddr_storage ss; 3161 3162 if (!my_name) 3163 my_name = global_myname(); 3164 3165 if (!(cli = cli_initialise_ex(signing_state))) { 3166 return NT_STATUS_NO_MEMORY; 3167 } 3168 3169 make_nmb_name(&calling, my_name, 0x0); 3170 make_nmb_name(&called , dest_host, 0x20); 3171 3172 cli_set_port(cli, port); 3173 cli_set_timeout(cli, 10000); /* 10 seconds. */ 3174 3175 if (dest_ss) { 3176 ss = *dest_ss; 3177 } else { 3178 zero_sockaddr(&ss); 3179 } 3180 3181 again: 3182 3183 DEBUG(3,("Connecting to host=%s\n", dest_host)); 3184 3185 nt_status = cli_connect(cli, dest_host, &ss); 3186 if (!NT_STATUS_IS_OK(nt_status)) { 3187 char addr[INET6_ADDRSTRLEN]; 3188 print_sockaddr(addr, sizeof(addr), &ss); 3189 DEBUG(1,("cli_start_connection: failed to connect to %s (%s). Error %s\n", 3190 nmb_namestr(&called), addr, nt_errstr(nt_status) )); 3191 cli_shutdown(cli); 3192 return nt_status; 3193 } 3194 3195 if (!cli_session_request(cli, &calling, &called)) { 3196 char *p; 3197 DEBUG(1,("session request to %s failed (%s)\n", 3198 called.name, cli_errstr(cli))); 3199 if ((p=strchr(called.name, '.')) && !is_ipaddress(called.name)) { 3200 *p = 0; 3201 goto again; 3202 } 3203 if (strcmp(called.name, STAR_SMBSERVER)) { 3204 make_nmb_name(&called , STAR_SMBSERVER, 0x20); 3205 goto again; 3206 } 3207 return NT_STATUS_BAD_NETWORK_NAME; 3208 } 3209 3210 if (flags & CLI_FULL_CONNECTION_DONT_SPNEGO) 3211 cli->use_spnego = False; 3212 else if (flags & CLI_FULL_CONNECTION_USE_KERBEROS) 3213 cli->use_kerberos = True; 3214 3215 if ((flags & CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS) && 3216 cli->use_kerberos) { 3217 cli->fallback_after_kerberos = true; 3218 } 3219 if (flags & CLI_FULL_CONNECTION_USE_CCACHE) { 3220 cli->use_ccache = true; 3221 } 3222 3223 nt_status = cli_negprot(cli); 3224 if (!NT_STATUS_IS_OK(nt_status)) { 3225 DEBUG(1, ("failed negprot: %s\n", nt_errstr(nt_status))); 3226 cli_shutdown(cli); 3227 return nt_status; 3228 } 3229 3230 *output_cli = cli; 3231 return NT_STATUS_OK; 3232 } 3233 3311 struct tevent_context *ev; 3312 struct tevent_req *req; 3313 NTSTATUS status = NT_STATUS_NO_MEMORY; 3314 3315 ev = samba_tevent_context_init(talloc_tos()); 3316 if (ev == NULL) { 3317 goto fail; 3318 } 3319 req = cli_start_connection_send(ev, ev, my_name, dest_host, dest_ss, 3320 port, signing_state, flags); 3321 if (req == NULL) { 3322 goto fail; 3323 } 3324 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 3325 goto fail; 3326 } 3327 status = cli_start_connection_recv(req, output_cli); 3328 fail: 3329 TALLOC_FREE(ev); 3330 return status; 3331 } 3234 3332 3235 3333 /** … … 3246 3344 */ 3247 3345 3248 NTSTATUS cli_full_connection(struct cli_state **output_cli, 3249 const char *my_name, 3250 const char *dest_host, 3251 struct sockaddr_storage *dest_ss, int port, 3346 struct cli_full_connection_state { 3347 struct tevent_context *ev; 3348 const char *service; 3349 const char *service_type; 3350 const char *user; 3351 const char *domain; 3352 const char *password; 3353 int pw_len; 3354 int flags; 3355 struct cli_state *cli; 3356 }; 3357 3358 static int cli_full_connection_state_destructor( 3359 struct cli_full_connection_state *s); 3360 static void cli_full_connection_started(struct tevent_req *subreq); 3361 static void cli_full_connection_sess_set_up(struct tevent_req *subreq); 3362 static void cli_full_connection_done(struct tevent_req *subreq); 3363 3364 struct tevent_req *cli_full_connection_send( 3365 TALLOC_CTX *mem_ctx, struct tevent_context *ev, 3366 const char *my_name, const char *dest_host, 3367 const struct sockaddr_storage *dest_ss, int port, 3368 const char *service, const char *service_type, 3369 const char *user, const char *domain, 3370 const char *password, int flags, int signing_state) 3371 { 3372 struct tevent_req *req, *subreq; 3373 struct cli_full_connection_state *state; 3374 3375 req = tevent_req_create(mem_ctx, &state, 3376 struct cli_full_connection_state); 3377 if (req == NULL) { 3378 return NULL; 3379 } 3380 talloc_set_destructor(state, cli_full_connection_state_destructor); 3381 3382 state->ev = ev; 3383 state->service = service; 3384 state->service_type = service_type; 3385 state->user = user; 3386 state->domain = domain; 3387 state->password = password; 3388 state->flags = flags; 3389 3390 state->pw_len = state->password ? strlen(state->password)+1 : 0; 3391 if (state->password == NULL) { 3392 state->password = ""; 3393 } 3394 3395 subreq = cli_start_connection_send( 3396 state, ev, my_name, dest_host, dest_ss, port, 3397 signing_state, flags); 3398 if (tevent_req_nomem(subreq, req)) { 3399 return tevent_req_post(req, ev); 3400 } 3401 tevent_req_set_callback(subreq, cli_full_connection_started, req); 3402 return req; 3403 } 3404 3405 static int cli_full_connection_state_destructor( 3406 struct cli_full_connection_state *s) 3407 { 3408 if (s->cli != NULL) { 3409 cli_shutdown(s->cli); 3410 s->cli = NULL; 3411 } 3412 return 0; 3413 } 3414 3415 static void cli_full_connection_started(struct tevent_req *subreq) 3416 { 3417 struct tevent_req *req = tevent_req_callback_data( 3418 subreq, struct tevent_req); 3419 struct cli_full_connection_state *state = tevent_req_data( 3420 req, struct cli_full_connection_state); 3421 NTSTATUS status; 3422 3423 status = cli_start_connection_recv(subreq, &state->cli); 3424 TALLOC_FREE(subreq); 3425 if (tevent_req_nterror(req, status)) { 3426 return; 3427 } 3428 subreq = cli_session_setup_send( 3429 state, state->ev, state->cli, state->user, 3430 state->password, state->pw_len, state->password, state->pw_len, 3431 state->domain); 3432 if (tevent_req_nomem(subreq, req)) { 3433 return; 3434 } 3435 tevent_req_set_callback(subreq, cli_full_connection_sess_set_up, req); 3436 } 3437 3438 static void cli_full_connection_sess_set_up(struct tevent_req *subreq) 3439 { 3440 struct tevent_req *req = tevent_req_callback_data( 3441 subreq, struct tevent_req); 3442 struct cli_full_connection_state *state = tevent_req_data( 3443 req, struct cli_full_connection_state); 3444 NTSTATUS status; 3445 3446 status = cli_session_setup_recv(subreq); 3447 TALLOC_FREE(subreq); 3448 3449 if (!NT_STATUS_IS_OK(status) && 3450 (state->flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) { 3451 3452 state->flags &= ~CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK; 3453 3454 subreq = cli_session_setup_send( 3455 state, state->ev, state->cli, "", "", 0, "", 0, 3456 state->domain); 3457 if (tevent_req_nomem(subreq, req)) { 3458 return; 3459 } 3460 tevent_req_set_callback( 3461 subreq, cli_full_connection_sess_set_up, req); 3462 return; 3463 } 3464 3465 if (tevent_req_nterror(req, status)) { 3466 return; 3467 } 3468 3469 if (state->service != NULL) { 3470 subreq = cli_tree_connect_send( 3471 state, state->ev, state->cli, 3472 state->service, state->service_type, 3473 state->password, state->pw_len); 3474 if (tevent_req_nomem(subreq, req)) { 3475 return; 3476 } 3477 tevent_req_set_callback(subreq, cli_full_connection_done, req); 3478 return; 3479 } 3480 3481 tevent_req_done(req); 3482 } 3483 3484 static void cli_full_connection_done(struct tevent_req *subreq) 3485 { 3486 struct tevent_req *req = tevent_req_callback_data( 3487 subreq, struct tevent_req); 3488 NTSTATUS status; 3489 3490 status = cli_tree_connect_recv(subreq); 3491 TALLOC_FREE(subreq); 3492 if (tevent_req_nterror(req, status)) { 3493 return; 3494 } 3495 3496 tevent_req_done(req); 3497 } 3498 3499 NTSTATUS cli_full_connection_recv(struct tevent_req *req, 3500 struct cli_state **output_cli) 3501 { 3502 struct cli_full_connection_state *state = tevent_req_data( 3503 req, struct cli_full_connection_state); 3504 NTSTATUS status; 3505 3506 if (tevent_req_is_nterror(req, &status)) { 3507 return status; 3508 } 3509 *output_cli = state->cli; 3510 talloc_set_destructor(state, NULL); 3511 return NT_STATUS_OK; 3512 } 3513 3514 NTSTATUS cli_full_connection(struct cli_state **output_cli, 3515 const char *my_name, 3516 const char *dest_host, 3517 const struct sockaddr_storage *dest_ss, int port, 3252 3518 const char *service, const char *service_type, 3253 const char *user, const char *domain, 3519 const char *user, const char *domain, 3254 3520 const char *password, int flags, 3255 3521 int signing_state) 3256 3522 { 3257 NTSTATUS nt_status; 3258 struct cli_state *cli = NULL; 3259 int pw_len = password ? strlen(password)+1 : 0; 3260 3261 *output_cli = NULL; 3262 3263 if (password == NULL) { 3264 password = ""; 3265 } 3266 3267 nt_status = cli_start_connection(&cli, my_name, dest_host, 3268 dest_ss, port, signing_state, 3269 flags); 3270 3271 if (!NT_STATUS_IS_OK(nt_status)) { 3272 return nt_status; 3273 } 3274 3275 cli->use_oplocks = ((flags & CLI_FULL_CONNECTION_OPLOCKS) != 0); 3276 cli->use_level_II_oplocks = 3277 ((flags & CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS) != 0); 3278 3279 nt_status = cli_session_setup(cli, user, password, pw_len, password, 3280 pw_len, domain); 3281 if (!NT_STATUS_IS_OK(nt_status)) { 3282 3283 if (!(flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) { 3284 DEBUG(1,("failed session setup with %s\n", 3285 nt_errstr(nt_status))); 3286 cli_shutdown(cli); 3287 return nt_status; 3288 } 3289 3290 nt_status = cli_session_setup(cli, "", "", 0, "", 0, domain); 3291 if (!NT_STATUS_IS_OK(nt_status)) { 3292 DEBUG(1,("anonymous failed session setup with %s\n", 3293 nt_errstr(nt_status))); 3294 cli_shutdown(cli); 3295 return nt_status; 3296 } 3297 } 3298 3299 if (service) { 3300 nt_status = cli_tcon_andx(cli, service, service_type, password, 3301 pw_len); 3302 if (!NT_STATUS_IS_OK(nt_status)) { 3303 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status))); 3304 cli_shutdown(cli); 3305 if (NT_STATUS_IS_OK(nt_status)) { 3306 nt_status = NT_STATUS_UNSUCCESSFUL; 3307 } 3308 return nt_status; 3309 } 3310 } 3311 3312 nt_status = cli_init_creds(cli, user, domain, password); 3313 if (!NT_STATUS_IS_OK(nt_status)) { 3314 cli_shutdown(cli); 3315 return nt_status; 3316 } 3317 3318 *output_cli = cli; 3319 return NT_STATUS_OK; 3320 } 3321 3322 /**************************************************************************** 3323 Attempt a NetBIOS session request, falling back to *SMBSERVER if needed. 3324 ****************************************************************************/ 3325 3326 bool attempt_netbios_session_request(struct cli_state **ppcli, const char *srchost, const char *desthost, 3327 struct sockaddr_storage *pdest_ss) 3328 { 3329 struct nmb_name calling, called; 3330 3331 make_nmb_name(&calling, srchost, 0x0); 3332 3333 /* 3334 * If the called name is an IP address 3335 * then use *SMBSERVER immediately. 3336 */ 3337 3338 if(is_ipaddress(desthost)) { 3339 make_nmb_name(&called, STAR_SMBSERVER, 0x20); 3340 } else { 3341 make_nmb_name(&called, desthost, 0x20); 3342 } 3343 3344 if (!cli_session_request(*ppcli, &calling, &called)) { 3345 NTSTATUS status; 3346 struct nmb_name smbservername; 3347 3348 make_nmb_name(&smbservername, STAR_SMBSERVER, 0x20); 3349 3350 /* 3351 * If the name wasn't *SMBSERVER then 3352 * try with *SMBSERVER if the first name fails. 3353 */ 3354 3355 if (nmb_name_equal(&called, &smbservername)) { 3356 3357 /* 3358 * The name used was *SMBSERVER, don't bother with another name. 3359 */ 3360 3361 DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \ 3362 with error %s.\n", desthost, cli_errstr(*ppcli) )); 3363 return False; 3364 } 3365 3366 /* Try again... */ 3367 cli_shutdown(*ppcli); 3368 3369 *ppcli = cli_initialise(); 3370 if (!*ppcli) { 3371 /* Out of memory... */ 3372 return False; 3373 } 3374 3375 status = cli_connect(*ppcli, desthost, pdest_ss); 3376 if (!NT_STATUS_IS_OK(status) || 3377 !cli_session_request(*ppcli, &calling, &smbservername)) { 3378 DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \ 3379 name *SMBSERVER with error %s\n", desthost, cli_errstr(*ppcli) )); 3380 return False; 3381 } 3382 } 3383 3384 return True; 3523 struct tevent_context *ev; 3524 struct tevent_req *req; 3525 NTSTATUS status = NT_STATUS_NO_MEMORY; 3526 3527 ev = samba_tevent_context_init(talloc_tos()); 3528 if (ev == NULL) { 3529 goto fail; 3530 } 3531 req = cli_full_connection_send( 3532 ev, ev, my_name, dest_host, dest_ss, port, service, 3533 service_type, user, domain, password, flags, signing_state); 3534 if (req == NULL) { 3535 goto fail; 3536 } 3537 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 3538 goto fail; 3539 } 3540 status = cli_full_connection_recv(req, output_cli); 3541 fail: 3542 TALLOC_FREE(ev); 3543 return status; 3385 3544 } 3386 3545 … … 3388 3547 Send an old style tcon. 3389 3548 ****************************************************************************/ 3390 NTSTATUS cli_raw_tcon(struct cli_state *cli, 3391 const char *service, const char *pass, const char *dev, 3392 uint16 *max_xmit, uint16 *tid) 3393 { 3394 struct tevent_req *req; 3549 struct cli_raw_tcon_state { 3395 3550 uint16_t *ret_vwv; 3551 }; 3552 3553 static void cli_raw_tcon_done(struct tevent_req *subreq); 3554 3555 static struct tevent_req *cli_raw_tcon_send( 3556 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli, 3557 const char *service, const char *pass, const char *dev) 3558 { 3559 struct tevent_req *req, *subreq; 3560 struct cli_raw_tcon_state *state; 3396 3561 uint8_t *bytes; 3397 NTSTATUS status; 3562 3563 req = tevent_req_create(mem_ctx, &state, struct cli_raw_tcon_state); 3564 if (req == NULL) { 3565 return NULL; 3566 } 3398 3567 3399 3568 if (!lp_client_plaintext_auth() && (*pass)) { 3400 DEBUG(1, ("Server requested plaintext password but 'client " 3401 "plaintext auth' is disabled\n")); 3402 return NT_STATUS_ACCESS_DENIED; 3403 } 3404 3405 bytes = talloc_array(talloc_tos(), uint8_t, 0); 3569 DEBUG(1, ("Server requested PLAINTEXT password but 'client plaintext auth = no'" 3570 " or 'client ntlmv2 auth = yes'\n")); 3571 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); 3572 return tevent_req_post(req, ev); 3573 } 3574 3575 bytes = talloc_array(state, uint8_t, 0); 3406 3576 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0); 3407 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),3577 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), 3408 3578 service, strlen(service)+1, NULL); 3409 3579 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0); 3410 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),3580 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), 3411 3581 pass, strlen(pass)+1, NULL); 3412 3582 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0); 3413 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli),3583 bytes = smb_bytes_push_str(bytes, smbXcli_conn_use_unicode(cli->conn), 3414 3584 dev, strlen(dev)+1, NULL); 3415 3585 3416 status = cli_smb(talloc_tos(), cli, SMBtcon, 0, 0, NULL, 3417 talloc_get_size(bytes), bytes, &req, 3418 2, NULL, &ret_vwv, NULL, NULL); 3419 if (!NT_STATUS_IS_OK(status)) { 3586 if (tevent_req_nomem(bytes, req)) { 3587 return tevent_req_post(req, ev); 3588 } 3589 3590 subreq = cli_smb_send(state, ev, cli, SMBtcon, 0, 0, NULL, 3591 talloc_get_size(bytes), bytes); 3592 if (tevent_req_nomem(subreq, req)) { 3593 return tevent_req_post(req, ev); 3594 } 3595 tevent_req_set_callback(subreq, cli_raw_tcon_done, req); 3596 return req; 3597 } 3598 3599 static void cli_raw_tcon_done(struct tevent_req *subreq) 3600 { 3601 struct tevent_req *req = tevent_req_callback_data( 3602 subreq, struct tevent_req); 3603 struct cli_raw_tcon_state *state = tevent_req_data( 3604 req, struct cli_raw_tcon_state); 3605 NTSTATUS status; 3606 3607 status = cli_smb_recv(subreq, state, NULL, 2, NULL, &state->ret_vwv, 3608 NULL, NULL); 3609 TALLOC_FREE(subreq); 3610 if (tevent_req_nterror(req, status)) { 3611 return; 3612 } 3613 tevent_req_done(req); 3614 } 3615 3616 static NTSTATUS cli_raw_tcon_recv(struct tevent_req *req, 3617 uint16_t *max_xmit, uint16_t *tid) 3618 { 3619 struct cli_raw_tcon_state *state = tevent_req_data( 3620 req, struct cli_raw_tcon_state); 3621 NTSTATUS status; 3622 3623 if (tevent_req_is_nterror(req, &status)) { 3420 3624 return status; 3421 3625 } 3422 3423 *max_xmit = SVAL(ret_vwv + 0, 0); 3424 *tid = SVAL(ret_vwv + 1, 0); 3425 3626 *max_xmit = SVAL(state->ret_vwv + 0, 0); 3627 *tid = SVAL(state->ret_vwv + 1, 0); 3426 3628 return NT_STATUS_OK; 3629 } 3630 3631 NTSTATUS cli_raw_tcon(struct cli_state *cli, 3632 const char *service, const char *pass, const char *dev, 3633 uint16_t *max_xmit, uint16_t *tid) 3634 { 3635 struct tevent_context *ev; 3636 struct tevent_req *req; 3637 NTSTATUS status = NT_STATUS_NO_MEMORY; 3638 3639 ev = samba_tevent_context_init(talloc_tos()); 3640 if (ev == NULL) { 3641 goto fail; 3642 } 3643 req = cli_raw_tcon_send(ev, ev, cli, service, pass, dev); 3644 if (req == NULL) { 3645 goto fail; 3646 } 3647 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 3648 goto fail; 3649 } 3650 status = cli_raw_tcon_recv(req, max_xmit, tid); 3651 fail: 3652 TALLOC_FREE(ev); 3653 return status; 3427 3654 } 3428 3655 … … 3446 3673 user_info->password ? user_info->password : "", 3447 3674 flags, 3448 Undefined);3675 SMB_SIGNING_DEFAULT); 3449 3676 3450 3677 if (NT_STATUS_IS_OK(nt_status)) { … … 3550 3777 DEBUG(99, ("No master browsers responded: %s\n", 3551 3778 nt_errstr(status))); 3552 return False;3779 return NULL; 3553 3780 } 3554 3781
Note:
See TracChangeset
for help on using the changeset viewer.