]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
smbd: compare Open.ClientGuid against Client.ClientGuid in DH reconnect
authorRalph Boehme <slow@samba.org>
Wed, 26 Feb 2025 14:28:53 +0000 (15:28 +0100)
committerRalph Boehme <slow@samba.org>
Fri, 6 Jun 2025 16:16:34 +0000 (16:16 +0000)
This implements the check from MS-SMB2 3.3.5.9.7 "Handling the
SMB2_CREATE_DURABLE_HANDLE_RECONNECT Create Context".

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15649
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15651

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
source3/smbd/smb2_create.c
source3/smbd/smbXsrv_open.c
source3/smbd/smbXsrv_open.h

index d82018519c50a47edef95e5eecce779e68b1aa2f..6f4f3ed47de382ea6567a8c318e7fed3d6db419e 100644 (file)
@@ -1096,11 +1096,16 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
        if (state->do_durable_reconnect) {
                DATA_BLOB new_cookie = data_blob_null;
                NTTIME now = timeval_to_nttime(&smb2req->request_time);
+               const struct smb2_lease_key *lease_key = NULL;
 
+               if (state->lease_ptr != NULL) {
+                       lease_key = &state->lease_ptr->lease_key;
+               }
                status = smb2srv_open_recreate(smb2req->xconn,
                                               smb1req->conn->session_info,
                                               state->persistent_id,
                                               state->create_guid,
+                                              lease_key,
                                               now,
                                               &state->op);
                if (tevent_req_nterror(req, status)) {
index 6fd64a028c952385569026c306e1c15aa9d5cb71..6001b4bd09f4cb7864eb4dfcafd0b86192ef412a 100644 (file)
@@ -35,6 +35,7 @@
 #include "source3/include/util_tdb.h"
 #include "lib/util/idtree_random.h"
 #include "lib/util/time_basic.h"
+#include "../librpc/gen_ndr/ndr_smb2_lease_struct.h"
 
 struct smbXsrv_open_table {
        struct {
@@ -1159,7 +1160,9 @@ NTSTATUS smb2srv_open_lookup_replay_cache(struct smbXsrv_connection *conn,
 
 struct smb2srv_open_recreate_state {
        struct smbXsrv_open *op;
+       const struct GUID *client_guid;
        const struct GUID *create_guid;
+       const struct smb2_lease_key *lease_key;
        struct security_token *current_token;
        struct server_id me;
 
@@ -1172,6 +1175,7 @@ static void smb2srv_open_recreate_fn(
        struct smb2srv_open_recreate_state *state = private_data;
        TDB_DATA key = dbwrap_record_get_key(rec);
        struct smbXsrv_open_global0 *global = NULL;
+       struct GUID_txt_buf buf1, buf2;
 
        state->status = smbXsrv_open_global_verify_record(
                key, oldval, state->op, &state->op->global);
@@ -1184,6 +1188,16 @@ static void smb2srv_open_recreate_fn(
        }
        global = state->op->global;
 
+       if (state->lease_key != NULL &&
+           !GUID_equal(&global->client_guid, state->client_guid))
+       {
+               DBG_NOTICE("client guid: %s != %s in %s\n",
+                          GUID_buf_string(&global->client_guid, &buf1),
+                          GUID_buf_string(state->client_guid, &buf2),
+                          tdb_data_dbg(key));
+               goto not_found;
+       }
+
        /*
         * If the provided create_guid is NULL, this means that
         * the reconnect request was a v1 request. In that case
@@ -1192,7 +1206,6 @@ static void smb2srv_open_recreate_fn(
         */
        if ((state->create_guid != NULL) &&
            !GUID_equal(&global->create_guid, state->create_guid)) {
-               struct GUID_txt_buf buf1, buf2;
                DBG_NOTICE("%s != %s in %s\n",
                           GUID_buf_string(&global->create_guid, &buf1),
                           GUID_buf_string(state->create_guid, &buf2),
@@ -1237,12 +1250,15 @@ NTSTATUS smb2srv_open_recreate(struct smbXsrv_connection *conn,
                               struct auth_session_info *session_info,
                               uint64_t persistent_id,
                               const struct GUID *create_guid,
+                              const struct smb2_lease_key *lease_key,
                               NTTIME now,
                               struct smbXsrv_open **_open)
 {
        struct smbXsrv_open_table *table = conn->client->open_table;
        struct smb2srv_open_recreate_state state = {
+               .client_guid = &conn->client->global->client_guid,
                .create_guid = create_guid,
+               .lease_key = lease_key,
                .me = messaging_server_id(conn->client->msg_ctx),
        };
        struct smbXsrv_open_global_key_buf key_buf;
index 0257650123792bad05f3857784c3a5fa16ecdf1e..58e585888e29340cf5ebc6c368e2acb86565b7ad 100644 (file)
@@ -58,10 +58,12 @@ NTSTATUS smb2srv_open_lookup_replay_cache(struct smbXsrv_connection *conn,
                                          const char *name,
                                          NTTIME now,
                                          struct smbXsrv_open **_open);
+struct smb2_lease_key;
 NTSTATUS smb2srv_open_recreate(struct smbXsrv_connection *conn,
                               struct auth_session_info *session_info,
                               uint64_t persistent_id,
                               const struct GUID *create_guid,
+                              const struct smb2_lease_key *lease_key,
                               NTTIME now,
                               struct smbXsrv_open **_open);