diff options
-rw-r--r-- | source3/libsmb/clidfs.c | 73 |
1 files changed, 56 insertions, 17 deletions
diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 2e4a3b8ef1..ff48719c76 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -645,9 +645,7 @@ NTSTATUS cli_dfs_get_referral(TALLOC_CTX *ctx, size_t *num_refs, size_t *consumed) { - unsigned int data_len = 0; unsigned int param_len = 0; - uint16_t setup[1]; uint16_t recv_flags2; uint8_t *param = NULL; uint8_t *rdata = NULL; @@ -664,8 +662,6 @@ NTSTATUS cli_dfs_get_referral(TALLOC_CTX *ctx, *num_refs = 0; *refs = NULL; - SSVAL(setup, 0, TRANSACT2_GET_DFS_REFERRAL); - param = talloc_array(talloc_tos(), uint8_t, 2); if (!param) { status = NT_STATUS_NO_MEMORY; @@ -683,20 +679,63 @@ NTSTATUS cli_dfs_get_referral(TALLOC_CTX *ctx, param_len = talloc_get_size(param); path_ucs = (smb_ucs2_t *)¶m[2]; - status = cli_trans(talloc_tos(), cli, SMBtrans2, - NULL, 0xffff, 0, 0, - setup, 1, 0, - param, param_len, 2, - NULL, 0, CLI_BUFFER_SIZE, - &recv_flags2, - NULL, 0, NULL, /* rsetup */ - NULL, 0, NULL, - &rdata, 4, &data_len); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } + if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) { + DATA_BLOB in_input_buffer; + DATA_BLOB in_output_buffer = data_blob_null; + DATA_BLOB out_input_buffer = data_blob_null; + DATA_BLOB out_output_buffer = data_blob_null; + + in_input_buffer.data = param; + in_input_buffer.length = param_len; + + status = smb2cli_ioctl(cli->conn, + cli->timeout, + cli->smb2.session, + cli->smb2.tcon, + UINT64_MAX, /* in_fid_persistent */ + UINT64_MAX, /* in_fid_volatile */ + FSCTL_DFS_GET_REFERRALS, + 0, /* in_max_input_length */ + &in_input_buffer, + CLI_BUFFER_SIZE, /* in_max_output_length */ + &in_output_buffer, + SMB2_IOCTL_FLAG_IS_FSCTL, + talloc_tos(), + &out_input_buffer, + &out_output_buffer); + if (!NT_STATUS_IS_OK(status)) { + goto out; + } - endp = (char *)rdata + data_len; + if (out_output_buffer.length < 4) { + status = NT_STATUS_INVALID_NETWORK_RESPONSE; + goto out; + } + + recv_flags2 = FLAGS2_UNICODE_STRINGS; + rdata = out_output_buffer.data; + endp = (char *)rdata + out_output_buffer.length; + } else { + unsigned int data_len = 0; + uint16_t setup[1]; + + SSVAL(setup, 0, TRANSACT2_GET_DFS_REFERRAL); + + status = cli_trans(talloc_tos(), cli, SMBtrans2, + NULL, 0xffff, 0, 0, + setup, 1, 0, + param, param_len, 2, + NULL, 0, CLI_BUFFER_SIZE, + &recv_flags2, + NULL, 0, NULL, /* rsetup */ + NULL, 0, NULL, + &rdata, 4, &data_len); + if (!NT_STATUS_IS_OK(status)) { + goto out; + } + + endp = (char *)rdata + data_len; + } consumed_ucs = SVAL(rdata, 0); num_referrals = SVAL(rdata, 2); |