summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Beale <timbeale@catalyst.net.nz>2019-01-07 15:28:12 +1300
committerKarolin Seeger <kseeger@samba.org>2019-02-01 11:32:46 +0100
commitdf175f06f9fb63a04ae7635d6d0cbcbfe8ef2ceb (patch)
tree13321660da45f367cebdb280ee0476289abaa8e5
parentbb76511f41355b7d3a8a20b69d86eaeb89ebe0e5 (diff)
downloadsamba-df175f06f9fb63a04ae7635d6d0cbcbfe8ef2ceb.tar.gz
s3:libsmb: cli_smb2_list() can sometimes fail initially on a connection
cli_smb2_list() appears to be a slightly unique SMB operation in that it specifies the max transaction size for the response buffer size. The Python bindings highlighted a problem where if cli_smb2_list() were one of the first operations performed on the SMBv2 connection, it would fail due to insufficient credits. Because the response buffer size is (potentially) so much larger, it requires more credits (128) compared with other SMB operations. When talking to a samba DC, the connection credits seem to start off at 1, then increase by 32 for every SMB reply we receive back from the server. After cli_full_connection(), the connection has 65 credits. The cli_smb2_create_fnum() in cli_smb2_list() adds another 32 credits, but this is still less than the 128 that smb2cli_query_directory() requires. This problem doesn't happen for smbclient because the cli_cm_open() API it uses ends up sending more messages, and so the connection has more credits. This patch changes cli_smb2_list(), so it requests a smaller response buffer size if it doesn't have enough credits available for the max transaction size. smb2cli_query_directory() is already in a loop, so it can span multiple SMB messages if for some reason the transaction size isn't big enough for the listings. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13736 Signed-off-by: Tim Beale <timbeale@catalyst.net.nz> Reviewed-by: Stefan Metzmacher <metze@samba.org> Autobuild-User(master): Stefan Metzmacher <metze@samba.org> Autobuild-Date(master): Thu Jan 10 02:40:16 CET 2019 on sn-devel-144 (cherry picked from commit fd355dff906f5f4832901bce76544f1a4e50c33d)
-rw-r--r--source3/libsmb/cli_smb2_fnum.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/source3/libsmb/cli_smb2_fnum.c b/source3/libsmb/cli_smb2_fnum.c
index de0ddb4e0dd..176b58d160a 100644
--- a/source3/libsmb/cli_smb2_fnum.c
+++ b/source3/libsmb/cli_smb2_fnum.c
@@ -910,7 +910,9 @@ NTSTATUS cli_smb2_list(struct cli_state *cli,
TALLOC_CTX *frame = talloc_stackframe();
TALLOC_CTX *subframe = NULL;
bool mask_has_wild;
- uint32_t max_trans = smb2cli_conn_max_trans_size(cli->conn);
+ uint32_t max_trans;
+ uint32_t max_avail_len;
+ bool ok;
if (smbXcli_conn_has_async_calls(cli->conn)) {
/*
@@ -958,6 +960,16 @@ NTSTATUS cli_smb2_list(struct cli_state *cli,
goto fail;
}
+ /*
+ * ideally, use the max transaction size, but don't send a request
+ * bigger than we have credits available for
+ */
+ max_trans = smb2cli_conn_max_trans_size(cli->conn);
+ ok = smb2cli_conn_req_possible(cli->conn, &max_avail_len);
+ if (ok) {
+ max_trans = MIN(max_trans, max_avail_len);
+ }
+
do {
uint8_t *dir_data = NULL;
uint32_t dir_data_length = 0;