From: Volker Lendecke Date: Thu, 25 Aug 2022 13:16:10 +0000 (+0200) Subject: smbXcli: Detect the SMB311 posix negotiate context X-Git-Tag: talloc-2.4.0~1229 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ae5dc52d23627e285214c92798f8412f265e9852;p=thirdparty%2Fsamba.git smbXcli: Detect the SMB311 posix negotiate context The server will only return this if the client requested in via smbXcli_negprot_send()'s in_ctx parameter. This adds knowledge about SMB2_CREATE_TAG_POSIX to smbXcli_base.c with a function to query it. The alternative would have been to detect this in the caller, but this would have meant that we also would need a smbXcli_conn_set_have_posix() function or something similar. Signed-off-by: Volker Lendecke Reviewed-by: Ralph Boehme --- diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c index 353b4816e3d..47f385349c4 100644 --- a/libcli/smb/smbXcli_base.c +++ b/libcli/smb/smbXcli_base.c @@ -130,6 +130,7 @@ struct smbXcli_conn { DATA_BLOB gss_blob; uint16_t sign_algo; uint16_t cipher; + bool smb311_posix; } server; uint64_t mid; @@ -500,6 +501,17 @@ bool smbXcli_conn_signing_mandatory(struct smbXcli_conn *conn) return conn->mandatory_signing; } +bool smbXcli_conn_have_posix(struct smbXcli_conn *conn) +{ + if (conn->protocol >= PROTOCOL_SMB3_11) { + return conn->smb2.server.smb311_posix; + } + if (conn->protocol <= PROTOCOL_NT1) { + return (conn->smb1.capabilities & CAP_UNIX); + } + return false; +} + /* * [MS-SMB] 2.2.2.3.5 - SMB1 support for passing through * query/set commands to the file system @@ -5024,6 +5036,7 @@ static void smbXcli_negprot_smb2_done(struct tevent_req *subreq) gnutls_hash_hd_t hash_hnd = NULL; struct smb2_negotiate_context *sign_algo = NULL; struct smb2_negotiate_context *cipher = NULL; + struct smb2_negotiate_context *posix = NULL; struct iovec sent_iov[3] = {{0}, {0}, {0}}; static const struct smb2cli_req_expected_response expected[] = { { @@ -5380,6 +5393,17 @@ static void smbXcli_negprot_smb2_done(struct tevent_req *subreq) conn->smb2.server.cipher = cipher_selected; } + posix = smb2_negotiate_context_find( + state->out_ctx, SMB2_POSIX_EXTENSIONS_AVAILABLE); + if (posix != NULL) { + DATA_BLOB posix_blob = data_blob_const( + SMB2_CREATE_TAG_POSIX, strlen(SMB2_CREATE_TAG_POSIX)); + int cmp = data_blob_cmp(&posix->data, &posix_blob); + + conn->smb2.server.smb311_posix = (cmp == 0); + } + + /* First we hash the request */ smb2cli_req_get_sent_iov(subreq, sent_iov); diff --git a/libcli/smb/smbXcli_base.h b/libcli/smb/smbXcli_base.h index 8e4fb81818f..8d2e6b3e204 100644 --- a/libcli/smb/smbXcli_base.h +++ b/libcli/smb/smbXcli_base.h @@ -53,6 +53,7 @@ bool smbXcli_conn_dfs_supported(struct smbXcli_conn *conn); enum protocol_types smbXcli_conn_protocol(struct smbXcli_conn *conn); bool smbXcli_conn_use_unicode(struct smbXcli_conn *conn); bool smbXcli_conn_signing_mandatory(struct smbXcli_conn *conn); +bool smbXcli_conn_have_posix(struct smbXcli_conn *conn); bool smbXcli_conn_support_passthrough(struct smbXcli_conn *conn); void smbXcli_conn_set_sockopt(struct smbXcli_conn *conn, const char *options);