Changeset 988 for vendor/current/source3/libsmb/clidfs.c
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/libsmb/clidfs.c
r919 r988 26 26 #include "trans2.h" 27 27 #include "libsmb/nmblib.h" 28 #include "../libcli/smb/smbXcli_base.h" 28 29 29 30 /******************************************************************** … … 48 49 const char *sharename) 49 50 { 50 NTSTATUS status = cli_force_encryption(c, 51 NTSTATUS status; 52 53 if (smbXcli_conn_protocol(c->conn) >= PROTOCOL_SMB2_02) { 54 status = smb2cli_session_encryption_on(c->smb2.session); 55 if (NT_STATUS_EQUAL(status,NT_STATUS_NOT_SUPPORTED)) { 56 d_printf("Encryption required and " 57 "server doesn't support " 58 "SMB3 encryption - failing connect\n"); 59 } else if (!NT_STATUS_IS_OK(status)) { 60 d_printf("Encryption required and " 61 "setup failed with error %s.\n", 62 nt_errstr(status)); 63 } 64 return status; 65 } 66 67 status = cli_force_encryption(c, 51 68 username, 52 69 password, … … 78 95 ********************************************************************/ 79 96 80 static struct cli_state *do_connect(TALLOC_CTX *ctx,97 static NTSTATUS do_connect(TALLOC_CTX *ctx, 81 98 const char *server, 82 99 const char *share, … … 86 103 int max_protocol, 87 104 int port, 88 int name_type) 105 int name_type, 106 struct cli_state **pcli) 89 107 { 90 108 struct cli_state *c = NULL; 91 struct nmb_name called, calling;92 const char *called_str;93 const char *server_n;94 struct sockaddr_storage ss;95 109 char *servicename; 96 110 char *sharename; … … 98 112 const char *username; 99 113 const char *password; 114 const char *domain; 100 115 NTSTATUS status; 116 int flags = 0; 101 117 int signing_state = get_cmdline_auth_info_signing_state(auth_info); 102 118 103 119 if (force_encrypt) { 104 signing_state = Required;120 signing_state = SMB_SIGNING_REQUIRED; 105 121 } 106 122 … … 108 124 servicename = talloc_strdup(ctx,share); 109 125 if (!servicename) { 110 return N ULL;126 return NT_STATUS_NO_MEMORY; 111 127 } 112 128 sharename = servicename; 113 129 if (*sharename == '\\') { 114 130 sharename += 2; 115 called_str = sharename;116 131 if (server == NULL) { 117 132 server = sharename; … … 119 134 sharename = strchr_m(sharename,'\\'); 120 135 if (!sharename) { 121 return N ULL;136 return NT_STATUS_NO_MEMORY; 122 137 } 123 138 *sharename = 0; 124 139 sharename++; 125 } else { 126 called_str = server; 127 } 128 129 server_n = server; 130 131 zero_sockaddr(&ss); 132 133 make_nmb_name(&calling, global_myname(), 0x0); 134 make_nmb_name(&called , called_str, name_type); 135 136 again: 137 zero_sockaddr(&ss); 138 139 /* have to open a new connection */ 140 c = cli_initialise_ex(signing_state); 141 if (c == NULL) { 142 d_printf("Connection to %s failed\n", server_n); 143 return NULL; 144 } 145 if (port) { 146 cli_set_port(c, port); 147 } 148 149 status = cli_connect(c, server_n, &ss); 140 } 141 if (server == NULL) { 142 return NT_STATUS_INVALID_PARAMETER; 143 } 144 145 if (get_cmdline_auth_info_use_kerberos(auth_info)) { 146 flags |= CLI_FULL_CONNECTION_USE_KERBEROS; 147 } 148 if (get_cmdline_auth_info_fallback_after_kerberos(auth_info)) { 149 flags |= CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS; 150 } 151 if (get_cmdline_auth_info_use_ccache(auth_info)) { 152 flags |= CLI_FULL_CONNECTION_USE_CCACHE; 153 } 154 if (get_cmdline_auth_info_use_pw_nt_hash(auth_info)) { 155 flags |= CLI_FULL_CONNECTION_USE_NT_HASH; 156 } 157 158 status = cli_connect_nb( 159 server, NULL, port, name_type, NULL, 160 signing_state, 161 flags, &c); 162 150 163 if (!NT_STATUS_IS_OK(status)) { 151 164 d_printf("Connection to %s failed (Error %s)\n", 152 server _n,165 server, 153 166 nt_errstr(status)); 154 cli_shutdown(c); 155 return NULL; 167 return status; 156 168 } 157 169 … … 159 171 max_protocol = PROTOCOL_NT1; 160 172 } 161 c->protocol = max_protocol;162 c->use_kerberos = get_cmdline_auth_info_use_kerberos(auth_info);163 c->fallback_after_kerberos =164 get_cmdline_auth_info_fallback_after_kerberos(auth_info);165 c->use_ccache = get_cmdline_auth_info_use_ccache(auth_info);166 167 if (!cli_session_request(c, &calling, &called)) {168 char *p;169 d_printf("session request to %s failed (%s)\n",170 called.name, cli_errstr(c));171 cli_shutdown(c);172 c = NULL;173 if ((p=strchr_m(called.name, '.'))) {174 *p = 0;175 goto again;176 }177 if (strcmp(called.name, "*SMBSERVER")) {178 make_nmb_name(&called , "*SMBSERVER", 0x20);179 goto again;180 }181 return NULL;182 }183 184 173 DEBUG(4,(" session request ok\n")); 185 174 186 status = cli_negprot(c); 175 status = smbXcli_negprot(c->conn, c->timeout, 176 lp_client_min_protocol(), 177 max_protocol); 187 178 188 179 if (!NT_STATUS_IS_OK(status)) { … … 190 181 nt_errstr(status)); 191 182 cli_shutdown(c); 192 return NULL; 183 return status; 184 } 185 186 if (smbXcli_conn_protocol(c->conn) >= PROTOCOL_SMB2_02) { 187 /* Ensure we ask for some initial credits. */ 188 smb2cli_conn_set_max_credits(c->conn, DEFAULT_SMB2_MAX_CREDITS); 193 189 } 194 190 195 191 username = get_cmdline_auth_info_username(auth_info); 196 192 password = get_cmdline_auth_info_password(auth_info); 197 198 if (!NT_STATUS_IS_OK(cli_session_setup(c, username, 199 password, strlen(password), 200 password, strlen(password), 201 lp_workgroup()))) { 193 domain = get_cmdline_auth_info_domain(auth_info); 194 if ((domain == NULL) || (domain[0] == '\0')) { 195 domain = lp_workgroup(); 196 } 197 198 status = cli_session_setup(c, username, 199 password, strlen(password), 200 password, strlen(password), 201 domain); 202 if (!NT_STATUS_IS_OK(status)) { 202 203 /* If a password was not supplied then 203 204 * try again with a null username. */ 204 205 if (password[0] || !username[0] || 205 206 get_cmdline_auth_info_use_kerberos(auth_info) || 206 !NT_STATUS_IS_OK( cli_session_setup(c, "",207 !NT_STATUS_IS_OK(status = cli_session_setup(c, "", 207 208 "", 0, 208 209 "", 0, 209 210 lp_workgroup()))) { 210 d_printf("session setup failed: %s\n", cli_errstr(c)); 211 if (NT_STATUS_V(cli_nt_error(c)) == 212 NT_STATUS_V(NT_STATUS_MORE_PROCESSING_REQUIRED)) 211 d_printf("session setup failed: %s\n", 212 nt_errstr(status)); 213 if (NT_STATUS_EQUAL(status, 214 NT_STATUS_MORE_PROCESSING_REQUIRED)) 213 215 d_printf("did you forget to run kinit?\n"); 214 216 cli_shutdown(c); 215 return NULL;217 return status; 216 218 } 217 219 d_printf("Anonymous login successful\n"); 218 status = cli_init_creds(c, "", lp_workgroup(), "");219 } else {220 status = cli_init_creds(c, username, lp_workgroup(), password);221 220 } 222 221 … … 224 223 DEBUG(10,("cli_init_creds() failed: %s\n", nt_errstr(status))); 225 224 cli_shutdown(c); 226 return NULL;225 return status; 227 226 } 228 227 … … 243 242 cli_check_msdfs_proxy() will fail if it is a normal share. */ 244 243 245 if ( (c->capabilities & CAP_DFS) &&244 if (smbXcli_conn_dfs_supported(c->conn) && 246 245 cli_check_msdfs_proxy(ctx, c, sharename, 247 246 &newserver, &newshare, … … 249 248 username, 250 249 password, 251 lp_workgroup())) {250 domain)) { 252 251 cli_shutdown(c); 253 252 return do_connect(ctx, newserver, 254 253 newshare, auth_info, false, 255 254 force_encrypt, max_protocol, 256 port, name_type );255 port, name_type, pcli); 257 256 } 258 257 259 258 /* must be a normal share */ 260 259 261 status = cli_t con_andx(c, sharename, "?????",262 260 status = cli_tree_connect(c, sharename, "?????", 261 password, strlen(password)+1); 263 262 if (!NT_STATUS_IS_OK(status)) { 264 263 d_printf("tree connect failed: %s\n", nt_errstr(status)); 265 264 cli_shutdown(c); 266 return NULL;265 return status; 267 266 } 268 267 … … 271 270 username, 272 271 password, 273 lp_workgroup(),272 domain, 274 273 sharename); 275 274 if (!NT_STATUS_IS_OK(status)) { 276 275 cli_shutdown(c); 277 return NULL;276 return status; 278 277 } 279 278 } 280 279 281 280 DEBUG(4,(" tconx ok\n")); 282 return c; 281 *pcli = c; 282 return NT_STATUS_OK; 283 283 } 284 284 … … 288 288 static void cli_set_mntpoint(struct cli_state *cli, const char *mnt) 289 289 { 290 char *name = clean_name(NULL, mnt); 290 TALLOC_CTX *frame = talloc_stackframe(); 291 char *name = clean_name(frame, mnt); 291 292 if (!name) { 293 TALLOC_FREE(frame); 292 294 return; 293 295 } 294 296 TALLOC_FREE(cli->dfs_mountpoint); 295 297 cli->dfs_mountpoint = talloc_strdup(cli, name); 296 TALLOC_FREE( name);298 TALLOC_FREE(frame); 297 299 } 298 300 … … 302 304 ********************************************************************/ 303 305 304 static struct cli_state *cli_cm_connect(TALLOC_CTX *ctx, 305 struct cli_state *referring_cli, 306 const char *server, 307 const char *share, 308 const struct user_auth_info *auth_info, 309 bool show_hdr, 310 bool force_encrypt, 311 int max_protocol, 312 int port, 313 int name_type) 306 static NTSTATUS cli_cm_connect(TALLOC_CTX *ctx, 307 struct cli_state *referring_cli, 308 const char *server, 309 const char *share, 310 const struct user_auth_info *auth_info, 311 bool show_hdr, 312 bool force_encrypt, 313 int max_protocol, 314 int port, 315 int name_type, 316 struct cli_state **pcli) 314 317 { 315 318 struct cli_state *cli; 316 317 cli = do_connect(ctx, server, share, 319 NTSTATUS status; 320 321 status = do_connect(ctx, server, share, 318 322 auth_info, 319 323 show_hdr, force_encrypt, max_protocol, 320 port, name_type );321 322 if (! cli) {323 return NULL;324 port, name_type, &cli); 325 326 if (!NT_STATUS_IS_OK(status)) { 327 return status; 324 328 } 325 329 326 330 /* Enter into the list. */ 327 331 if (referring_cli) { 328 DLIST_ADD_END(referring_cli, cli , struct cli_state *);332 DLIST_ADD_END(referring_cli, cli); 329 333 } 330 334 331 335 if (referring_cli && referring_cli->requested_posix_capabilities) { 332 uint16 major, minor; 333 uint32 caplow, caphigh; 334 NTSTATUS status; 336 uint16_t major, minor; 337 uint32_t caplow, caphigh; 335 338 status = cli_unix_extensions_version(cli, &major, &minor, 336 339 &caplow, &caphigh); … … 342 345 } 343 346 344 return cli; 347 *pcli = cli; 348 return NT_STATUS_OK; 345 349 } 346 350 … … 361 365 /* Search to the start of the list. */ 362 366 for (p = cli; p; p = DLIST_PREV(p)) { 363 if (strequal(server, p->desthost) && 367 const char *remote_name = 368 smbXcli_conn_remote_name(p->conn); 369 370 if (strequal(server, remote_name) && 364 371 strequal(share,p->share)) { 365 372 return p; … … 369 376 /* Search to the end of the list. */ 370 377 for (p = cli->next; p; p = p->next) { 371 if (strequal(server, p->desthost) && 378 const char *remote_name = 379 smbXcli_conn_remote_name(p->conn); 380 381 if (strequal(server, remote_name) && 372 382 strequal(share,p->share)) { 373 383 return p; … … 382 392 ****************************************************************************/ 383 393 384 struct cli_state *cli_cm_open(TALLOC_CTX *ctx,394 NTSTATUS cli_cm_open(TALLOC_CTX *ctx, 385 395 struct cli_state *referring_cli, 386 396 const char *server, … … 391 401 int max_protocol, 392 402 int port, 393 int name_type) 403 int name_type, 404 struct cli_state **pcli) 394 405 { 395 406 /* Try to reuse an existing connection in this list. */ 396 407 struct cli_state *c = cli_cm_find(referring_cli, server, share); 408 NTSTATUS status; 397 409 398 410 if (c) { 399 return c; 411 *pcli = c; 412 return NT_STATUS_OK; 400 413 } 401 414 … … 406 419 "without auth info\n", 407 420 server, share ); 408 return N ULL;409 } 410 411 returncli_cm_connect(ctx,421 return NT_STATUS_INVALID_PARAMETER; 422 } 423 424 status = cli_cm_connect(ctx, 412 425 referring_cli, 413 426 server, … … 418 431 max_protocol, 419 432 port, 420 name_type); 433 name_type, 434 &c); 435 if (!NT_STATUS_IS_OK(status)) { 436 return status; 437 } 438 *pcli = c; 439 return NT_STATUS_OK; 421 440 } 422 441 … … 424 443 ****************************************************************************/ 425 444 426 void cli_cm_display( conststruct cli_state *cli)445 void cli_cm_display(struct cli_state *cli) 427 446 { 428 447 int i; … … 430 449 for (i=0; cli; cli = cli->next,i++ ) { 431 450 d_printf("%d:\tserver=%s, share=%s\n", 432 i, cli->desthost, cli->share);451 i, smbXcli_conn_remote_name(cli->conn), cli->share); 433 452 } 434 453 } … … 597 616 return talloc_asprintf(ctx, "%c%s%c%s%c%s", 598 617 path_sep, 599 cli->desthost,618 smbXcli_conn_remote_name(cli->conn), 600 619 path_sep, 601 620 cli->share, … … 613 632 /* only deal with DS when we negotiated NT_STATUS codes and UNICODE */ 614 633 615 if (!( cli->capabilities & CAP_UNICODE)) {634 if (!(smbXcli_conn_use_unicode(cli->conn))) { 616 635 return false; 617 636 } 618 if (!( cli->capabilities& CAP_STATUS32)) {637 if (!(smb1cli_conn_capabilities(cli->conn) & CAP_STATUS32)) { 619 638 return false; 620 639 } … … 636 655 size_t *consumed) 637 656 { 638 unsigned int data_len = 0;639 657 unsigned int param_len = 0; 640 uint16 setup[1];658 uint16_t recv_flags2; 641 659 uint8_t *param = NULL; 642 660 uint8_t *rdata = NULL; 643 661 char *p; 644 662 char *endp; 645 size_t pathlen = 2*(strlen(path)+1);646 663 smb_ucs2_t *path_ucs; 647 664 char *consumed_path = NULL; 648 665 uint16_t consumed_ucs; 649 uint16 num_referrals;666 uint16_t num_referrals; 650 667 struct client_dfs_referral *referrals = NULL; 651 668 NTSTATUS status; 669 TALLOC_CTX *frame = talloc_stackframe(); 652 670 653 671 *num_refs = 0; 654 672 *refs = NULL; 655 673 656 SSVAL(setup, 0, TRANSACT2_GET_DFS_REFERRAL); 657 658 param = SMB_MALLOC_ARRAY(uint8_t, 2+pathlen+2); 674 param = talloc_array(talloc_tos(), uint8_t, 2); 659 675 if (!param) { 660 676 status = NT_STATUS_NO_MEMORY; … … 662 678 } 663 679 SSVAL(param, 0, 0x03); /* max referral level */ 664 p = (char *)(¶m[2]); 665 666 path_ucs = (smb_ucs2_t *)p; 667 p += clistr_push(cli, p, path, pathlen, STR_TERMINATE); 668 param_len = PTR_DIFF(p, param); 669 670 status = cli_trans(talloc_tos(), cli, SMBtrans2, 671 NULL, 0xffff, 0, 0, 672 setup, 1, 0, 673 param, param_len, 2, 674 NULL, 0, cli->max_xmit, 675 NULL, 676 NULL, 0, NULL, /* rsetup */ 677 NULL, 0, NULL, 678 &rdata, 4, &data_len); 679 if (!NT_STATUS_IS_OK(status)) { 680 681 param = trans2_bytes_push_str(param, smbXcli_conn_use_unicode(cli->conn), 682 path, strlen(path)+1, 683 NULL); 684 if (!param) { 685 status = NT_STATUS_NO_MEMORY; 680 686 goto out; 681 687 } 682 if (data_len < 4) { 683 goto out; 684 } 685 686 endp = (char *)rdata + data_len; 688 param_len = talloc_get_size(param); 689 path_ucs = (smb_ucs2_t *)¶m[2]; 690 691 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) { 692 DATA_BLOB in_input_buffer; 693 DATA_BLOB in_output_buffer = data_blob_null; 694 DATA_BLOB out_input_buffer = data_blob_null; 695 DATA_BLOB out_output_buffer = data_blob_null; 696 697 in_input_buffer.data = param; 698 in_input_buffer.length = param_len; 699 700 status = smb2cli_ioctl(cli->conn, 701 cli->timeout, 702 cli->smb2.session, 703 cli->smb2.tcon, 704 UINT64_MAX, /* in_fid_persistent */ 705 UINT64_MAX, /* in_fid_volatile */ 706 FSCTL_DFS_GET_REFERRALS, 707 0, /* in_max_input_length */ 708 &in_input_buffer, 709 CLI_BUFFER_SIZE, /* in_max_output_length */ 710 &in_output_buffer, 711 SMB2_IOCTL_FLAG_IS_FSCTL, 712 talloc_tos(), 713 &out_input_buffer, 714 &out_output_buffer); 715 if (!NT_STATUS_IS_OK(status)) { 716 goto out; 717 } 718 719 if (out_output_buffer.length < 4) { 720 status = NT_STATUS_INVALID_NETWORK_RESPONSE; 721 goto out; 722 } 723 724 recv_flags2 = FLAGS2_UNICODE_STRINGS; 725 rdata = out_output_buffer.data; 726 endp = (char *)rdata + out_output_buffer.length; 727 } else { 728 unsigned int data_len = 0; 729 uint16_t setup[1]; 730 731 SSVAL(setup, 0, TRANSACT2_GET_DFS_REFERRAL); 732 733 status = cli_trans(talloc_tos(), cli, SMBtrans2, 734 NULL, 0xffff, 0, 0, 735 setup, 1, 0, 736 param, param_len, 2, 737 NULL, 0, CLI_BUFFER_SIZE, 738 &recv_flags2, 739 NULL, 0, NULL, /* rsetup */ 740 NULL, 0, NULL, 741 &rdata, 4, &data_len); 742 if (!NT_STATUS_IS_OK(status)) { 743 goto out; 744 } 745 746 endp = (char *)rdata + data_len; 747 } 687 748 688 749 consumed_ucs = SVAL(rdata, 0); … … 696 757 * the incoming path. */ 697 758 759 errno = 0; 698 760 if (pull_string_talloc(talloc_tos(), 699 761 NULL, … … 703 765 consumed_ucs, 704 766 STR_UNICODE) == 0) { 767 if (errno != 0) { 768 status = map_nt_error_from_unix(errno); 769 } else { 770 status = NT_STATUS_INVALID_NETWORK_RESPONSE; 771 } 705 772 goto out; 706 773 } 707 774 if (consumed_path == NULL) { 775 status = map_nt_error_from_unix(errno); 708 776 goto out; 709 777 } … … 711 779 712 780 if (num_referrals != 0) { 713 uint16 ref_version;714 uint16 ref_size;781 uint16_t ref_version; 782 uint16_t ref_size; 715 783 int i; 716 uint16 node_offset;784 uint16_t node_offset; 717 785 718 786 referrals = talloc_array(ctx, struct client_dfs_referral, … … 720 788 721 789 if (!referrals) { 790 status = NT_STATUS_NO_MEMORY; 722 791 goto out; 723 792 } … … 742 811 743 812 if (p + node_offset > endp) { 813 status = NT_STATUS_INVALID_NETWORK_RESPONSE; 744 814 goto out; 745 815 } 746 clistr_pull_talloc(ctx, cli->inbuf, 747 SVAL(cli->inbuf, smb_flg2), 816 clistr_pull_talloc(referrals, 817 (const char *)rdata, 818 recv_flags2, 748 819 &referrals[i].dfspath, 749 p+node_offset, -1, 820 p+node_offset, 821 PTR_DIFF(endp, p+node_offset), 750 822 STR_TERMINATE|STR_UNICODE); 751 823 752 824 if (!referrals[i].dfspath) { 825 status = map_nt_error_from_unix(errno); 753 826 goto out; 754 827 } … … 756 829 } 757 830 if (i < num_referrals) { 831 status = NT_STATUS_INVALID_NETWORK_RESPONSE; 758 832 goto out; 759 833 } … … 765 839 out: 766 840 767 TALLOC_FREE(consumed_path); 768 SAFE_FREE(param); 769 TALLOC_FREE(rdata); 841 TALLOC_FREE(frame); 770 842 return status; 771 843 } … … 773 845 /******************************************************************** 774 846 ********************************************************************/ 775 776 bool cli_resolve_path(TALLOC_CTX *ctx, 777 const char *mountpt, 778 const struct user_auth_info *dfs_auth_info, 779 struct cli_state *rootcli, 780 const char *path, 781 struct cli_state **targetcli, 782 char **pp_targetpath) 847 struct cli_dfs_path_split { 848 char *server; 849 char *share; 850 char *extrapath; 851 }; 852 853 NTSTATUS cli_resolve_path(TALLOC_CTX *ctx, 854 const char *mountpt, 855 const struct user_auth_info *dfs_auth_info, 856 struct cli_state *rootcli, 857 const char *path, 858 struct cli_state **targetcli, 859 char **pp_targetpath) 783 860 { 784 861 struct client_dfs_referral *refs = NULL; … … 790 867 char *extrapath = NULL; 791 868 int pathlen; 792 char *server = NULL;793 char *share = NULL;794 869 struct cli_state *newcli = NULL; 870 struct cli_state *ccli = NULL; 871 int count = 0; 795 872 char *newpath = NULL; 796 873 char *newmount = NULL; 797 874 char *ppath = NULL; 798 875 SMB_STRUCT_STAT sbuf; 799 uint32 attributes;876 uint32_t attributes; 800 877 NTSTATUS status; 878 struct smbXcli_tcon *root_tcon = NULL; 879 struct smbXcli_tcon *target_tcon = NULL; 880 struct cli_dfs_path_split *dfs_refs = NULL; 801 881 802 882 if ( !rootcli || !path || !targetcli ) { 803 return false;883 return NT_STATUS_INVALID_PARAMETER; 804 884 } 805 885 806 886 /* Don't do anything if this is not a DFS root. */ 807 887 808 if ( !rootcli->dfsroot) { 888 if (smbXcli_conn_protocol(rootcli->conn) >= PROTOCOL_SMB2_02) { 889 root_tcon = rootcli->smb2.tcon; 890 } else { 891 root_tcon = rootcli->smb1.tcon; 892 } 893 894 if (!smbXcli_tcon_is_dfs_share(root_tcon)) { 809 895 *targetcli = rootcli; 810 896 *pp_targetpath = talloc_strdup(ctx, path); 811 897 if (!*pp_targetpath) { 812 return false;813 } 814 return true;898 return NT_STATUS_NO_MEMORY; 899 } 900 return NT_STATUS_OK; 815 901 } 816 902 … … 821 907 cleanpath = clean_path(ctx, path); 822 908 if (!cleanpath) { 823 return false;909 return NT_STATUS_NO_MEMORY; 824 910 } 825 911 826 912 dfs_path = cli_dfs_make_full_path(ctx, rootcli, cleanpath); 827 913 if (!dfs_path) { 828 return false;914 return NT_STATUS_NO_MEMORY; 829 915 } 830 916 … … 835 921 *pp_targetpath = talloc_strdup(ctx, path); 836 922 if (!*pp_targetpath) { 837 return false;923 return NT_STATUS_NO_MEMORY; 838 924 } 839 925 goto done; … … 847 933 *pp_targetpath = talloc_strdup(ctx, path); 848 934 if (!*pp_targetpath) { 849 return false;935 return NT_STATUS_NO_MEMORY; 850 936 } 851 937 goto done; … … 856 942 if (!cli_dfs_check_error(rootcli, NT_STATUS_PATH_NOT_COVERED, 857 943 status)) { 858 return false;944 return status; 859 945 } 860 946 861 947 /* Check for the referral. */ 862 948 863 if (!(cli_ipc = cli_cm_open(ctx, 864 rootcli, 865 rootcli->desthost, 866 "IPC$", 949 status = cli_cm_open(ctx, 950 rootcli, 951 smbXcli_conn_remote_name(rootcli->conn), 952 "IPC$", 953 dfs_auth_info, 954 false, 955 smb1cli_conn_encryption_on(rootcli->conn), 956 smbXcli_conn_protocol(rootcli->conn), 957 0, 958 0x20, 959 &cli_ipc); 960 if (!NT_STATUS_IS_OK(status)) { 961 return status; 962 } 963 964 status = cli_dfs_get_referral(ctx, cli_ipc, dfs_path, &refs, 965 &num_refs, &consumed); 966 if (!NT_STATUS_IS_OK(status)) { 967 return status; 968 } 969 970 if (!num_refs || !refs[0].dfspath) { 971 return NT_STATUS_NOT_FOUND; 972 } 973 974 /* 975 * Bug#10123 - DFS referal entries can be provided in a random order, 976 * so check the connection cache for each item to avoid unnecessary 977 * reconnections. 978 */ 979 dfs_refs = talloc_array(ctx, struct cli_dfs_path_split, num_refs); 980 if (dfs_refs == NULL) { 981 return NT_STATUS_NO_MEMORY; 982 } 983 984 for (count = 0; count < num_refs; count++) { 985 if (!split_dfs_path(dfs_refs, refs[count].dfspath, 986 &dfs_refs[count].server, 987 &dfs_refs[count].share, 988 &dfs_refs[count].extrapath)) { 989 TALLOC_FREE(dfs_refs); 990 return NT_STATUS_NOT_FOUND; 991 } 992 993 ccli = cli_cm_find(rootcli, dfs_refs[count].server, 994 dfs_refs[count].share); 995 if (ccli != NULL) { 996 extrapath = dfs_refs[count].extrapath; 997 *targetcli = ccli; 998 break; 999 } 1000 } 1001 1002 /* 1003 * If no cached connection was found, then connect to the first live 1004 * referral server in the list. 1005 */ 1006 for (count = 0; (ccli == NULL) && (count < num_refs); count++) { 1007 /* Connect to the target server & share */ 1008 status = cli_cm_connect(ctx, rootcli, 1009 dfs_refs[count].server, 1010 dfs_refs[count].share, 867 1011 dfs_auth_info, 868 1012 false, 869 (rootcli->trans_enc_state != NULL),870 rootcli->protocol,1013 smb1cli_conn_encryption_on(rootcli->conn), 1014 smbXcli_conn_protocol(rootcli->conn), 871 1015 0, 872 0x20))) { 873 return false; 874 } 875 876 status = cli_dfs_get_referral(ctx, cli_ipc, dfs_path, &refs, 877 &num_refs, &consumed); 878 if (!NT_STATUS_IS_OK(status) || !num_refs) { 879 return false; 880 } 881 882 /* Just store the first referral for now. */ 883 884 if (!refs[0].dfspath) { 885 return false; 886 } 887 if (!split_dfs_path(ctx, refs[0].dfspath, &server, &share, 888 &extrapath)) { 889 return false; 1016 0x20, 1017 targetcli); 1018 if (!NT_STATUS_IS_OK(status)) { 1019 d_printf("Unable to follow dfs referral [\\%s\\%s]\n", 1020 dfs_refs[count].server, 1021 dfs_refs[count].share); 1022 continue; 1023 } else { 1024 extrapath = dfs_refs[count].extrapath; 1025 break; 1026 } 1027 } 1028 1029 /* No available referral server for the connection */ 1030 if (*targetcli == NULL) { 1031 TALLOC_FREE(dfs_refs); 1032 return status; 890 1033 } 891 1034 … … 894 1037 dfs_path = cli_dfs_make_full_path(ctx, rootcli, path); 895 1038 if (!dfs_path) { 896 return false; 1039 TALLOC_FREE(dfs_refs); 1040 return NT_STATUS_NO_MEMORY; 897 1041 } 898 1042 pathlen = strlen(dfs_path); … … 900 1044 *pp_targetpath = talloc_strdup(ctx, &dfs_path[consumed]); 901 1045 if (!*pp_targetpath) { 902 return false; 1046 TALLOC_FREE(dfs_refs); 1047 return NT_STATUS_NO_MEMORY; 903 1048 } 904 1049 dfs_path[consumed] = '\0'; … … 909 1054 * (in \server\share\path format). 910 1055 */ 911 912 /* Open the connection to the target server & share */913 if ((*targetcli = cli_cm_open(ctx, rootcli,914 server,915 share,916 dfs_auth_info,917 false,918 (rootcli->trans_enc_state != NULL),919 rootcli->protocol,920 0,921 0x20)) == NULL) {922 d_printf("Unable to follow dfs referral [\\%s\\%s]\n",923 server, share );924 return false;925 }926 1056 927 1057 if (extrapath && strlen(extrapath) > 0) { … … 940 1070 } 941 1071 if (!*pp_targetpath) { 942 return false; 1072 TALLOC_FREE(dfs_refs); 1073 return NT_STATUS_NO_MEMORY; 943 1074 } 944 1075 } … … 953 1084 "dfs_path (%s) not in correct format.\n", 954 1085 dfs_path ); 955 return false; 1086 TALLOC_FREE(dfs_refs); 1087 return NT_STATUS_NOT_FOUND; 956 1088 } 957 1089 … … 959 1091 960 1092 if ((ppath = strchr_m( dfs_path, '\\' )) == NULL) { 961 return false; 1093 TALLOC_FREE(dfs_refs); 1094 return NT_STATUS_NOT_FOUND; 962 1095 } 963 1096 … … 965 1098 966 1099 if ((ppath = strchr_m( ppath+1, '\\' )) == NULL) { 967 return false; 1100 TALLOC_FREE(dfs_refs); 1101 return NT_STATUS_NOT_FOUND; 968 1102 } 969 1103 … … 972 1106 newmount = talloc_asprintf(ctx, "%s\\%s", mountpt, ppath ); 973 1107 if (!newmount) { 974 return false; 1108 TALLOC_FREE(dfs_refs); 1109 return NT_STATUS_NOT_FOUND; 975 1110 } 976 1111 … … 981 1116 982 1117 if (!strequal(*pp_targetpath, "\\") && !strequal(*pp_targetpath, "/")) { 983 if (cli_resolve_path(ctx, 984 newmount, 985 dfs_auth_info, 986 *targetcli, 987 *pp_targetpath, 988 &newcli, 989 &newpath)) { 1118 status = cli_resolve_path(ctx, 1119 newmount, 1120 dfs_auth_info, 1121 *targetcli, 1122 *pp_targetpath, 1123 &newcli, 1124 &newpath); 1125 if (NT_STATUS_IS_OK(status)) { 990 1126 /* 991 1127 * When cli_resolve_path returns true here it's always … … 995 1131 *targetcli = newcli; 996 1132 *pp_targetpath = newpath; 997 return true; 1133 TALLOC_FREE(dfs_refs); 1134 return status; 998 1135 } 999 1136 } … … 1001 1138 done: 1002 1139 1140 if (smbXcli_conn_protocol((*targetcli)->conn) >= PROTOCOL_SMB2_02) { 1141 target_tcon = (*targetcli)->smb2.tcon; 1142 } else { 1143 target_tcon = (*targetcli)->smb1.tcon; 1144 } 1145 1003 1146 /* If returning true ensure we return a dfs root full path. */ 1004 if ( (*targetcli)->dfsroot) {1147 if (smbXcli_tcon_is_dfs_share(target_tcon)) { 1005 1148 dfs_path = talloc_strdup(ctx, *pp_targetpath); 1006 1149 if (!dfs_path) { 1007 return false; 1150 TALLOC_FREE(dfs_refs); 1151 return NT_STATUS_NO_MEMORY; 1008 1152 } 1009 1153 *pp_targetpath = cli_dfs_make_full_path(ctx, *targetcli, dfs_path); 1010 } 1011 1012 return true; 1154 if (*pp_targetpath == NULL) { 1155 TALLOC_FREE(dfs_refs); 1156 return NT_STATUS_NO_MEMORY; 1157 } 1158 } 1159 1160 TALLOC_FREE(dfs_refs); 1161 return NT_STATUS_OK; 1013 1162 } 1014 1163 … … 1031 1180 char *fullpath = NULL; 1032 1181 bool res; 1033 uint16 cnum;1182 uint16_t cnum; 1034 1183 char *newextrapath = NULL; 1035 1184 NTSTATUS status; 1185 const char *remote_name; 1036 1186 1037 1187 if (!cli || !sharename) { … … 1039 1189 } 1040 1190 1041 cnum = cli->cnum; 1191 remote_name = smbXcli_conn_remote_name(cli->conn); 1192 cnum = cli_state_get_tid(cli); 1042 1193 1043 1194 /* special case. never check for a referral on the IPC$ share */ … … 1049 1200 /* send a trans2_query_path_info to check for a referral */ 1050 1201 1051 fullpath = talloc_asprintf(ctx, "\\%s\\%s", cli->desthost, sharename);1202 fullpath = talloc_asprintf(ctx, "\\%s\\%s", remote_name, sharename); 1052 1203 if (!fullpath) { 1053 1204 return false; … … 1056 1207 /* check for the referral */ 1057 1208 1058 if (!NT_STATUS_IS_OK(cli_t con_andx(cli, "IPC$", "IPC", NULL, 0))) {1209 if (!NT_STATUS_IS_OK(cli_tree_connect(cli, "IPC$", "IPC", NULL, 0))) { 1059 1210 return false; 1060 1211 } … … 1064 1215 username, 1065 1216 password, 1066 lp_workgroup(),1217 domain, 1067 1218 "IPC$"); 1068 1219 if (!NT_STATUS_IS_OK(status)) { … … 1080 1231 } 1081 1232 1082 cli ->cnum = cnum;1233 cli_state_set_tid(cli, cnum); 1083 1234 1084 1235 if (!res || !num_refs) { … … 1097 1248 /* check that this is not a self-referral */ 1098 1249 1099 if (strequal( cli->desthost, *pp_newserver) &&1250 if (strequal(remote_name, *pp_newserver) && 1100 1251 strequal(sharename, *pp_newshare)) { 1101 1252 return false;
Note:
See TracChangeset
for help on using the changeset viewer.