Changeset 740 for vendor/current/source3/libsmb/cliconnect.c
- Timestamp:
- Nov 14, 2012, 12:59:34 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/libsmb/cliconnect.c
r597 r740 4 4 Copyright (C) Andrew Tridgell 1994-1998 5 5 Copyright (C) Andrew Bartlett 2001-2003 6 6 Copyright (C) Volker Lendecke 2011 7 Copyright (C) Jeremy Allison 2011 8 7 9 This program is free software; you can redistribute it and/or modify 8 10 it under the terms of the GNU General Public License as published by 9 11 the Free Software Foundation; either version 3 of the License, or 10 12 (at your option) any later version. 11 13 12 14 This program is distributed in the hope that it will be useful, 13 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 17 GNU General Public License for more details. 16 18 17 19 You should have received a copy of the GNU General Public License 18 20 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 20 22 21 23 #include "includes.h" 24 #include "libsmb/libsmb.h" 25 #include "popt_common.h" 22 26 #include "../libcli/auth/libcli_auth.h" 23 27 #include "../libcli/auth/spnego.h" 24 28 #include "smb_krb5.h" 29 #include "../libcli/auth/ntlmssp.h" 30 #include "libads/kerberos_proto.h" 31 #include "krb5_env.h" 32 #include "../lib/util/tevent_ntstatus.h" 33 #include "async_smb.h" 34 #include "libsmb/nmblib.h" 25 35 26 36 static const struct { … … 42 52 #define STAR_SMBSERVER "*SMBSERVER" 43 53 54 /******************************************************** 55 Utility function to ensure we always return at least 56 a valid char * pointer to an empty string for the 57 cli->server_os, cli->server_type and cli->server_domain 58 strings. 59 *******************************************************/ 60 61 static NTSTATUS smb_bytes_talloc_string(struct cli_state *cli, 62 char *inbuf, 63 char **dest, 64 uint8_t *src, 65 size_t srclen, 66 ssize_t *destlen) 67 { 68 *destlen = clistr_pull_talloc(cli, 69 inbuf, 70 SVAL(inbuf, smb_flg2), 71 dest, 72 (char *)src, 73 srclen, 74 STR_TERMINATE); 75 if (*destlen == -1) { 76 return NT_STATUS_NO_MEMORY; 77 } 78 79 if (*dest == NULL) { 80 *dest = talloc_strdup(cli, ""); 81 if (*dest == NULL) { 82 return NT_STATUS_NO_MEMORY; 83 } 84 } 85 return NT_STATUS_OK; 86 } 87 44 88 /** 45 89 * Set the user session key for a connection … … 58 102 ****************************************************************************/ 59 103 60 static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli, 61 const char *user, 104 struct cli_session_setup_lanman2_state { 105 struct cli_state *cli; 106 uint16_t vwv[10]; 107 const char *user; 108 }; 109 110 static void cli_session_setup_lanman2_done(struct tevent_req *subreq); 111 112 static struct tevent_req *cli_session_setup_lanman2_send( 113 TALLOC_CTX *mem_ctx, struct tevent_context *ev, 114 struct cli_state *cli, const char *user, 115 const char *pass, size_t passlen, 116 const char *workgroup) 117 { 118 struct tevent_req *req, *subreq; 119 struct cli_session_setup_lanman2_state *state; 120 DATA_BLOB lm_response = data_blob_null; 121 uint16_t *vwv; 122 uint8_t *bytes; 123 char *tmp; 124 125 req = tevent_req_create(mem_ctx, &state, 126 struct cli_session_setup_lanman2_state); 127 if (req == NULL) { 128 return NULL; 129 } 130 state->cli = cli; 131 state->user = user; 132 vwv = state->vwv; 133 134 /* 135 * LANMAN servers predate NT status codes and Unicode and 136 * ignore those smb flags so we must disable the corresponding 137 * default capabilities that would otherwise cause the Unicode 138 * and NT Status flags to be set (and even returned by the 139 * server) 140 */ 141 142 cli->capabilities &= ~(CAP_UNICODE | CAP_STATUS32); 143 144 /* 145 * if in share level security then don't send a password now 146 */ 147 if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) { 148 passlen = 0; 149 } 150 151 if (passlen > 0 152 && (cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) 153 && passlen != 24) { 154 /* 155 * Encrypted mode needed, and non encrypted password 156 * supplied. 157 */ 158 lm_response = data_blob(NULL, 24); 159 if (tevent_req_nomem(lm_response.data, req)) { 160 return tevent_req_post(req, ev); 161 } 162 163 if (!SMBencrypt(pass, cli->secblob.data, 164 (uint8_t *)lm_response.data)) { 165 DEBUG(1, ("Password is > 14 chars in length, and is " 166 "therefore incompatible with Lanman " 167 "authentication\n")); 168 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); 169 return tevent_req_post(req, ev); 170 } 171 } else if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) 172 && passlen == 24) { 173 /* 174 * Encrypted mode needed, and encrypted password 175 * supplied. 176 */ 177 lm_response = data_blob(pass, passlen); 178 if (tevent_req_nomem(lm_response.data, req)) { 179 return tevent_req_post(req, ev); 180 } 181 } else if (passlen > 0) { 182 uint8_t *buf; 183 size_t converted_size; 184 /* 185 * Plaintext mode needed, assume plaintext supplied. 186 */ 187 buf = talloc_array(talloc_tos(), uint8_t, 0); 188 buf = smb_bytes_push_str(buf, cli_ucs2(cli), pass, passlen+1, 189 &converted_size); 190 if (tevent_req_nomem(buf, req)) { 191 return tevent_req_post(req, ev); 192 } 193 lm_response = data_blob(pass, passlen); 194 TALLOC_FREE(buf); 195 if (tevent_req_nomem(lm_response.data, req)) { 196 return tevent_req_post(req, ev); 197 } 198 } 199 200 SCVAL(vwv+0, 0, 0xff); 201 SCVAL(vwv+0, 1, 0); 202 SSVAL(vwv+1, 0, 0); 203 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE); 204 SSVAL(vwv+3, 0, 2); 205 SSVAL(vwv+4, 0, 1); 206 SIVAL(vwv+5, 0, cli->sesskey); 207 SSVAL(vwv+7, 0, lm_response.length); 208 209 bytes = talloc_array(state, uint8_t, lm_response.length); 210 if (tevent_req_nomem(bytes, req)) { 211 return tevent_req_post(req, ev); 212 } 213 if (lm_response.length != 0) { 214 memcpy(bytes, lm_response.data, lm_response.length); 215 } 216 data_blob_free(&lm_response); 217 218 tmp = talloc_strdup_upper(talloc_tos(), user); 219 if (tevent_req_nomem(tmp, req)) { 220 return tevent_req_post(req, ev); 221 } 222 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1, 223 NULL); 224 TALLOC_FREE(tmp); 225 226 tmp = talloc_strdup_upper(talloc_tos(), workgroup); 227 if (tevent_req_nomem(tmp, req)) { 228 return tevent_req_post(req, ev); 229 } 230 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1, 231 NULL); 232 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Unix", 5, NULL); 233 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Samba", 6, NULL); 234 235 if (tevent_req_nomem(bytes, req)) { 236 return tevent_req_post(req, ev); 237 } 238 239 subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 10, vwv, 240 talloc_get_size(bytes), bytes); 241 if (tevent_req_nomem(subreq, req)) { 242 return tevent_req_post(req, ev); 243 } 244 tevent_req_set_callback(subreq, cli_session_setup_lanman2_done, req); 245 return req; 246 } 247 248 static void cli_session_setup_lanman2_done(struct tevent_req *subreq) 249 { 250 struct tevent_req *req = tevent_req_callback_data( 251 subreq, struct tevent_req); 252 struct cli_session_setup_lanman2_state *state = tevent_req_data( 253 req, struct cli_session_setup_lanman2_state); 254 struct cli_state *cli = state->cli; 255 uint32_t num_bytes; 256 uint8_t *in; 257 char *inbuf; 258 uint8_t *bytes; 259 uint8_t *p; 260 NTSTATUS status; 261 ssize_t ret; 262 uint8_t wct; 263 uint16_t *vwv; 264 265 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv, 266 &num_bytes, &bytes); 267 TALLOC_FREE(subreq); 268 if (!NT_STATUS_IS_OK(status)) { 269 tevent_req_nterror(req, status); 270 return; 271 } 272 273 inbuf = (char *)in; 274 p = bytes; 275 276 cli->vuid = SVAL(inbuf, smb_uid); 277 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0); 278 279 status = smb_bytes_talloc_string(cli, 280 inbuf, 281 &cli->server_os, 282 p, 283 bytes+num_bytes-p, 284 &ret); 285 286 if (!NT_STATUS_IS_OK(status)) { 287 tevent_req_nterror(req, status); 288 return; 289 } 290 p += ret; 291 292 status = smb_bytes_talloc_string(cli, 293 inbuf, 294 &cli->server_type, 295 p, 296 bytes+num_bytes-p, 297 &ret); 298 299 if (!NT_STATUS_IS_OK(status)) { 300 tevent_req_nterror(req, status); 301 return; 302 } 303 p += ret; 304 305 status = smb_bytes_talloc_string(cli, 306 inbuf, 307 &cli->server_domain, 308 p, 309 bytes+num_bytes-p, 310 &ret); 311 312 if (!NT_STATUS_IS_OK(status)) { 313 tevent_req_nterror(req, status); 314 return; 315 } 316 p += ret; 317 318 if (strstr(cli->server_type, "Samba")) { 319 cli->is_samba = True; 320 } 321 status = cli_set_username(cli, state->user); 322 if (tevent_req_nterror(req, status)) { 323 return; 324 } 325 tevent_req_done(req); 326 } 327 328 static NTSTATUS cli_session_setup_lanman2_recv(struct tevent_req *req) 329 { 330 return tevent_req_simple_recv_ntstatus(req); 331 } 332 333 static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli, const char *user, 62 334 const char *pass, size_t passlen, 63 335 const char *workgroup) 64 336 { 65 DATA_BLOB session_key = data_blob_null; 66 DATA_BLOB lm_response = data_blob_null; 67 NTSTATUS status; 68 fstring pword; 69 char *p; 70 71 if (passlen > sizeof(pword)-1) { 72 return NT_STATUS_INVALID_PARAMETER; 73 } 74 75 /* LANMAN servers predate NT status codes and Unicode and ignore those 76 smb flags so we must disable the corresponding default capabilities 77 that would otherwise cause the Unicode and NT Status flags to be 78 set (and even returned by the server) */ 79 80 cli->capabilities &= ~(CAP_UNICODE | CAP_STATUS32); 81 82 /* if in share level security then don't send a password now */ 83 if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) 84 passlen = 0; 85 86 if (passlen > 0 && (cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen != 24) { 87 /* Encrypted mode needed, and non encrypted password supplied. */ 88 lm_response = data_blob(NULL, 24); 89 if (!SMBencrypt(pass, cli->secblob.data,(uchar *)lm_response.data)) { 90 DEBUG(1, ("Password is > 14 chars in length, and is therefore incompatible with Lanman authentication\n")); 91 return NT_STATUS_ACCESS_DENIED; 92 } 93 } else if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen == 24) { 94 /* Encrypted mode needed, and encrypted password supplied. */ 95 lm_response = data_blob(pass, passlen); 96 } else if (passlen > 0) { 97 /* Plaintext mode needed, assume plaintext supplied. */ 98 passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE); 99 lm_response = data_blob(pass, passlen); 100 } 101 102 /* send a session setup command */ 103 memset(cli->outbuf,'\0',smb_size); 104 cli_set_message(cli->outbuf,10, 0, True); 105 SCVAL(cli->outbuf,smb_com,SMBsesssetupX); 106 cli_setup_packet(cli); 107 108 SCVAL(cli->outbuf,smb_vwv0,0xFF); 109 SSVAL(cli->outbuf,smb_vwv2,cli->max_xmit); 110 SSVAL(cli->outbuf,smb_vwv3,2); 111 SSVAL(cli->outbuf,smb_vwv4,1); 112 SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); 113 SSVAL(cli->outbuf,smb_vwv7,lm_response.length); 114 115 p = smb_buf(cli->outbuf); 116 memcpy(p,lm_response.data,lm_response.length); 117 p += lm_response.length; 118 p += clistr_push(cli, p, user, -1, STR_TERMINATE|STR_UPPER); 119 p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE|STR_UPPER); 120 p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); 121 p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); 122 cli_setup_bcc(cli, p); 123 124 if (!cli_send_smb(cli) || !cli_receive_smb(cli)) { 125 return cli_nt_error(cli); 126 } 127 128 show_msg(cli->inbuf); 129 130 if (cli_is_error(cli)) { 131 return cli_nt_error(cli); 132 } 133 134 /* use the returned vuid from now on */ 135 cli->vuid = SVAL(cli->inbuf,smb_uid); 136 status = cli_set_username(cli, user); 137 if (!NT_STATUS_IS_OK(status)) { 138 return status; 139 } 140 141 if (session_key.data) { 142 /* Have plaintext orginal */ 143 cli_set_session_key(cli, session_key); 144 } 145 146 return NT_STATUS_OK; 337 TALLOC_CTX *frame = talloc_stackframe(); 338 struct event_context *ev; 339 struct tevent_req *req; 340 NTSTATUS status = NT_STATUS_NO_MEMORY; 341 342 if (cli_has_async_calls(cli)) { 343 /* 344 * Can't use sync call while an async call is in flight 345 */ 346 status = NT_STATUS_INVALID_PARAMETER; 347 goto fail; 348 } 349 ev = event_context_init(frame); 350 if (ev == NULL) { 351 goto fail; 352 } 353 req = cli_session_setup_lanman2_send(frame, ev, cli, user, pass, passlen, 354 workgroup); 355 if (req == NULL) { 356 goto fail; 357 } 358 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 359 goto fail; 360 } 361 status = cli_session_setup_lanman2_recv(req); 362 fail: 363 TALLOC_FREE(frame); 364 if (!NT_STATUS_IS_OK(status)) { 365 cli_set_error(cli, status); 366 } 367 return status; 147 368 } 148 369 … … 171 392 struct cli_session_setup_guest_state { 172 393 struct cli_state *cli; 173 uint16_t vwv[1 6];394 uint16_t vwv[13]; 174 395 struct iovec bytes; 175 396 }; … … 264 485 struct cli_state *cli = state->cli; 265 486 uint32_t num_bytes; 487 uint8_t *in; 266 488 char *inbuf; 267 489 uint8_t *bytes; 268 490 uint8_t *p; 269 491 NTSTATUS status; 270 271 status = cli_smb_recv(subreq, 0, NULL, NULL, &num_bytes, &bytes); 272 if (!NT_STATUS_IS_OK(status)) { 273 TALLOC_FREE(subreq); 492 ssize_t ret; 493 uint8_t wct; 494 uint16_t *vwv; 495 496 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv, 497 &num_bytes, &bytes); 498 TALLOC_FREE(subreq); 499 if (!NT_STATUS_IS_OK(status)) { 274 500 tevent_req_nterror(req, status); 275 501 return; 276 502 } 277 503 278 inbuf = (char *) cli_smb_inbuf(subreq);504 inbuf = (char *)in; 279 505 p = bytes; 280 506 281 507 cli->vuid = SVAL(inbuf, smb_uid); 282 283 p += clistr_pull(inbuf, cli->server_os, (char *)p, sizeof(fstring), 284 bytes+num_bytes-p, STR_TERMINATE); 285 p += clistr_pull(inbuf, cli->server_type, (char *)p, sizeof(fstring), 286 bytes+num_bytes-p, STR_TERMINATE); 287 p += clistr_pull(inbuf, cli->server_domain, (char *)p, sizeof(fstring), 288 bytes+num_bytes-p, STR_TERMINATE); 508 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0); 509 510 status = smb_bytes_talloc_string(cli, 511 inbuf, 512 &cli->server_os, 513 p, 514 bytes+num_bytes-p, 515 &ret); 516 517 if (!NT_STATUS_IS_OK(status)) { 518 tevent_req_nterror(req, status); 519 return; 520 } 521 p += ret; 522 523 status = smb_bytes_talloc_string(cli, 524 inbuf, 525 &cli->server_type, 526 p, 527 bytes+num_bytes-p, 528 &ret); 529 530 if (!NT_STATUS_IS_OK(status)) { 531 tevent_req_nterror(req, status); 532 return; 533 } 534 p += ret; 535 536 status = smb_bytes_talloc_string(cli, 537 inbuf, 538 &cli->server_domain, 539 p, 540 bytes+num_bytes-p, 541 &ret); 542 543 if (!NT_STATUS_IS_OK(status)) { 544 tevent_req_nterror(req, status); 545 return; 546 } 547 p += ret; 289 548 290 549 if (strstr(cli->server_type, "Samba")) { 291 550 cli->is_samba = True; 292 551 } 293 294 TALLOC_FREE(subreq);295 552 296 553 status = cli_set_username(cli, ""); … … 352 609 ****************************************************************************/ 353 610 354 static NTSTATUS cli_session_setup_plaintext(struct cli_state *cli, 355 const char *user, const char *pass, 356 const char *workgroup) 357 { 358 uint32 capabilities = cli_session_setup_capabilities(cli); 359 char *p; 611 struct cli_session_setup_plain_state { 612 struct cli_state *cli; 613 uint16_t vwv[13]; 614 const char *user; 615 }; 616 617 static void cli_session_setup_plain_done(struct tevent_req *subreq); 618 619 static struct tevent_req *cli_session_setup_plain_send( 620 TALLOC_CTX *mem_ctx, struct tevent_context *ev, 621 struct cli_state *cli, 622 const char *user, const char *pass, const char *workgroup) 623 { 624 struct tevent_req *req, *subreq; 625 struct cli_session_setup_plain_state *state; 626 uint16_t *vwv; 627 uint8_t *bytes; 628 size_t passlen; 629 char *version; 630 631 req = tevent_req_create(mem_ctx, &state, 632 struct cli_session_setup_plain_state); 633 if (req == NULL) { 634 return NULL; 635 } 636 state->cli = cli; 637 state->user = user; 638 vwv = state->vwv; 639 640 SCVAL(vwv+0, 0, 0xff); 641 SCVAL(vwv+0, 1, 0); 642 SSVAL(vwv+1, 0, 0); 643 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE); 644 SSVAL(vwv+3, 0, 2); 645 SSVAL(vwv+4, 0, cli->pid); 646 SIVAL(vwv+5, 0, cli->sesskey); 647 SSVAL(vwv+7, 0, 0); 648 SSVAL(vwv+8, 0, 0); 649 SSVAL(vwv+9, 0, 0); 650 SSVAL(vwv+10, 0, 0); 651 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli)); 652 653 bytes = talloc_array(state, uint8_t, 0); 654 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), pass, strlen(pass)+1, 655 &passlen); 656 if (tevent_req_nomem(bytes, req)) { 657 return tevent_req_post(req, ev); 658 } 659 SSVAL(vwv + (cli_ucs2(cli) ? 8 : 7), 0, passlen); 660 661 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), 662 user, strlen(user)+1, NULL); 663 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), 664 workgroup, strlen(workgroup)+1, NULL); 665 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), 666 "Unix", 5, NULL); 667 668 version = talloc_asprintf(talloc_tos(), "Samba %s", 669 samba_version_string()); 670 if (tevent_req_nomem(version, req)){ 671 return tevent_req_post(req, ev); 672 } 673 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), 674 version, strlen(version)+1, NULL); 675 TALLOC_FREE(version); 676 677 if (tevent_req_nomem(bytes, req)) { 678 return tevent_req_post(req, ev); 679 } 680 681 subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 13, vwv, 682 talloc_get_size(bytes), bytes); 683 if (tevent_req_nomem(subreq, req)) { 684 return tevent_req_post(req, ev); 685 } 686 tevent_req_set_callback(subreq, cli_session_setup_plain_done, req); 687 return req; 688 } 689 690 static void cli_session_setup_plain_done(struct tevent_req *subreq) 691 { 692 struct tevent_req *req = tevent_req_callback_data( 693 subreq, struct tevent_req); 694 struct cli_session_setup_plain_state *state = tevent_req_data( 695 req, struct cli_session_setup_plain_state); 696 struct cli_state *cli = state->cli; 697 uint32_t num_bytes; 698 uint8_t *in; 699 char *inbuf; 700 uint8_t *bytes; 701 uint8_t *p; 360 702 NTSTATUS status; 361 fstring lanman; 362 363 fstr_sprintf( lanman, "Samba %s", samba_version_string()); 364 365 memset(cli->outbuf, '\0', smb_size); 366 cli_set_message(cli->outbuf,13,0,True); 367 SCVAL(cli->outbuf,smb_com,SMBsesssetupX); 368 cli_setup_packet(cli); 369 370 SCVAL(cli->outbuf,smb_vwv0,0xFF); 371 SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE); 372 SSVAL(cli->outbuf,smb_vwv3,2); 373 SSVAL(cli->outbuf,smb_vwv4,cli->pid); 374 SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); 375 SSVAL(cli->outbuf,smb_vwv8,0); 376 SIVAL(cli->outbuf,smb_vwv11,capabilities); 377 p = smb_buf(cli->outbuf); 378 379 /* check wether to send the ASCII or UNICODE version of the password */ 380 381 if ( (capabilities & CAP_UNICODE) == 0 ) { 382 p += clistr_push(cli, p, pass, -1, STR_TERMINATE); /* password */ 383 SSVAL(cli->outbuf,smb_vwv7,PTR_DIFF(p, smb_buf(cli->outbuf))); 384 } 385 else { 386 /* For ucs2 passwords clistr_push calls ucs2_align, which causes 387 * the space taken by the unicode password to be one byte too 388 * long (as we're on an odd byte boundary here). Reduce the 389 * count by 1 to cope with this. Fixes smbclient against NetApp 390 * servers which can't cope. Fix from 391 * bryan.kolodziej@allenlund.com in bug #3840. 392 */ 393 p += clistr_push(cli, p, pass, -1, STR_UNICODE|STR_TERMINATE); /* unicode password */ 394 SSVAL(cli->outbuf,smb_vwv8,PTR_DIFF(p, smb_buf(cli->outbuf))-1); 395 } 396 397 p += clistr_push(cli, p, user, -1, STR_TERMINATE); /* username */ 398 p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE); /* workgroup */ 399 p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); 400 p += clistr_push(cli, p, lanman, -1, STR_TERMINATE); 401 cli_setup_bcc(cli, p); 402 403 if (!cli_send_smb(cli) || !cli_receive_smb(cli)) { 404 return cli_nt_error(cli); 405 } 406 407 show_msg(cli->inbuf); 408 409 if (cli_is_error(cli)) { 410 return cli_nt_error(cli); 411 } 412 413 cli->vuid = SVAL(cli->inbuf,smb_uid); 414 p = smb_buf(cli->inbuf); 415 p += clistr_pull(cli->inbuf, cli->server_os, p, sizeof(fstring), 416 -1, STR_TERMINATE); 417 p += clistr_pull(cli->inbuf, cli->server_type, p, sizeof(fstring), 418 -1, STR_TERMINATE); 419 p += clistr_pull(cli->inbuf, cli->server_domain, p, sizeof(fstring), 420 -1, STR_TERMINATE); 421 status = cli_set_username(cli, user); 422 if (!NT_STATUS_IS_OK(status)) { 423 return status; 703 ssize_t ret; 704 uint8_t wct; 705 uint16_t *vwv; 706 707 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv, 708 &num_bytes, &bytes); 709 TALLOC_FREE(subreq); 710 if (tevent_req_nterror(req, status)) { 711 return; 712 } 713 714 inbuf = (char *)in; 715 p = bytes; 716 717 cli->vuid = SVAL(inbuf, smb_uid); 718 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0); 719 720 status = smb_bytes_talloc_string(cli, 721 inbuf, 722 &cli->server_os, 723 p, 724 bytes+num_bytes-p, 725 &ret); 726 727 if (!NT_STATUS_IS_OK(status)) { 728 tevent_req_nterror(req, status); 729 return; 730 } 731 p += ret; 732 733 status = smb_bytes_talloc_string(cli, 734 inbuf, 735 &cli->server_type, 736 p, 737 bytes+num_bytes-p, 738 &ret); 739 740 if (!NT_STATUS_IS_OK(status)) { 741 tevent_req_nterror(req, status); 742 return; 743 } 744 p += ret; 745 746 status = smb_bytes_talloc_string(cli, 747 inbuf, 748 &cli->server_domain, 749 p, 750 bytes+num_bytes-p, 751 &ret); 752 753 if (!NT_STATUS_IS_OK(status)) { 754 tevent_req_nterror(req, status); 755 return; 756 } 757 p += ret; 758 759 status = cli_set_username(cli, state->user); 760 if (tevent_req_nterror(req, status)) { 761 return; 424 762 } 425 763 if (strstr(cli->server_type, "Samba")) { 426 764 cli->is_samba = True; 427 765 } 428 429 return NT_STATUS_OK; 766 tevent_req_done(req); 767 } 768 769 static NTSTATUS cli_session_setup_plain_recv(struct tevent_req *req) 770 { 771 return tevent_req_simple_recv_ntstatus(req); 772 } 773 774 static NTSTATUS cli_session_setup_plain(struct cli_state *cli, 775 const char *user, const char *pass, 776 const char *workgroup) 777 { 778 TALLOC_CTX *frame = talloc_stackframe(); 779 struct event_context *ev; 780 struct tevent_req *req; 781 NTSTATUS status = NT_STATUS_NO_MEMORY; 782 783 if (cli_has_async_calls(cli)) { 784 /* 785 * Can't use sync call while an async call is in flight 786 */ 787 status = NT_STATUS_INVALID_PARAMETER; 788 goto fail; 789 } 790 ev = event_context_init(frame); 791 if (ev == NULL) { 792 goto fail; 793 } 794 req = cli_session_setup_plain_send(frame, ev, cli, user, pass, 795 workgroup); 796 if (req == NULL) { 797 goto fail; 798 } 799 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 800 goto fail; 801 } 802 status = cli_session_setup_plain_recv(req); 803 fail: 804 TALLOC_FREE(frame); 805 if (!NT_STATUS_IS_OK(status)) { 806 cli_set_error(cli, status); 807 } 808 return status; 430 809 } 431 810 … … 440 819 ****************************************************************************/ 441 820 442 static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user, 443 const char *pass, size_t passlen, 444 const char *ntpass, size_t ntpasslen, 445 const char *workgroup) 446 { 447 uint32 capabilities = cli_session_setup_capabilities(cli); 821 struct cli_session_setup_nt1_state { 822 struct cli_state *cli; 823 uint16_t vwv[13]; 824 DATA_BLOB response; 825 DATA_BLOB session_key; 826 const char *user; 827 }; 828 829 static void cli_session_setup_nt1_done(struct tevent_req *subreq); 830 831 static struct tevent_req *cli_session_setup_nt1_send( 832 TALLOC_CTX *mem_ctx, struct tevent_context *ev, 833 struct cli_state *cli, const char *user, 834 const char *pass, size_t passlen, 835 const char *ntpass, size_t ntpasslen, 836 const char *workgroup) 837 { 838 struct tevent_req *req, *subreq; 839 struct cli_session_setup_nt1_state *state; 448 840 DATA_BLOB lm_response = data_blob_null; 449 841 DATA_BLOB nt_response = data_blob_null; 450 842 DATA_BLOB session_key = data_blob_null; 451 NTSTATUS result; 452 char *p; 453 bool ok; 843 uint16_t *vwv; 844 uint8_t *bytes; 845 char *workgroup_upper; 846 847 req = tevent_req_create(mem_ctx, &state, 848 struct cli_session_setup_nt1_state); 849 if (req == NULL) { 850 return NULL; 851 } 852 state->cli = cli; 853 state->user = user; 854 vwv = state->vwv; 454 855 455 856 if (passlen == 0) { … … 459 860 DATA_BLOB server_chal; 460 861 DATA_BLOB names_blob; 461 server_chal = data_blob(cli->secblob.data, MIN(cli->secblob.length, 8)); 462 463 /* note that the 'workgroup' here is a best guess - we don't know 464 the server's domain at this point. The 'server name' is also 465 dodgy... 466 */ 467 names_blob = NTLMv2_generate_names_blob(NULL, cli->called.name, workgroup); 468 469 if (!SMBNTLMv2encrypt(NULL, user, workgroup, pass, &server_chal, 470 &names_blob, 471 &lm_response, &nt_response, NULL, &session_key)) { 862 863 server_chal = data_blob(cli->secblob.data, 864 MIN(cli->secblob.length, 8)); 865 if (tevent_req_nomem(server_chal.data, req)) { 866 return tevent_req_post(req, ev); 867 } 868 869 /* 870 * note that the 'workgroup' here is a best 871 * guess - we don't know the server's domain 872 * at this point. The 'server name' is also 873 * dodgy... 874 */ 875 names_blob = NTLMv2_generate_names_blob( 876 NULL, cli->called.name, workgroup); 877 878 if (tevent_req_nomem(names_blob.data, req)) { 879 return tevent_req_post(req, ev); 880 } 881 882 if (!SMBNTLMv2encrypt(NULL, user, workgroup, pass, 883 &server_chal, &names_blob, 884 &lm_response, &nt_response, 885 NULL, &session_key)) { 472 886 data_blob_free(&names_blob); 473 887 data_blob_free(&server_chal); 474 return NT_STATUS_ACCESS_DENIED; 888 tevent_req_nterror( 889 req, NT_STATUS_ACCESS_DENIED); 890 return tevent_req_post(req, ev); 475 891 } 476 892 data_blob_free(&names_blob); … … 485 901 #else 486 902 nt_response = data_blob(NULL, 24); 487 SMBNTencrypt(pass,cli->secblob.data,nt_response.data); 903 if (tevent_req_nomem(nt_response.data, req)) { 904 return tevent_req_post(req, ev); 905 } 906 907 SMBNTencrypt(pass, cli->secblob.data, 908 nt_response.data); 488 909 #endif 489 910 /* non encrypted password supplied. Ignore ntpass. */ 490 911 if (lp_client_lanman_auth()) { 912 491 913 lm_response = data_blob(NULL, 24); 492 if (!SMBencrypt(pass,cli->secblob.data, lm_response.data)) { 493 /* Oops, the LM response is invalid, just put 494 the NT response there instead */ 914 if (tevent_req_nomem(lm_response.data, req)) { 915 return tevent_req_post(req, ev); 916 } 917 918 if (!SMBencrypt(pass,cli->secblob.data, 919 lm_response.data)) { 920 /* 921 * Oops, the LM response is 922 * invalid, just put the NT 923 * response there instead 924 */ 495 925 data_blob_free(&lm_response); 496 lm_response = data_blob(nt_response.data, nt_response.length); 926 lm_response = data_blob( 927 nt_response.data, 928 nt_response.length); 497 929 } 498 930 } else { 499 /* LM disabled, place NT# in LM field instead */ 500 lm_response = data_blob(nt_response.data, nt_response.length); 931 /* 932 * LM disabled, place NT# in LM field 933 * instead 934 */ 935 lm_response = data_blob( 936 nt_response.data, nt_response.length); 501 937 } 502 938 939 if (tevent_req_nomem(lm_response.data, req)) { 940 return tevent_req_post(req, ev); 941 } 942 503 943 session_key = data_blob(NULL, 16); 944 if (tevent_req_nomem(session_key.data, req)) { 945 return tevent_req_post(req, ev); 946 } 504 947 #ifdef LANMAN_ONLY 505 948 E_deshash(pass, session_key.data); … … 516 959 517 960 lm_response = data_blob(pass, passlen); 961 if (tevent_req_nomem(lm_response.data, req)) { 962 return tevent_req_post(req, ev); 963 } 964 518 965 nt_response = data_blob(ntpass, ntpasslen); 519 } 520 521 /* send a session setup command */ 522 memset(cli->outbuf,'\0',smb_size); 523 524 cli_set_message(cli->outbuf,13,0,True); 525 SCVAL(cli->outbuf,smb_com,SMBsesssetupX); 526 cli_setup_packet(cli); 527 528 SCVAL(cli->outbuf,smb_vwv0,0xFF); 529 SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE); 530 SSVAL(cli->outbuf,smb_vwv3,2); 531 SSVAL(cli->outbuf,smb_vwv4,cli->pid); 532 SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); 533 SSVAL(cli->outbuf,smb_vwv7,lm_response.length); 534 SSVAL(cli->outbuf,smb_vwv8,nt_response.length); 535 SIVAL(cli->outbuf,smb_vwv11,capabilities); 536 p = smb_buf(cli->outbuf); 537 if (lm_response.length) { 538 memcpy(p,lm_response.data, lm_response.length); p += lm_response.length; 539 } 540 if (nt_response.length) { 541 memcpy(p,nt_response.data, nt_response.length); p += nt_response.length; 542 } 543 p += clistr_push(cli, p, user, -1, STR_TERMINATE); 544 545 /* Upper case here might help some NTLMv2 implementations */ 546 p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE|STR_UPPER); 547 p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); 548 p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); 549 cli_setup_bcc(cli, p); 550 551 if (!cli_send_smb(cli) || !cli_receive_smb(cli)) { 552 result = cli_nt_error(cli); 553 goto end; 554 } 555 556 /* show_msg(cli->inbuf); */ 557 558 if (cli_is_error(cli)) { 559 result = cli_nt_error(cli); 560 goto end; 966 if (tevent_req_nomem(nt_response.data, req)) { 967 return tevent_req_post(req, ev); 968 } 561 969 } 562 970 563 971 #ifdef LANMAN_ONLY 564 ok = cli_simple_set_signing(cli, session_key, lm_response); 972 state->response = data_blob_talloc( 973 state, lm_response.data, lm_response.length); 565 974 #else 566 ok = cli_simple_set_signing(cli, session_key, nt_response); 975 state->response = data_blob_talloc( 976 state, nt_response.data, nt_response.length); 567 977 #endif 568 if (ok) { 569 if (!cli_check_sign_mac(cli, cli->inbuf, 1)) { 570 result = NT_STATUS_ACCESS_DENIED; 571 goto end; 572 } 573 } 574 575 /* use the returned vuid from now on */ 576 cli->vuid = SVAL(cli->inbuf,smb_uid); 577 578 p = smb_buf(cli->inbuf); 579 p += clistr_pull(cli->inbuf, cli->server_os, p, sizeof(fstring), 580 -1, STR_TERMINATE); 581 p += clistr_pull(cli->inbuf, cli->server_type, p, sizeof(fstring), 582 -1, STR_TERMINATE); 583 p += clistr_pull(cli->inbuf, cli->server_domain, p, sizeof(fstring), 584 -1, STR_TERMINATE); 978 if (tevent_req_nomem(state->response.data, req)) { 979 return tevent_req_post(req, ev); 980 } 981 982 if (session_key.data) { 983 state->session_key = data_blob_talloc( 984 state, session_key.data, session_key.length); 985 if (tevent_req_nomem(state->session_key.data, req)) { 986 return tevent_req_post(req, ev); 987 } 988 } 989 data_blob_free(&session_key); 990 991 SCVAL(vwv+0, 0, 0xff); 992 SCVAL(vwv+0, 1, 0); 993 SSVAL(vwv+1, 0, 0); 994 SSVAL(vwv+2, 0, CLI_BUFFER_SIZE); 995 SSVAL(vwv+3, 0, 2); 996 SSVAL(vwv+4, 0, cli->pid); 997 SIVAL(vwv+5, 0, cli->sesskey); 998 SSVAL(vwv+7, 0, lm_response.length); 999 SSVAL(vwv+8, 0, nt_response.length); 1000 SSVAL(vwv+9, 0, 0); 1001 SSVAL(vwv+10, 0, 0); 1002 SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli)); 1003 1004 bytes = talloc_array(state, uint8_t, 1005 lm_response.length + nt_response.length); 1006 if (tevent_req_nomem(bytes, req)) { 1007 return tevent_req_post(req, ev); 1008 } 1009 if (lm_response.length != 0) { 1010 memcpy(bytes, lm_response.data, lm_response.length); 1011 } 1012 if (nt_response.length != 0) { 1013 memcpy(bytes + lm_response.length, 1014 nt_response.data, nt_response.length); 1015 } 1016 data_blob_free(&lm_response); 1017 data_blob_free(&nt_response); 1018 1019 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), 1020 user, strlen(user)+1, NULL); 1021 1022 /* 1023 * Upper case here might help some NTLMv2 implementations 1024 */ 1025 workgroup_upper = talloc_strdup_upper(talloc_tos(), workgroup); 1026 if (tevent_req_nomem(workgroup_upper, req)) { 1027 return tevent_req_post(req, ev); 1028 } 1029 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), 1030 workgroup_upper, strlen(workgroup_upper)+1, 1031 NULL); 1032 TALLOC_FREE(workgroup_upper); 1033 1034 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Unix", 5, NULL); 1035 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Samba", 6, NULL); 1036 if (tevent_req_nomem(bytes, req)) { 1037 return tevent_req_post(req, ev); 1038 } 1039 1040 subreq = cli_smb_send(state, ev, cli, SMBsesssetupX, 0, 13, vwv, 1041 talloc_get_size(bytes), bytes); 1042 if (tevent_req_nomem(subreq, req)) { 1043 return tevent_req_post(req, ev); 1044 } 1045 tevent_req_set_callback(subreq, cli_session_setup_nt1_done, req); 1046 return req; 1047 } 1048 1049 static void cli_session_setup_nt1_done(struct tevent_req *subreq) 1050 { 1051 struct tevent_req *req = tevent_req_callback_data( 1052 subreq, struct tevent_req); 1053 struct cli_session_setup_nt1_state *state = tevent_req_data( 1054 req, struct cli_session_setup_nt1_state); 1055 struct cli_state *cli = state->cli; 1056 uint32_t num_bytes; 1057 uint8_t *in; 1058 char *inbuf; 1059 uint8_t *bytes; 1060 uint8_t *p; 1061 NTSTATUS status; 1062 ssize_t ret; 1063 uint8_t wct; 1064 uint16_t *vwv; 1065 1066 status = cli_smb_recv(subreq, state, &in, 3, &wct, &vwv, 1067 &num_bytes, &bytes); 1068 TALLOC_FREE(subreq); 1069 if (!NT_STATUS_IS_OK(status)) { 1070 tevent_req_nterror(req, status); 1071 return; 1072 } 1073 1074 inbuf = (char *)in; 1075 p = bytes; 1076 1077 cli->vuid = SVAL(inbuf, smb_uid); 1078 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0); 1079 1080 status = smb_bytes_talloc_string(cli, 1081 inbuf, 1082 &cli->server_os, 1083 p, 1084 bytes+num_bytes-p, 1085 &ret); 1086 if (!NT_STATUS_IS_OK(status)) { 1087 tevent_req_nterror(req, status); 1088 return; 1089 } 1090 p += ret; 1091 1092 status = smb_bytes_talloc_string(cli, 1093 inbuf, 1094 &cli->server_type, 1095 p, 1096 bytes+num_bytes-p, 1097 &ret); 1098 if (!NT_STATUS_IS_OK(status)) { 1099 tevent_req_nterror(req, status); 1100 return; 1101 } 1102 p += ret; 1103 1104 status = smb_bytes_talloc_string(cli, 1105 inbuf, 1106 &cli->server_domain, 1107 p, 1108 bytes+num_bytes-p, 1109 &ret); 1110 if (!NT_STATUS_IS_OK(status)) { 1111 tevent_req_nterror(req, status); 1112 return; 1113 } 1114 p += ret; 585 1115 586 1116 if (strstr(cli->server_type, "Samba")) { … … 588 1118 } 589 1119 590 result = cli_set_username(cli, user); 591 if (!NT_STATUS_IS_OK(result)) { 592 goto end; 593 } 594 595 if (session_key.data) { 1120 status = cli_set_username(cli, state->user); 1121 if (tevent_req_nterror(req, status)) { 1122 return; 1123 } 1124 if (cli_simple_set_signing(cli, state->session_key, state->response) 1125 && !cli_check_sign_mac(cli, (char *)in, 1)) { 1126 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); 1127 return; 1128 } 1129 if (state->session_key.data) { 596 1130 /* Have plaintext orginal */ 597 cli_set_session_key(cli, session_key); 598 } 599 600 result = NT_STATUS_OK; 601 end: 602 data_blob_free(&lm_response); 603 data_blob_free(&nt_response); 604 data_blob_free(&session_key); 605 return result; 606 } 607 608 /**************************************************************************** 609 Send a extended security session setup blob 610 ****************************************************************************/ 611 612 static bool cli_session_setup_blob_send(struct cli_state *cli, DATA_BLOB blob) 613 { 614 uint32 capabilities = cli_session_setup_capabilities(cli); 615 char *p; 616 617 capabilities |= CAP_EXTENDED_SECURITY; 618 619 /* send a session setup command */ 620 memset(cli->outbuf,'\0',smb_size); 621 622 cli_set_message(cli->outbuf,12,0,True); 623 SCVAL(cli->outbuf,smb_com,SMBsesssetupX); 624 625 cli_setup_packet(cli); 626 627 SCVAL(cli->outbuf,smb_vwv0,0xFF); 628 SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE); 629 SSVAL(cli->outbuf,smb_vwv3,2); 630 SSVAL(cli->outbuf,smb_vwv4,1); 631 SIVAL(cli->outbuf,smb_vwv5,0); 632 SSVAL(cli->outbuf,smb_vwv7,blob.length); 633 SIVAL(cli->outbuf,smb_vwv10,capabilities); 634 p = smb_buf(cli->outbuf); 635 memcpy(p, blob.data, blob.length); 636 p += blob.length; 637 p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); 638 p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); 639 cli_setup_bcc(cli, p); 640 return cli_send_smb(cli); 641 } 642 643 /**************************************************************************** 644 Send a extended security session setup blob, returning a reply blob. 645 ****************************************************************************/ 646 647 static DATA_BLOB cli_session_setup_blob_receive(struct cli_state *cli) 648 { 649 DATA_BLOB blob2 = data_blob_null; 650 char *p; 651 size_t len; 652 653 if (!cli_receive_smb(cli)) 654 return blob2; 655 656 show_msg(cli->inbuf); 657 658 if (cli_is_error(cli) && !NT_STATUS_EQUAL(cli_nt_error(cli), 659 NT_STATUS_MORE_PROCESSING_REQUIRED)) { 660 return blob2; 661 } 662 663 /* use the returned vuid from now on */ 664 cli->vuid = SVAL(cli->inbuf,smb_uid); 665 666 p = smb_buf(cli->inbuf); 667 668 blob2 = data_blob(p, SVAL(cli->inbuf, smb_vwv3)); 669 670 p += blob2.length; 671 p += clistr_pull(cli->inbuf, cli->server_os, p, sizeof(fstring), 672 -1, STR_TERMINATE); 673 674 /* w2k with kerberos doesn't properly null terminate this field */ 675 len = smb_bufrem(cli->inbuf, p); 676 if (p + len < cli->inbuf + cli->bufsize+SAFETY_MARGIN - 2) { 677 char *end_of_buf = p + len; 678 679 SSVAL(p, len, 0); 680 /* Now it's null terminated. */ 681 p += clistr_pull(cli->inbuf, cli->server_type, p, sizeof(fstring), 682 -1, STR_TERMINATE); 1131 cli_set_session_key(cli, state->session_key); 1132 } 1133 tevent_req_done(req); 1134 } 1135 1136 static NTSTATUS cli_session_setup_nt1_recv(struct tevent_req *req) 1137 { 1138 return tevent_req_simple_recv_ntstatus(req); 1139 } 1140 1141 static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user, 1142 const char *pass, size_t passlen, 1143 const char *ntpass, size_t ntpasslen, 1144 const char *workgroup) 1145 { 1146 TALLOC_CTX *frame = talloc_stackframe(); 1147 struct event_context *ev; 1148 struct tevent_req *req; 1149 NTSTATUS status = NT_STATUS_NO_MEMORY; 1150 1151 if (cli_has_async_calls(cli)) { 683 1152 /* 684 * See if there's another string. If so it's the 685 * server domain (part of the 'standard' Samba 686 * server signature). 1153 * Can't use sync call while an async call is in flight 687 1154 */ 688 if (p < end_of_buf) { 689 p += clistr_pull(cli->inbuf, cli->server_domain, p, sizeof(fstring), 690 -1, STR_TERMINATE); 691 } 692 } else { 693 /* 694 * No room to null terminate so we can't see if there 695 * is another string (server_domain) afterwards. 696 */ 697 p += clistr_pull(cli->inbuf, cli->server_type, p, sizeof(fstring), 698 len, 0); 699 } 700 return blob2; 701 } 702 703 #ifdef HAVE_KRB5 704 /**************************************************************************** 705 Send a extended security session setup blob, returning a reply blob. 706 ****************************************************************************/ 1155 status = NT_STATUS_INVALID_PARAMETER; 1156 goto fail; 1157 } 1158 ev = event_context_init(frame); 1159 if (ev == NULL) { 1160 goto fail; 1161 } 1162 req = cli_session_setup_nt1_send(frame, ev, cli, user, pass, passlen, 1163 ntpass, ntpasslen, workgroup); 1164 if (req == NULL) { 1165 goto fail; 1166 } 1167 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 1168 goto fail; 1169 } 1170 status = cli_session_setup_nt1_recv(req); 1171 fail: 1172 TALLOC_FREE(frame); 1173 if (!NT_STATUS_IS_OK(status)) { 1174 cli_set_error(cli, status); 1175 } 1176 return status; 1177 } 707 1178 708 1179 /* The following is calculated from : … … 715 1186 #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22) 716 1187 717 static bool cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) 718 { 719 int32 remaining = blob.length; 720 int32 cur = 0; 721 DATA_BLOB send_blob = data_blob_null; 722 int32 max_blob_size = 0; 723 DATA_BLOB receive_blob = data_blob_null; 1188 struct cli_sesssetup_blob_state { 1189 struct tevent_context *ev; 1190 struct cli_state *cli; 1191 DATA_BLOB blob; 1192 uint16_t max_blob_size; 1193 uint16_t vwv[12]; 1194 uint8_t *buf; 1195 1196 NTSTATUS status; 1197 char *inbuf; 1198 DATA_BLOB ret_blob; 1199 }; 1200 1201 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state, 1202 struct tevent_req **psubreq); 1203 static void cli_sesssetup_blob_done(struct tevent_req *subreq); 1204 1205 static struct tevent_req *cli_sesssetup_blob_send(TALLOC_CTX *mem_ctx, 1206 struct tevent_context *ev, 1207 struct cli_state *cli, 1208 DATA_BLOB blob) 1209 { 1210 struct tevent_req *req, *subreq; 1211 struct cli_sesssetup_blob_state *state; 1212 1213 req = tevent_req_create(mem_ctx, &state, 1214 struct cli_sesssetup_blob_state); 1215 if (req == NULL) { 1216 return NULL; 1217 } 1218 state->ev = ev; 1219 state->blob = blob; 1220 state->cli = cli; 724 1221 725 1222 if (cli->max_xmit < BASE_SESSSETUP_BLOB_PACKET_SIZE + 1) { 726 DEBUG(0,("cli_session_setup_blob: cli->max_xmit too small " 727 "(was %u, need minimum %u)\n", 728 (unsigned int)cli->max_xmit, 729 BASE_SESSSETUP_BLOB_PACKET_SIZE)); 730 cli_set_nt_error(cli, NT_STATUS_INVALID_PARAMETER); 731 return False; 732 } 733 734 max_blob_size = cli->max_xmit - BASE_SESSSETUP_BLOB_PACKET_SIZE; 735 736 while ( remaining > 0) { 737 if (remaining >= max_blob_size) { 738 send_blob.length = max_blob_size; 739 remaining -= max_blob_size; 740 } else { 741 send_blob.length = remaining; 742 remaining = 0; 743 } 744 745 send_blob.data = &blob.data[cur]; 746 cur += send_blob.length; 747 748 DEBUG(10, ("cli_session_setup_blob: Remaining (%u) sending (%u) current (%u)\n", 749 (unsigned int)remaining, 750 (unsigned int)send_blob.length, 751 (unsigned int)cur )); 752 753 if (!cli_session_setup_blob_send(cli, send_blob)) { 754 DEBUG(0, ("cli_session_setup_blob: send failed\n")); 755 return False; 756 } 757 758 receive_blob = cli_session_setup_blob_receive(cli); 759 data_blob_free(&receive_blob); 760 761 if (cli_is_error(cli) && 762 !NT_STATUS_EQUAL( cli_get_nt_error(cli), 763 NT_STATUS_MORE_PROCESSING_REQUIRED)) { 764 DEBUG(0, ("cli_session_setup_blob: receive failed " 765 "(%s)\n", nt_errstr(cli_get_nt_error(cli)))); 766 cli->vuid = 0; 767 return False; 768 } 769 } 770 771 return True; 772 } 1223 DEBUG(1, ("cli_session_setup_blob: cli->max_xmit too small " 1224 "(was %u, need minimum %u)\n", 1225 (unsigned int)cli->max_xmit, 1226 BASE_SESSSETUP_BLOB_PACKET_SIZE)); 1227 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); 1228 return tevent_req_post(req, ev); 1229 } 1230 state->max_blob_size = 1231 MIN(cli->max_xmit - BASE_SESSSETUP_BLOB_PACKET_SIZE, 0xFFFF); 1232 1233 if (!cli_sesssetup_blob_next(state, &subreq)) { 1234 tevent_req_nterror(req, NT_STATUS_NO_MEMORY); 1235 return tevent_req_post(req, ev); 1236 } 1237 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req); 1238 return req; 1239 } 1240 1241 static bool cli_sesssetup_blob_next(struct cli_sesssetup_blob_state *state, 1242 struct tevent_req **psubreq) 1243 { 1244 struct tevent_req *subreq; 1245 uint16_t thistime; 1246 1247 SCVAL(state->vwv+0, 0, 0xFF); 1248 SCVAL(state->vwv+0, 1, 0); 1249 SSVAL(state->vwv+1, 0, 0); 1250 SSVAL(state->vwv+2, 0, CLI_BUFFER_SIZE); 1251 SSVAL(state->vwv+3, 0, 2); 1252 SSVAL(state->vwv+4, 0, 1); 1253 SIVAL(state->vwv+5, 0, 0); 1254 1255 thistime = MIN(state->blob.length, state->max_blob_size); 1256 SSVAL(state->vwv+7, 0, thistime); 1257 1258 SSVAL(state->vwv+8, 0, 0); 1259 SSVAL(state->vwv+9, 0, 0); 1260 SIVAL(state->vwv+10, 0, 1261 cli_session_setup_capabilities(state->cli) 1262 | CAP_EXTENDED_SECURITY); 1263 1264 state->buf = (uint8_t *)talloc_memdup(state, state->blob.data, 1265 thistime); 1266 if (state->buf == NULL) { 1267 return false; 1268 } 1269 state->blob.data += thistime; 1270 state->blob.length -= thistime; 1271 1272 state->buf = smb_bytes_push_str(state->buf, cli_ucs2(state->cli), 1273 "Unix", 5, NULL); 1274 state->buf = smb_bytes_push_str(state->buf, cli_ucs2(state->cli), 1275 "Samba", 6, NULL); 1276 if (state->buf == NULL) { 1277 return false; 1278 } 1279 subreq = cli_smb_send(state, state->ev, state->cli, SMBsesssetupX, 0, 1280 12, state->vwv, 1281 talloc_get_size(state->buf), state->buf); 1282 if (subreq == NULL) { 1283 return false; 1284 } 1285 *psubreq = subreq; 1286 return true; 1287 } 1288 1289 static void cli_sesssetup_blob_done(struct tevent_req *subreq) 1290 { 1291 struct tevent_req *req = tevent_req_callback_data( 1292 subreq, struct tevent_req); 1293 struct cli_sesssetup_blob_state *state = tevent_req_data( 1294 req, struct cli_sesssetup_blob_state); 1295 struct cli_state *cli = state->cli; 1296 uint8_t wct; 1297 uint16_t *vwv; 1298 uint32_t num_bytes; 1299 uint8_t *bytes; 1300 NTSTATUS status; 1301 uint8_t *p; 1302 uint16_t blob_length; 1303 uint8_t *inbuf; 1304 ssize_t ret; 1305 1306 status = cli_smb_recv(subreq, state, &inbuf, 4, &wct, &vwv, 1307 &num_bytes, &bytes); 1308 TALLOC_FREE(subreq); 1309 if (!NT_STATUS_IS_OK(status) 1310 && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 1311 tevent_req_nterror(req, status); 1312 return; 1313 } 1314 1315 state->status = status; 1316 TALLOC_FREE(state->buf); 1317 1318 state->inbuf = (char *)inbuf; 1319 cli->vuid = SVAL(state->inbuf, smb_uid); 1320 cli->is_guestlogin = ((SVAL(vwv+2, 0) & 1) != 0); 1321 1322 blob_length = SVAL(vwv+3, 0); 1323 if (blob_length > num_bytes) { 1324 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); 1325 return; 1326 } 1327 state->ret_blob = data_blob_const(bytes, blob_length); 1328 1329 p = bytes + blob_length; 1330 1331 status = smb_bytes_talloc_string(cli, 1332 (char *)inbuf, 1333 &cli->server_os, 1334 p, 1335 bytes+num_bytes-p, 1336 &ret); 1337 1338 if (!NT_STATUS_IS_OK(status)) { 1339 tevent_req_nterror(req, status); 1340 return; 1341 } 1342 p += ret; 1343 1344 status = smb_bytes_talloc_string(cli, 1345 (char *)inbuf, 1346 &cli->server_type, 1347 p, 1348 bytes+num_bytes-p, 1349 &ret); 1350 1351 if (!NT_STATUS_IS_OK(status)) { 1352 tevent_req_nterror(req, status); 1353 return; 1354 } 1355 p += ret; 1356 1357 status = smb_bytes_talloc_string(cli, 1358 (char *)inbuf, 1359 &cli->server_domain, 1360 p, 1361 bytes+num_bytes-p, 1362 &ret); 1363 1364 if (!NT_STATUS_IS_OK(status)) { 1365 tevent_req_nterror(req, status); 1366 return; 1367 } 1368 p += ret; 1369 1370 if (strstr(cli->server_type, "Samba")) { 1371 cli->is_samba = True; 1372 } 1373 1374 if (state->blob.length != 0) { 1375 /* 1376 * More to send 1377 */ 1378 if (!cli_sesssetup_blob_next(state, &subreq)) { 1379 tevent_req_nomem(NULL, req); 1380 return; 1381 } 1382 tevent_req_set_callback(subreq, cli_sesssetup_blob_done, req); 1383 return; 1384 } 1385 tevent_req_done(req); 1386 } 1387 1388 static NTSTATUS cli_sesssetup_blob_recv(struct tevent_req *req, 1389 TALLOC_CTX *mem_ctx, 1390 DATA_BLOB *pblob, 1391 char **pinbuf) 1392 { 1393 struct cli_sesssetup_blob_state *state = tevent_req_data( 1394 req, struct cli_sesssetup_blob_state); 1395 NTSTATUS status; 1396 char *inbuf; 1397 1398 if (tevent_req_is_nterror(req, &status)) { 1399 state->cli->vuid = 0; 1400 return status; 1401 } 1402 1403 inbuf = talloc_move(mem_ctx, &state->inbuf); 1404 if (pblob != NULL) { 1405 *pblob = state->ret_blob; 1406 } 1407 if (pinbuf != NULL) { 1408 *pinbuf = inbuf; 1409 } 1410 /* could be NT_STATUS_MORE_PROCESSING_REQUIRED */ 1411 return state->status; 1412 } 1413 1414 #ifdef HAVE_KRB5 773 1415 774 1416 /**************************************************************************** … … 784 1426 ****************************************************************************/ 785 1427 786 st atic ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli, const char *principal, const char *workgroup)787 { 1428 struct cli_session_setup_kerberos_state { 1429 struct cli_state *cli; 788 1430 DATA_BLOB negTokenTarg; 789 1431 DATA_BLOB session_key_krb5; 790 NTSTATUS nt_status; 1432 ADS_STATUS ads_status; 1433 }; 1434 1435 static void cli_session_setup_kerberos_done(struct tevent_req *subreq); 1436 1437 static struct tevent_req *cli_session_setup_kerberos_send( 1438 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli, 1439 const char *principal, const char *workgroup) 1440 { 1441 struct tevent_req *req, *subreq; 1442 struct cli_session_setup_kerberos_state *state; 791 1443 int rc; 792 1444 1445 DEBUG(2,("Doing kerberos session setup\n")); 1446 1447 req = tevent_req_create(mem_ctx, &state, 1448 struct cli_session_setup_kerberos_state); 1449 if (req == NULL) { 1450 return NULL; 1451 } 1452 state->cli = cli; 1453 state->ads_status = ADS_SUCCESS; 1454 793 1455 cli_temp_set_signing(cli); 794 1456 795 DEBUG(2,("Doing kerberos session setup\n")); 796 797 /* generate the encapsulated kerberos5 ticket */ 798 rc = spnego_gen_negTokenTarg(principal, 0, &negTokenTarg, &session_key_krb5, 0, NULL); 799 1457 /* 1458 * Ok, this is cheating: spnego_gen_krb5_negTokenInit can block if 1459 * we have to acquire a ticket. To be fixed later :-) 1460 */ 1461 rc = spnego_gen_krb5_negTokenInit(state, principal, 0, &state->negTokenTarg, 1462 &state->session_key_krb5, 0, NULL); 800 1463 if (rc) { 801 DEBUG(1, ("cli_session_setup_kerberos: spnego_gen_negTokenTarg failed: %s\n", 802 error_message(rc))); 803 return ADS_ERROR_KRB5(rc); 1464 DEBUG(1, ("cli_session_setup_kerberos: " 1465 "spnego_gen_krb5_negTokenInit failed: %s\n", 1466 error_message(rc))); 1467 state->ads_status = ADS_ERROR_KRB5(rc); 1468 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL); 1469 return tevent_req_post(req, ev); 804 1470 } 805 1471 806 1472 #if 0 807 file_save("negTokenTarg.dat", negTokenTarg.data, negTokenTarg.length); 1473 file_save("negTokenTarg.dat", state->negTokenTarg.data, 1474 state->negTokenTarg.length); 808 1475 #endif 809 1476 810 if (!cli_session_setup_blob(cli, negTokenTarg)) { 811 nt_status = cli_nt_error(cli); 812 goto nt_error; 813 } 814 815 if (cli_is_error(cli)) { 816 nt_status = cli_nt_error(cli); 817 if (NT_STATUS_IS_OK(nt_status)) { 818 nt_status = NT_STATUS_UNSUCCESSFUL; 819 } 820 goto nt_error; 821 } 822 823 cli_set_session_key(cli, session_key_krb5); 824 825 if (cli_simple_set_signing( 826 cli, session_key_krb5, data_blob_null)) { 827 828 if (!cli_check_sign_mac(cli, cli->inbuf, 1)) { 829 nt_status = NT_STATUS_ACCESS_DENIED; 830 goto nt_error; 831 } 832 } 833 834 data_blob_free(&negTokenTarg); 835 data_blob_free(&session_key_krb5); 836 837 return ADS_ERROR_NT(NT_STATUS_OK); 838 839 nt_error: 840 data_blob_free(&negTokenTarg); 841 data_blob_free(&session_key_krb5); 842 cli->vuid = 0; 843 return ADS_ERROR_NT(nt_status); 1477 subreq = cli_sesssetup_blob_send(state, ev, cli, state->negTokenTarg); 1478 if (tevent_req_nomem(subreq, req)) { 1479 return tevent_req_post(req, ev); 1480 } 1481 tevent_req_set_callback(subreq, cli_session_setup_kerberos_done, req); 1482 return req; 1483 } 1484 1485 static void cli_session_setup_kerberos_done(struct tevent_req *subreq) 1486 { 1487 struct tevent_req *req = tevent_req_callback_data( 1488 subreq, struct tevent_req); 1489 struct cli_session_setup_kerberos_state *state = tevent_req_data( 1490 req, struct cli_session_setup_kerberos_state); 1491 char *inbuf = NULL; 1492 NTSTATUS status; 1493 1494 status = cli_sesssetup_blob_recv(subreq, talloc_tos(), NULL, &inbuf); 1495 if (!NT_STATUS_IS_OK(status)) { 1496 TALLOC_FREE(subreq); 1497 tevent_req_nterror(req, status); 1498 return; 1499 } 1500 1501 cli_set_session_key(state->cli, state->session_key_krb5); 1502 1503 if (cli_simple_set_signing(state->cli, state->session_key_krb5, 1504 data_blob_null) 1505 && !cli_check_sign_mac(state->cli, inbuf, 1)) { 1506 TALLOC_FREE(subreq); 1507 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); 1508 return; 1509 } 1510 TALLOC_FREE(subreq); 1511 tevent_req_done(req); 1512 } 1513 1514 static ADS_STATUS cli_session_setup_kerberos_recv(struct tevent_req *req) 1515 { 1516 struct cli_session_setup_kerberos_state *state = tevent_req_data( 1517 req, struct cli_session_setup_kerberos_state); 1518 NTSTATUS status; 1519 1520 if (tevent_req_is_nterror(req, &status)) { 1521 return ADS_ERROR_NT(status); 1522 } 1523 return state->ads_status; 1524 } 1525 1526 static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli, 1527 const char *principal, 1528 const char *workgroup) 1529 { 1530 struct tevent_context *ev; 1531 struct tevent_req *req; 1532 ADS_STATUS status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); 1533 1534 if (cli_has_async_calls(cli)) { 1535 return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); 1536 } 1537 ev = tevent_context_init(talloc_tos()); 1538 if (ev == NULL) { 1539 goto fail; 1540 } 1541 req = cli_session_setup_kerberos_send(ev, ev, cli, principal, 1542 workgroup); 1543 if (req == NULL) { 1544 goto fail; 1545 } 1546 if (!tevent_req_poll(req, ev)) { 1547 status = ADS_ERROR_SYSTEM(errno); 1548 goto fail; 1549 } 1550 status = cli_session_setup_kerberos_recv(req); 1551 fail: 1552 TALLOC_FREE(ev); 1553 return status; 844 1554 } 845 1555 #endif /* HAVE_KRB5 */ 846 847 1556 848 1557 /**************************************************************************** … … 850 1559 ****************************************************************************/ 851 1560 852 st atic NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *user,853 const char *pass, const char *domain)854 { 1561 struct cli_session_setup_ntlmssp_state { 1562 struct tevent_context *ev; 1563 struct cli_state *cli; 855 1564 struct ntlmssp_state *ntlmssp_state; 856 NTSTATUS nt_status; 857 int turn = 1; 858 DATA_BLOB msg1; 859 DATA_BLOB blob = data_blob_null; 860 DATA_BLOB blob_in = data_blob_null; 861 DATA_BLOB blob_out = data_blob_null; 1565 int turn; 1566 DATA_BLOB blob_out; 1567 }; 1568 1569 static int cli_session_setup_ntlmssp_state_destructor( 1570 struct cli_session_setup_ntlmssp_state *state) 1571 { 1572 if (state->ntlmssp_state != NULL) { 1573 TALLOC_FREE(state->ntlmssp_state); 1574 } 1575 return 0; 1576 } 1577 1578 static void cli_session_setup_ntlmssp_done(struct tevent_req *req); 1579 1580 static struct tevent_req *cli_session_setup_ntlmssp_send( 1581 TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli, 1582 const char *user, const char *pass, const char *domain) 1583 { 1584 struct tevent_req *req, *subreq; 1585 struct cli_session_setup_ntlmssp_state *state; 1586 NTSTATUS status; 1587 DATA_BLOB blob_out; 1588 const char *OIDs_ntlm[] = {OID_NTLMSSP, NULL}; 1589 1590 req = tevent_req_create(mem_ctx, &state, 1591 struct cli_session_setup_ntlmssp_state); 1592 if (req == NULL) { 1593 return NULL; 1594 } 1595 state->ev = ev; 1596 state->cli = cli; 1597 state->turn = 1; 1598 1599 state->ntlmssp_state = NULL; 1600 talloc_set_destructor( 1601 state, cli_session_setup_ntlmssp_state_destructor); 862 1602 863 1603 cli_temp_set_signing(cli); 864 1604 865 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_client_start(&ntlmssp_state))) { 866 return nt_status; 867 } 868 ntlmssp_want_feature(ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY); 1605 status = ntlmssp_client_start(state, 1606 global_myname(), 1607 lp_workgroup(), 1608 lp_client_ntlmv2_auth(), 1609 &state->ntlmssp_state); 1610 if (!NT_STATUS_IS_OK(status)) { 1611 goto fail; 1612 } 1613 ntlmssp_want_feature(state->ntlmssp_state, 1614 NTLMSSP_FEATURE_SESSION_KEY); 869 1615 if (cli->use_ccache) { 870 ntlmssp_want_feature(ntlmssp_state, NTLMSSP_FEATURE_CCACHE); 871 } 872 873 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) { 874 return nt_status; 875 } 876 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) { 877 return nt_status; 878 } 879 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_password(ntlmssp_state, pass))) { 880 return nt_status; 881 } 882 883 do { 884 nt_status = ntlmssp_update(ntlmssp_state, 885 blob_in, &blob_out); 886 data_blob_free(&blob_in); 887 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) || NT_STATUS_IS_OK(nt_status)) { 888 if (turn == 1) { 889 /* and wrap it in a SPNEGO wrapper */ 890 msg1 = gen_negTokenInit(OID_NTLMSSP, blob_out); 891 } else { 892 /* wrap it in SPNEGO */ 893 msg1 = spnego_gen_auth(blob_out); 1616 ntlmssp_want_feature(state->ntlmssp_state, 1617 NTLMSSP_FEATURE_CCACHE); 1618 } 1619 status = ntlmssp_set_username(state->ntlmssp_state, user); 1620 if (!NT_STATUS_IS_OK(status)) { 1621 goto fail; 1622 } 1623 status = ntlmssp_set_domain(state->ntlmssp_state, domain); 1624 if (!NT_STATUS_IS_OK(status)) { 1625 goto fail; 1626 } 1627 status = ntlmssp_set_password(state->ntlmssp_state, pass); 1628 if (!NT_STATUS_IS_OK(status)) { 1629 goto fail; 1630 } 1631 status = ntlmssp_update(state->ntlmssp_state, data_blob_null, 1632 &blob_out); 1633 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 1634 goto fail; 1635 } 1636 1637 state->blob_out = spnego_gen_negTokenInit(state, OIDs_ntlm, &blob_out, NULL); 1638 data_blob_free(&blob_out); 1639 1640 subreq = cli_sesssetup_blob_send(state, ev, cli, state->blob_out); 1641 if (tevent_req_nomem(subreq, req)) { 1642 return tevent_req_post(req, ev); 1643 } 1644 tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req); 1645 return req; 1646 fail: 1647 tevent_req_nterror(req, status); 1648 return tevent_req_post(req, ev); 1649 } 1650 1651 static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq) 1652 { 1653 struct tevent_req *req = tevent_req_callback_data( 1654 subreq, struct tevent_req); 1655 struct cli_session_setup_ntlmssp_state *state = tevent_req_data( 1656 req, struct cli_session_setup_ntlmssp_state); 1657 DATA_BLOB blob_in, msg_in, blob_out; 1658 char *inbuf = NULL; 1659 bool parse_ret; 1660 NTSTATUS status; 1661 1662 status = cli_sesssetup_blob_recv(subreq, talloc_tos(), &blob_in, 1663 &inbuf); 1664 TALLOC_FREE(subreq); 1665 data_blob_free(&state->blob_out); 1666 1667 if (NT_STATUS_IS_OK(status)) { 1668 if (state->cli->server_domain[0] == '\0') { 1669 TALLOC_FREE(state->cli->server_domain); 1670 state->cli->server_domain = talloc_strdup(state->cli, 1671 state->ntlmssp_state->server.netbios_domain); 1672 if (state->cli->server_domain == NULL) { 1673 TALLOC_FREE(subreq); 1674 tevent_req_nterror(req, NT_STATUS_NO_MEMORY); 1675 return; 894 1676 } 895 896 /* now send that blob on its way */ 897 if (!cli_session_setup_blob_send(cli, msg1)) { 898 DEBUG(3, ("Failed to send NTLMSSP/SPNEGO blob to server!\n")); 899 nt_status = NT_STATUS_UNSUCCESSFUL; 900 } else { 901 blob = cli_session_setup_blob_receive(cli); 902 903 nt_status = cli_nt_error(cli); 904 if (cli_is_error(cli) && NT_STATUS_IS_OK(nt_status)) { 905 if (cli->smb_rw_error == SMB_READ_BAD_SIG) { 906 nt_status = NT_STATUS_ACCESS_DENIED; 907 } else { 908 nt_status = NT_STATUS_UNSUCCESSFUL; 909 } 910 } 911 } 912 data_blob_free(&msg1); 913 } 914 915 if (!blob.length) { 916 if (NT_STATUS_IS_OK(nt_status)) { 917 nt_status = NT_STATUS_UNSUCCESSFUL; 918 } 919 } else if ((turn == 1) && 920 NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 921 DATA_BLOB tmp_blob = data_blob_null; 922 /* the server might give us back two challenges */ 923 if (!spnego_parse_challenge(blob, &blob_in, 924 &tmp_blob)) { 925 DEBUG(3,("Failed to parse challenges\n")); 926 nt_status = NT_STATUS_INVALID_PARAMETER; 927 } 928 data_blob_free(&tmp_blob); 929 } else { 930 if (!spnego_parse_auth_response(blob, nt_status, OID_NTLMSSP, 931 &blob_in)) { 932 DEBUG(3,("Failed to parse auth response\n")); 933 if (NT_STATUS_IS_OK(nt_status) 934 || NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) 935 nt_status = NT_STATUS_INVALID_PARAMETER; 936 } 937 } 938 data_blob_free(&blob); 939 data_blob_free(&blob_out); 940 turn++; 941 } while (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)); 942 943 data_blob_free(&blob_in); 944 945 if (NT_STATUS_IS_OK(nt_status)) { 946 947 if (cli->server_domain[0] == '\0') { 948 fstrcpy(cli->server_domain, ntlmssp_state->server_domain); 949 } 950 cli_set_session_key(cli, ntlmssp_state->session_key); 1677 } 1678 cli_set_session_key( 1679 state->cli, state->ntlmssp_state->session_key); 951 1680 952 1681 if (cli_simple_set_signing( 953 cli, ntlmssp_state->session_key, data_blob_null)) { 954 955 if (!cli_check_sign_mac(cli, cli->inbuf, 1)) { 956 nt_status = NT_STATUS_ACCESS_DENIED; 957 } 958 } 959 } 960 961 /* we have a reference conter on ntlmssp_state, if we are signing 962 then the state will be kept by the signing engine */ 963 964 ntlmssp_end(&ntlmssp_state); 965 966 if (!NT_STATUS_IS_OK(nt_status)) { 967 cli->vuid = 0; 968 } 969 return nt_status; 1682 state->cli, state->ntlmssp_state->session_key, 1683 data_blob_null) 1684 && !cli_check_sign_mac(state->cli, inbuf, 1)) { 1685 TALLOC_FREE(subreq); 1686 tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); 1687 return; 1688 } 1689 TALLOC_FREE(subreq); 1690 TALLOC_FREE(state->ntlmssp_state); 1691 tevent_req_done(req); 1692 return; 1693 } 1694 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 1695 tevent_req_nterror(req, status); 1696 return; 1697 } 1698 1699 if (blob_in.length == 0) { 1700 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL); 1701 return; 1702 } 1703 1704 if ((state->turn == 1) 1705 && NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 1706 DATA_BLOB tmp_blob = data_blob_null; 1707 /* the server might give us back two challenges */ 1708 parse_ret = spnego_parse_challenge(state, blob_in, &msg_in, 1709 &tmp_blob); 1710 data_blob_free(&tmp_blob); 1711 } else { 1712 parse_ret = spnego_parse_auth_response(state, blob_in, status, 1713 OID_NTLMSSP, &msg_in); 1714 } 1715 state->turn += 1; 1716 1717 if (!parse_ret) { 1718 DEBUG(3,("Failed to parse auth response\n")); 1719 if (NT_STATUS_IS_OK(status) 1720 || NT_STATUS_EQUAL(status, 1721 NT_STATUS_MORE_PROCESSING_REQUIRED)) { 1722 tevent_req_nterror( 1723 req, NT_STATUS_INVALID_NETWORK_RESPONSE); 1724 return; 1725 } 1726 } 1727 1728 status = ntlmssp_update(state->ntlmssp_state, msg_in, &blob_out); 1729 1730 if (!NT_STATUS_IS_OK(status) 1731 && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 1732 TALLOC_FREE(subreq); 1733 TALLOC_FREE(state->ntlmssp_state); 1734 tevent_req_nterror(req, status); 1735 return; 1736 } 1737 1738 state->blob_out = spnego_gen_auth(state, blob_out); 1739 TALLOC_FREE(subreq); 1740 if (tevent_req_nomem(state->blob_out.data, req)) { 1741 return; 1742 } 1743 1744 subreq = cli_sesssetup_blob_send(state, state->ev, state->cli, 1745 state->blob_out); 1746 if (tevent_req_nomem(subreq, req)) { 1747 return; 1748 } 1749 tevent_req_set_callback(subreq, cli_session_setup_ntlmssp_done, req); 1750 } 1751 1752 static NTSTATUS cli_session_setup_ntlmssp_recv(struct tevent_req *req) 1753 { 1754 struct cli_session_setup_ntlmssp_state *state = tevent_req_data( 1755 req, struct cli_session_setup_ntlmssp_state); 1756 NTSTATUS status; 1757 1758 if (tevent_req_is_nterror(req, &status)) { 1759 state->cli->vuid = 0; 1760 return status; 1761 } 1762 return NT_STATUS_OK; 1763 } 1764 1765 static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, 1766 const char *user, 1767 const char *pass, 1768 const char *domain) 1769 { 1770 struct tevent_context *ev; 1771 struct tevent_req *req; 1772 NTSTATUS status = NT_STATUS_NO_MEMORY; 1773 1774 if (cli_has_async_calls(cli)) { 1775 return NT_STATUS_INVALID_PARAMETER; 1776 } 1777 ev = tevent_context_init(talloc_tos()); 1778 if (ev == NULL) { 1779 goto fail; 1780 } 1781 req = cli_session_setup_ntlmssp_send(ev, ev, cli, user, pass, domain); 1782 if (req == NULL) { 1783 goto fail; 1784 } 1785 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 1786 goto fail; 1787 } 1788 status = cli_session_setup_ntlmssp_recv(req); 1789 fail: 1790 TALLOC_FREE(ev); 1791 if (!NT_STATUS_IS_OK(status)) { 1792 cli_set_error(cli, status); 1793 } 1794 return status; 970 1795 } 971 1796 … … 1008 1833 * negprot reply, but right now we do it. If we don't receive one, 1009 1834 * we try to best guess, then fall back to NTLM. */ 1010 if (!spnego_parse_negTokenInit( blob, OIDs, &principal) ||1835 if (!spnego_parse_negTokenInit(talloc_tos(), blob, OIDs, &principal, NULL) || 1011 1836 OIDs[0] == NULL) { 1012 1837 data_blob_free(&blob); … … 1032 1857 status = cli_set_username(cli, user); 1033 1858 if (!NT_STATUS_IS_OK(status)) { 1859 TALLOC_FREE(principal); 1034 1860 return ADS_ERROR_NT(status); 1035 1861 } … … 1075 1901 if (dest_realm) { 1076 1902 realm = SMB_STRDUP(dest_realm); 1903 if (!realm) { 1904 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); 1905 } 1077 1906 strupper_m(realm); 1078 1907 } else { … … 1086 1915 } 1087 1916 1088 if (realm && *realm) { 1089 principal = talloc_asprintf(talloc_tos(), 1090 "cifs/%s@%s", 1091 cli->desthost, 1092 realm); 1093 if (!principal) { 1094 SAFE_FREE(realm); 1917 if (realm == NULL || *realm == '\0') { 1918 realm = SMB_STRDUP(lp_realm()); 1919 if (!realm) { 1095 1920 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); 1096 1921 } 1097 DEBUG(3,("cli_session_setup_spnego: guessed " 1098 "server principal=%s\n", 1099 principal ? principal : "<null>")); 1922 strupper_m(realm); 1923 DEBUG(3,("cli_session_setup_spnego: cannot " 1924 "get realm from dest_realm %s, " 1925 "desthost %s. Using default " 1926 "smb.conf realm %s\n", 1927 dest_realm ? dest_realm : "<null>", 1928 cli->desthost, 1929 realm)); 1100 1930 } 1931 1932 principal = talloc_asprintf(talloc_tos(), 1933 "cifs/%s@%s", 1934 cli->desthost, 1935 realm); 1936 if (!principal) { 1937 SAFE_FREE(realm); 1938 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); 1939 } 1940 DEBUG(3,("cli_session_setup_spnego: guessed " 1941 "server principal=%s\n", 1942 principal ? principal : "<null>")); 1943 1101 1944 SAFE_FREE(realm); 1102 1945 } … … 1145 1988 { 1146 1989 char *p; 1147 fstringuser2;1990 char *user2; 1148 1991 1149 1992 if (user) { 1150 fstrcpy(user2, user);1993 user2 = talloc_strdup(talloc_tos(), user); 1151 1994 } else { 1152 user2[0] ='\0'; 1995 user2 = talloc_strdup(talloc_tos(), ""); 1996 } 1997 if (user2 == NULL) { 1998 return NT_STATUS_NO_MEMORY; 1153 1999 } 1154 2000 … … 1162 2008 *p = 0; 1163 2009 user = p+1; 2010 strupper_m(user2); 1164 2011 workgroup = user2; 1165 2012 } … … 1177 2024 if (cli->protocol < PROTOCOL_NT1) { 1178 2025 if (!lp_client_lanman_auth() && passlen != 24 && (*pass)) { 1179 DEBUG(1, ("Server requested LM password but 'client lanman auth '"1180 " is disabled\n"));2026 DEBUG(1, ("Server requested LM password but 'client lanman auth = no'" 2027 " or 'client ntlmv2 auth = yes'\n")); 1181 2028 return NT_STATUS_ACCESS_DENIED; 1182 2029 } … … 1184 2031 if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 && 1185 2032 !lp_client_plaintext_auth() && (*pass)) { 1186 DEBUG(1, ("Server requested plaintext password but"1187 " 'client plaintext auth' is disabled\n"));2033 DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'" 2034 " or 'client ntlmv2 auth = yes'\n")); 1188 2035 return NT_STATUS_ACCESS_DENIED; 1189 2036 } … … 1204 2051 1205 2052 if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) 1206 return cli_session_setup_plain text(cli, user, "", workgroup);2053 return cli_session_setup_plain(cli, user, "", workgroup); 1207 2054 1208 2055 /* if the server doesn't support encryption then we have to use … … 1211 2058 if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) { 1212 2059 if (!lp_client_plaintext_auth() && (*pass)) { 1213 DEBUG(1, ("Server requested plaintext password but"1214 " 'client plaintext auth' is disabled\n"));2060 DEBUG(1, ("Server requested LM password but 'client plaintext auth = no'" 2061 " or 'client ntlmv2 auth = yes'\n")); 1215 2062 return NT_STATUS_ACCESS_DENIED; 1216 2063 } 1217 return cli_session_setup_plain text(cli, user, pass, workgroup);2064 return cli_session_setup_plain(cli, user, pass, workgroup); 1218 2065 } 1219 2066 … … 1251 2098 *****************************************************************************/ 1252 2099 1253 bool cli_ulogoff(struct cli_state *cli) 1254 { 1255 memset(cli->outbuf,'\0',smb_size); 1256 cli_set_message(cli->outbuf,2,0,True); 1257 SCVAL(cli->outbuf,smb_com,SMBulogoffX); 1258 cli_setup_packet(cli); 1259 SSVAL(cli->outbuf,smb_vwv0,0xFF); 1260 SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */ 1261 1262 cli_send_smb(cli); 1263 if (!cli_receive_smb(cli)) 1264 return False; 1265 1266 if (cli_is_error(cli)) { 1267 return False; 1268 } 1269 1270 cli->vuid = -1; 1271 return True; 2100 struct cli_ulogoff_state { 2101 struct cli_state *cli; 2102 uint16_t vwv[3]; 2103 }; 2104 2105 static void cli_ulogoff_done(struct tevent_req *subreq); 2106 2107 struct tevent_req *cli_ulogoff_send(TALLOC_CTX *mem_ctx, 2108 struct tevent_context *ev, 2109 struct cli_state *cli) 2110 { 2111 struct tevent_req *req, *subreq; 2112 struct cli_ulogoff_state *state; 2113 2114 req = tevent_req_create(mem_ctx, &state, struct cli_ulogoff_state); 2115 if (req == NULL) { 2116 return NULL; 2117 } 2118 state->cli = cli; 2119 2120 SCVAL(state->vwv+0, 0, 0xFF); 2121 SCVAL(state->vwv+1, 0, 0); 2122 SSVAL(state->vwv+2, 0, 0); 2123 2124 subreq = cli_smb_send(state, ev, cli, SMBulogoffX, 0, 2, state->vwv, 2125 0, NULL); 2126 if (tevent_req_nomem(subreq, req)) { 2127 return tevent_req_post(req, ev); 2128 } 2129 tevent_req_set_callback(subreq, cli_ulogoff_done, req); 2130 return req; 2131 } 2132 2133 static void cli_ulogoff_done(struct tevent_req *subreq) 2134 { 2135 struct tevent_req *req = tevent_req_callback_data( 2136 subreq, struct tevent_req); 2137 struct cli_ulogoff_state *state = tevent_req_data( 2138 req, struct cli_ulogoff_state); 2139 NTSTATUS status; 2140 2141 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); 2142 if (!NT_STATUS_IS_OK(status)) { 2143 tevent_req_nterror(req, status); 2144 return; 2145 } 2146 state->cli->vuid = -1; 2147 tevent_req_done(req); 2148 } 2149 2150 NTSTATUS cli_ulogoff_recv(struct tevent_req *req) 2151 { 2152 return tevent_req_simple_recv_ntstatus(req); 2153 } 2154 2155 NTSTATUS cli_ulogoff(struct cli_state *cli) 2156 { 2157 struct tevent_context *ev; 2158 struct tevent_req *req; 2159 NTSTATUS status = NT_STATUS_NO_MEMORY; 2160 2161 if (cli_has_async_calls(cli)) { 2162 return NT_STATUS_INVALID_PARAMETER; 2163 } 2164 ev = tevent_context_init(talloc_tos()); 2165 if (ev == NULL) { 2166 goto fail; 2167 } 2168 req = cli_ulogoff_send(ev, ev, cli); 2169 if (req == NULL) { 2170 goto fail; 2171 } 2172 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 2173 goto fail; 2174 } 2175 status = cli_ulogoff_recv(req); 2176 fail: 2177 TALLOC_FREE(ev); 2178 if (!NT_STATUS_IS_OK(status)) { 2179 cli_set_error(cli, status); 2180 } 2181 return status; 1272 2182 } 1273 2183 … … 1293 2203 struct tevent_req *req, *subreq; 1294 2204 struct cli_tcon_andx_state *state; 1295 fstring pword;2205 uint8_t p24[24]; 1296 2206 uint16_t *vwv; 1297 2207 char *tmp = NULL; … … 1307 2217 vwv = state->vwv; 1308 2218 1309 fstrcpy(cli->share, share); 2219 cli->share = talloc_strdup(cli, share); 2220 if (!cli->share) { 2221 return NULL; 2222 } 1310 2223 1311 2224 /* in user level security don't send a password now */ … … 1324 2237 DEBUG(1, ("Server requested LANMAN password " 1325 2238 "(share-level security) but " 1326 "'client lanman auth ' is disabled\n"));2239 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n")); 1327 2240 goto access_denied; 1328 2241 } … … 1332 2245 * encryption. 1333 2246 */ 2247 SMBencrypt(pass, cli->secblob.data, p24); 1334 2248 passlen = 24; 1335 SMBencrypt(pass, cli->secblob.data, (uchar *)pword);2249 pass = (const char *)p24; 1336 2250 } else { 1337 2251 if((cli->sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL 1338 2252 |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)) 1339 2253 == 0) { 2254 char *tmp_pass; 2255 1340 2256 if (!lp_client_plaintext_auth() && (*pass)) { 1341 2257 DEBUG(1, ("Server requested plaintext " 1342 "password but 'client plaintext"1343 " auth' is disabled\n"));2258 "password but " 2259 "'client lanman auth = no' or 'client ntlmv2 auth = yes'\n")); 1344 2260 goto access_denied; 1345 2261 } … … 1349 2265 * before using. 1350 2266 */ 1351 passlen = clistr_push(cli, pword, pass, sizeof(pword), 1352 STR_TERMINATE); 2267 tmp_pass = talloc_array(talloc_tos(), char, 128); 2268 if (tmp_pass == NULL) { 2269 tevent_req_nterror(req, NT_STATUS_NO_MEMORY); 2270 return tevent_req_post(req, ev); 2271 } 2272 passlen = clistr_push(cli, 2273 tmp_pass, 2274 pass, 2275 talloc_get_size(tmp_pass), 2276 STR_TERMINATE); 1353 2277 if (passlen == -1) { 1354 DEBUG(1, ("clistr_push(pword) failed\n"));1355 goto access_denied;2278 tevent_req_nterror(req, NT_STATUS_NO_MEMORY); 2279 return tevent_req_post(req, ev); 1356 2280 } 1357 } else { 1358 if (passlen) { 1359 memcpy(pword, pass, passlen); 1360 } 2281 pass = tmp_pass; 1361 2282 } 1362 2283 } … … 1368 2289 SSVAL(vwv+3, 0, passlen); 1369 2290 1370 if (passlen ) {1371 bytes = (uint8_t *)talloc_memdup(state, p word, passlen);2291 if (passlen && pass) { 2292 bytes = (uint8_t *)talloc_memdup(state, pass, passlen); 1372 2293 } else { 1373 2294 bytes = talloc_array(state, uint8_t, 0); … … 1453 2374 req, struct cli_tcon_andx_state); 1454 2375 struct cli_state *cli = state->cli; 1455 char *inbuf = (char *)cli_smb_inbuf(subreq); 2376 uint8_t *in; 2377 char *inbuf; 1456 2378 uint8_t wct; 1457 2379 uint16_t *vwv; … … 1460 2382 NTSTATUS status; 1461 2383 1462 status = cli_smb_recv(subreq, 0, &wct, &vwv, &num_bytes, &bytes); 1463 if (!NT_STATUS_IS_OK(status)) { 1464 TALLOC_FREE(subreq); 2384 status = cli_smb_recv(subreq, state, &in, 0, &wct, &vwv, 2385 &num_bytes, &bytes); 2386 TALLOC_FREE(subreq); 2387 if (!NT_STATUS_IS_OK(status)) { 1465 2388 tevent_req_nterror(req, status); 1466 2389 return; 1467 2390 } 1468 2391 1469 clistr_pull(inbuf, cli->dev, bytes, sizeof(fstring), num_bytes, 1470 STR_TERMINATE|STR_ASCII); 2392 inbuf = (char *)in; 2393 2394 if (num_bytes) { 2395 if (clistr_pull_talloc(cli, 2396 inbuf, 2397 SVAL(inbuf, smb_flg2), 2398 &cli->dev, 2399 bytes, 2400 num_bytes, 2401 STR_TERMINATE|STR_ASCII) == -1) { 2402 tevent_req_nterror(req, NT_STATUS_NO_MEMORY); 2403 return; 2404 } 2405 } else { 2406 cli->dev = talloc_strdup(cli, ""); 2407 if (cli->dev == NULL) { 2408 tevent_req_nterror(req, NT_STATUS_NO_MEMORY); 2409 return; 2410 } 2411 } 1471 2412 1472 2413 if ((cli->protocol >= PROTOCOL_NT1) && (num_bytes == 3)) { … … 1541 2482 ****************************************************************************/ 1542 2483 1543 bool cli_tdis(struct cli_state *cli) 1544 { 1545 memset(cli->outbuf,'\0',smb_size); 1546 cli_set_message(cli->outbuf,0,0,True); 1547 SCVAL(cli->outbuf,smb_com,SMBtdis); 1548 SSVAL(cli->outbuf,smb_tid,cli->cnum); 1549 cli_setup_packet(cli); 1550 1551 cli_send_smb(cli); 1552 if (!cli_receive_smb(cli)) 1553 return False; 1554 1555 if (cli_is_error(cli)) { 1556 return False; 1557 } 1558 1559 cli->cnum = -1; 1560 return True; 1561 } 1562 1563 /**************************************************************************** 1564 Send a negprot command. 1565 ****************************************************************************/ 1566 1567 void cli_negprot_sendsync(struct cli_state *cli) 1568 { 1569 char *p; 1570 int numprots; 1571 1572 if (cli->protocol < PROTOCOL_NT1) 1573 cli->use_spnego = False; 1574 1575 memset(cli->outbuf,'\0',smb_size); 1576 1577 /* setup the protocol strings */ 1578 cli_set_message(cli->outbuf,0,0,True); 1579 1580 p = smb_buf(cli->outbuf); 1581 for (numprots=0; numprots < ARRAY_SIZE(prots); numprots++) { 1582 if (prots[numprots].prot > cli->protocol) { 1583 break; 1584 } 1585 *p++ = 2; 1586 p += clistr_push(cli, p, prots[numprots].name, -1, STR_TERMINATE); 1587 } 1588 1589 SCVAL(cli->outbuf,smb_com,SMBnegprot); 1590 cli_setup_bcc(cli, p); 1591 cli_setup_packet(cli); 1592 1593 SCVAL(smb_buf(cli->outbuf),0,2); 1594 1595 cli_send_smb(cli); 2484 struct cli_tdis_state { 2485 struct cli_state *cli; 2486 }; 2487 2488 static void cli_tdis_done(struct tevent_req *subreq); 2489 2490 struct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx, 2491 struct tevent_context *ev, 2492 struct cli_state *cli) 2493 { 2494 struct tevent_req *req, *subreq; 2495 struct cli_tdis_state *state; 2496 2497 req = tevent_req_create(mem_ctx, &state, struct cli_tdis_state); 2498 if (req == NULL) { 2499 return NULL; 2500 } 2501 state->cli = cli; 2502 2503 subreq = cli_smb_send(state, ev, cli, SMBtdis, 0, 0, NULL, 0, NULL); 2504 if (tevent_req_nomem(subreq, req)) { 2505 return tevent_req_post(req, ev); 2506 } 2507 tevent_req_set_callback(subreq, cli_tdis_done, req); 2508 return req; 2509 } 2510 2511 static void cli_tdis_done(struct tevent_req *subreq) 2512 { 2513 struct tevent_req *req = tevent_req_callback_data( 2514 subreq, struct tevent_req); 2515 struct cli_tdis_state *state = tevent_req_data( 2516 req, struct cli_tdis_state); 2517 NTSTATUS status; 2518 2519 status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); 2520 TALLOC_FREE(subreq); 2521 if (!NT_STATUS_IS_OK(status)) { 2522 tevent_req_nterror(req, status); 2523 return; 2524 } 2525 state->cli->cnum = -1; 2526 tevent_req_done(req); 2527 } 2528 2529 NTSTATUS cli_tdis_recv(struct tevent_req *req) 2530 { 2531 return tevent_req_simple_recv_ntstatus(req); 2532 } 2533 2534 NTSTATUS cli_tdis(struct cli_state *cli) 2535 { 2536 struct tevent_context *ev; 2537 struct tevent_req *req; 2538 NTSTATUS status = NT_STATUS_NO_MEMORY; 2539 2540 if (cli_has_async_calls(cli)) { 2541 return NT_STATUS_INVALID_PARAMETER; 2542 } 2543 ev = tevent_context_init(talloc_tos()); 2544 if (ev == NULL) { 2545 goto fail; 2546 } 2547 req = cli_tdis_send(ev, ev, cli); 2548 if (req == NULL) { 2549 goto fail; 2550 } 2551 if (!tevent_req_poll_ntstatus(req, ev, &status)) { 2552 goto fail; 2553 } 2554 status = cli_tdis_recv(req); 2555 fail: 2556 TALLOC_FREE(ev); 2557 if (!NT_STATUS_IS_OK(status)) { 2558 cli_set_error(cli, status); 2559 } 2560 return status; 1596 2561 } 1597 2562 … … 1672 2637 NTSTATUS status; 1673 2638 uint16_t protnum; 1674 1675 status = cli_smb_recv(subreq, 1, &wct, &vwv, &num_bytes, &bytes); 1676 if (!NT_STATUS_IS_OK(status)) { 1677 TALLOC_FREE(subreq); 2639 uint8_t *inbuf; 2640 2641 status = cli_smb_recv(subreq, state, &inbuf, 1, &wct, &vwv, 2642 &num_bytes, &bytes); 2643 TALLOC_FREE(subreq); 2644 if (!NT_STATUS_IS_OK(status)) { 1678 2645 tevent_req_nterror(req, status); 1679 2646 return; … … 1719 2686 /* work out if they sent us a workgroup */ 1720 2687 if (!(cli->capabilities & CAP_EXTENDED_SECURITY) && 1721 smb_buflen(cli->inbuf) > 8) { 1722 clistr_pull(cli->inbuf, cli->server_domain, 1723 bytes+8, sizeof(cli->server_domain), 1724 num_bytes-8, 1725 STR_UNICODE|STR_NOALIGN); 2688 smb_buflen(inbuf) > 8) { 2689 ssize_t ret; 2690 status = smb_bytes_talloc_string( 2691 cli, (char *)inbuf, &cli->server_domain, 2692 bytes + 8, num_bytes - 8, &ret); 2693 if (tevent_req_nterror(req, status)) { 2694 return; 2695 } 1726 2696 } 1727 2697 … … 1762 2732 cli->outbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN); 1763 2733 cli->inbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN); 2734 if (!cli->outbuf || !cli->inbuf) { 2735 tevent_req_nterror(req, 2736 NT_STATUS_NO_MEMORY); 2737 return; 2738 } 1764 2739 cli->bufsize = CLI_SAMBA_MAX_LARGE_READX_SIZE + LARGE_WRITEX_HDR_SIZE; 1765 2740 } … … 1774 2749 cli->serverzone *= 60; 1775 2750 /* this time is converted to GMT by make_unix_date */ 1776 cli->servertime = cli_make_unix_date(1777 cli, (char *)(vwv + 8));2751 cli->servertime = make_unix_date( 2752 (char *)(vwv + 8), cli->serverzone); 1778 2753 cli->readbraw_supported = ((SVAL(vwv + 5, 0) & 0x1) != 0); 1779 2754 cli->writebraw_supported = ((SVAL(vwv + 5, 0) & 0x2) != 0); … … 2070 3045 } 2071 3046 2072 fstrcpy(cli->desthost, host); 3047 cli->desthost = talloc_strdup(cli, host); 3048 if (cli->desthost == NULL) { 3049 return NT_STATUS_NO_MEMORY; 3050 } 2073 3051 2074 3052 /* allow hostnames of the form NAME#xx and do a netbios lookup */ … … 2078 3056 } 2079 3057 2080 if (!dest_ss || is_zero_addr( (struct sockaddr *)dest_ss)) {3058 if (!dest_ss || is_zero_addr(dest_ss)) { 2081 3059 NTSTATUS status =resolve_name_list(frame, 2082 3060 cli->desthost, … … 2143 3121 @param dest_ss (optional) The the destination IP, NULL for name based lookup 2144 3122 @param port (optional) The destination port (0 for default) 2145 @param retry bool. Did this connection fail with a retryable error ?2146 2147 3123 */ 2148 3124 NTSTATUS cli_start_connection(struct cli_state **output_cli, … … 2150 3126 const char *dest_host, 2151 3127 struct sockaddr_storage *dest_ss, int port, 2152 int signing_state, int flags, 2153 bool *retry) 3128 int signing_state, int flags) 2154 3129 { 2155 3130 NTSTATUS nt_status; … … 2158 3133 struct cli_state *cli; 2159 3134 struct sockaddr_storage ss; 2160 2161 if (retry)2162 *retry = False;2163 3135 2164 3136 if (!my_name) … … 2194 3166 return nt_status; 2195 3167 } 2196 2197 if (retry)2198 *retry = True;2199 3168 2200 3169 if (!cli_session_request(cli, &calling, &called)) { … … 2249 3218 @param domain User's domain 2250 3219 @param password User's password, unencrypted unix string. 2251 @param retry bool. Did this connection fail with a retryable error ?2252 3220 */ 2253 3221 … … 2259 3227 const char *user, const char *domain, 2260 3228 const char *password, int flags, 2261 int signing_state, 2262 bool *retry) 3229 int signing_state) 2263 3230 { 2264 3231 NTSTATUS nt_status; … … 2274 3241 nt_status = cli_start_connection(&cli, my_name, dest_host, 2275 3242 dest_ss, port, signing_state, 2276 flags , retry);3243 flags); 2277 3244 2278 3245 if (!NT_STATUS_IS_OK(nt_status)) { … … 2399 3366 uint16 *max_xmit, uint16 *tid) 2400 3367 { 2401 char *p; 3368 struct tevent_req *req; 3369 uint16_t *ret_vwv; 3370 uint8_t *bytes; 3371 NTSTATUS status; 2402 3372 2403 3373 if (!lp_client_plaintext_auth() && (*pass)) { … … 2407 3377 } 2408 3378 2409 memset(cli->outbuf,'\0',smb_size); 2410 memset(cli->inbuf,'\0',smb_size); 2411 2412 cli_set_message(cli->outbuf, 0, 0, True); 2413 SCVAL(cli->outbuf,smb_com,SMBtcon); 2414 cli_setup_packet(cli); 2415 2416 p = smb_buf(cli->outbuf); 2417 *p++ = 4; p += clistr_push(cli, p, service, -1, STR_TERMINATE | STR_NOALIGN); 2418 *p++ = 4; p += clistr_push(cli, p, pass, -1, STR_TERMINATE | STR_NOALIGN); 2419 *p++ = 4; p += clistr_push(cli, p, dev, -1, STR_TERMINATE | STR_NOALIGN); 2420 2421 cli_setup_bcc(cli, p); 2422 2423 cli_send_smb(cli); 2424 if (!cli_receive_smb(cli)) { 2425 return NT_STATUS_UNEXPECTED_NETWORK_ERROR; 2426 } 2427 2428 if (cli_is_error(cli)) { 2429 return cli_nt_error(cli); 2430 } 2431 2432 *max_xmit = SVAL(cli->inbuf, smb_vwv0); 2433 *tid = SVAL(cli->inbuf, smb_vwv1); 3379 bytes = talloc_array(talloc_tos(), uint8_t, 0); 3380 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0); 3381 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), 3382 service, strlen(service)+1, NULL); 3383 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0); 3384 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), 3385 pass, strlen(pass)+1, NULL); 3386 bytes = smb_bytes_push_bytes(bytes, 4, NULL, 0); 3387 bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), 3388 dev, strlen(dev)+1, NULL); 3389 3390 status = cli_smb(talloc_tos(), cli, SMBtcon, 0, 0, NULL, 3391 talloc_get_size(bytes), bytes, &req, 3392 2, NULL, &ret_vwv, NULL, NULL); 3393 if (!NT_STATUS_IS_OK(status)) { 3394 return status; 3395 } 3396 3397 *max_xmit = SVAL(ret_vwv + 0, 0); 3398 *tid = SVAL(ret_vwv + 1, 0); 2434 3399 2435 3400 return NT_STATUS_OK; … … 2455 3420 user_info->password ? user_info->password : "", 2456 3421 flags, 2457 Undefined , NULL);3422 Undefined); 2458 3423 2459 3424 if (NT_STATUS_IS_OK(nt_status)) { … … 2485 3450 2486 3451 struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx, 2487 struct ip_service *mb_ip,3452 struct sockaddr_storage *mb_ip, 2488 3453 const struct user_auth_info *user_info, 2489 3454 char **pp_workgroup_out) … … 2496 3461 *pp_workgroup_out = NULL; 2497 3462 2498 print_sockaddr(addr, sizeof(addr), &mb_ip->ss);3463 print_sockaddr(addr, sizeof(addr), mb_ip); 2499 3464 DEBUG(99, ("Looking up name of master browser %s\n", 2500 3465 addr)); … … 2511 3476 * MSBROWSE if the wildcard query fails. 2512 3477 */ 2513 if (!name_status_find("*", 0, 0x1d, &mb_ip->ss, name) &&2514 !name_status_find(MSBROWSE, 1, 0x1d, &mb_ip->ss, name)) {3478 if (!name_status_find("*", 0, 0x1d, mb_ip, name) && 3479 !name_status_find(MSBROWSE, 1, 0x1d, mb_ip, name)) { 2515 3480 2516 3481 DEBUG(99, ("Could not retrieve name status for %s\n", … … 2543 3508 char **pp_workgroup_out) 2544 3509 { 2545 struct ip_service *ip_list;3510 struct sockaddr_storage *ip_list; 2546 3511 struct cli_state *cli; 2547 3512 int i, count; 3513 NTSTATUS status; 2548 3514 2549 3515 *pp_workgroup_out = NULL; … … 2553 3519 /* Go looking for workgroups by broadcasting on the local network */ 2554 3520 2555 if (!NT_STATUS_IS_OK(name_resolve_bcast(MSBROWSE, 1, &ip_list, 2556 &count))) { 2557 DEBUG(99, ("No master browsers responded\n")); 3521 status = name_resolve_bcast(MSBROWSE, 1, talloc_tos(), 3522 &ip_list, &count); 3523 if (!NT_STATUS_IS_OK(status)) { 3524 DEBUG(99, ("No master browsers responded: %s\n", 3525 nt_errstr(status))); 2558 3526 return False; 2559 3527 } … … 2561 3529 for (i = 0; i < count; i++) { 2562 3530 char addr[INET6_ADDRSTRLEN]; 2563 print_sockaddr(addr, sizeof(addr), &ip_list[i] .ss);3531 print_sockaddr(addr, sizeof(addr), &ip_list[i]); 2564 3532 DEBUG(99, ("Found master browser %s\n", addr)); 2565 3533
Note:
See TracChangeset
for help on using the changeset viewer.