]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
smbXcli: Detect the SMB311 posix negotiate context
authorVolker Lendecke <vl@samba.org>
Thu, 25 Aug 2022 13:16:10 +0000 (15:16 +0200)
committerRalph Boehme <slow@samba.org>
Fri, 2 Sep 2022 13:31:38 +0000 (13:31 +0000)
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 <vl@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
libcli/smb/smbXcli_base.c
libcli/smb/smbXcli_base.h

index 353b4816e3dfea4b134345cd1e72cc8dfdc93818..47f385349c4124222e8996ad0461c79782b30664 100644 (file)
@@ -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);
 
index 8e4fb81818fcf7472fa50507aad03d3ad21aaf9f..8d2e6b3e204114fa953918164ca03c6796b2c7ac 100644 (file)
@@ -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);