Revert "TODO: s3:smb2:durable: get up-to-date stat in vfs_default_durable_disconnect"
[metze/samba/wip.git] / source3 / smbd / durable.c
index 15d70058c6e2ea11a02f513af26b63b9d54282cc..f39a365242c963d0443109084b2a0a15b000d33e 100644 (file)
@@ -121,7 +121,6 @@ NTSTATUS vfs_default_durable_cookie(struct files_struct *fsp,
        cookie.stat_info.st_ex_blocks = fsp->fsp_name->st.st_ex_blocks;
        cookie.stat_info.st_ex_flags = fsp->fsp_name->st.st_ex_flags;
        cookie.stat_info.st_ex_mask = fsp->fsp_name->st.st_ex_mask;
-       cookie.stat_info.vfs_private = fsp->fsp_name->st.vfs_private;
 
        ndr_err = ndr_push_struct_blob(cookie_blob, mem_ctx, &cookie,
                        (ndr_push_flags_fn_t)ndr_push_vfs_default_durable_cookie);
@@ -169,7 +168,7 @@ NTSTATUS vfs_default_durable_disconnect(struct files_struct *fsp,
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       if (!BATCH_OPLOCK_TYPE(fsp->oplock_type)) {
+       if ((fsp_lease_type(fsp) & SMB2_LEASE_HANDLE) == 0) {
                return NT_STATUS_NOT_SUPPORTED;
        }
 
@@ -275,7 +274,6 @@ NTSTATUS vfs_default_durable_disconnect(struct files_struct *fsp,
        cookie.stat_info.st_ex_blocks = fsp->fsp_name->st.st_ex_blocks;
        cookie.stat_info.st_ex_flags = fsp->fsp_name->st.st_ex_flags;
        cookie.stat_info.st_ex_mask = fsp->fsp_name->st.st_ex_mask;
-       cookie.stat_info.vfs_private = fsp->fsp_name->st.vfs_private;
 
        ndr_err = ndr_push_struct_blob(&new_cookie_blob, mem_ctx, &cookie,
                        (ndr_push_flags_fn_t)ndr_push_vfs_default_durable_cookie);
@@ -536,18 +534,6 @@ static bool vfs_default_durable_reconnect_check_stat(
                return false;
        }
 
-       if (cookie_st->vfs_private != fsp_st->vfs_private) {
-               DEBUG(1, ("vfs_default_durable_reconnect (%s): "
-                         "stat_ex.%s differs: "
-                         "cookie:%llu != stat:%llu, "
-                         "denying durable reconnect\n",
-                         name,
-                         "vfs_private",
-                         (unsigned long long)cookie_st->vfs_private,
-                         (unsigned long long)fsp_st->vfs_private));
-               return false;
-       }
-
        return true;
 }
 
@@ -612,8 +598,11 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
        }
 
        /* Create an smb_filename with stream_name == NULL. */
-       smb_fname = synthetic_smb_fname(talloc_tos(), cookie.base_name,
-                                       NULL, NULL);
+       smb_fname = synthetic_smb_fname(talloc_tos(),
+                                       cookie.base_name,
+                                       NULL,
+                                       NULL,
+                                       0);
        if (smb_fname == NULL) {
                return NT_STATUS_NO_MEMORY;
        }
@@ -717,6 +706,7 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
        fsp->share_access = e->share_access;
        fsp->can_read = ((fsp->access_mask & (FILE_READ_DATA)) != 0);
        fsp->can_write = ((fsp->access_mask & (FILE_WRITE_DATA|FILE_APPEND_DATA)) != 0);
+       fsp->fnum = op->local_id;
 
        /*
         * TODO:
@@ -737,6 +727,32 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
        fsp->aio_write_behind = false;
        fsp->oplock_type = e->op_type;
 
+       if (fsp->oplock_type == LEASE_OPLOCK) {
+               struct share_mode_lease *l = &lck->data->leases[e->lease_idx];
+               struct smb2_lease_key key;
+
+               key.data[0] = l->lease_key.data[0];
+               key.data[1] = l->lease_key.data[1];
+
+               fsp->lease = find_fsp_lease(fsp, &key, l);
+               if (fsp->lease == NULL) {
+                       TALLOC_FREE(lck);
+                       fsp_free(fsp);
+                       return NT_STATUS_NO_MEMORY;
+               }
+
+               /*
+                * Ensure the existing client guid matches the
+                * stored one in the share_mode_lease.
+                */
+               if (!GUID_equal(fsp_client_guid(fsp),
+                               &l->client_guid)) {
+                       TALLOC_FREE(lck);
+                       fsp_free(fsp);
+                       return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+               }
+       }
+
        fsp->initial_allocation_size = cookie.initial_allocation_size;
        fsp->fh->position_information = cookie.position_information;
        fsp->update_write_time_triggered = cookie.update_write_time_triggered;
@@ -864,7 +880,7 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
                return NT_STATUS_OBJECT_NAME_NOT_FOUND;
        }
 
-       status = set_file_oplock(fsp, fsp->oplock_type);
+       status = set_file_oplock(fsp);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(1, ("vfs_default_durable_reconnect failed to set oplock "
                          "after opening file: %s\n", nt_errstr(status)));