smbd: Don't pass lease_idx down to set_share_mode()
authorVolker Lendecke <vl@samba.org>
Tue, 18 Sep 2018 09:31:27 +0000 (11:31 +0200)
committerChristof Schmitt <cs@samba.org>
Sun, 14 Apr 2019 04:01:32 +0000 (04:01 +0000)
Temporary patch to keep the code running. The new code in set_share_mode() will
leave again once the patchset to remove share_mode_lease and thus the lease_idx
in share_mode_entry goes away.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Christof Schmitt <cs@samba.org>
source3/locking/locking.c
source3/locking/proto.h
source3/smbd/open.c

index db20a5a1c9019e655da493229b7700c164a41397..ddae920398683f6bb7135e16476723a9b1bda494 100644 (file)
@@ -812,18 +812,17 @@ void remove_stale_share_mode_entries(struct share_mode_data *d)
        }
 }
 
-bool set_share_mode(struct share_mode_lock *lck, struct files_struct *fsp,
-                   uid_t uid, uint64_t mid, uint16_t op_type,
-                   uint32_t lease_idx)
+bool set_share_mode(struct share_mode_lock *lck,
+                   struct files_struct *fsp,
+                   uid_t uid,
+                   uint64_t mid,
+                   uint16_t op_type,
+                   const struct GUID *client_guid,
+                   const struct smb2_lease_key *lease_key)
 {
        struct share_mode_data *d = lck->data;
        struct share_mode_entry *tmp, *e;
 
-       if ((lease_idx != UINT32_MAX) &&
-           (lease_idx >= d->num_leases)) {
-               return false;
-       }
-
        tmp = talloc_realloc(d, d->share_modes, struct share_mode_entry,
                             d->num_share_modes+1);
        if (tmp == NULL) {
@@ -841,11 +840,41 @@ bool set_share_mode(struct share_mode_lock *lck, struct files_struct *fsp,
        e->access_mask = fsp->access_mask;
        e->op_mid = mid;
        e->op_type = op_type;
-       e->lease_idx = lease_idx;
-       if (lease_idx != UINT32_MAX) {
-               e->client_guid = lck->data->leases[lease_idx].client_guid;
-               e->lease_key = lck->data->leases[lease_idx].lease_key;
+
+       if (op_type == LEASE_OPLOCK) {
+               uint32_t i;
+
+               e->client_guid = *client_guid;
+               e->lease_key = *lease_key;
+
+               /*
+                * Need to set lease_idx. This is essentially
+                * find_share_mode_lease(), but that will go away
+                * soon. So don't add the dependency here.
+                */
+
+               for (i=0; i<d->num_leases; i++) {
+                       struct share_mode_lease *l = &d->leases[i];
+
+                       if (smb2_lease_equal(client_guid,
+                                            lease_key,
+                                            &l->client_guid,
+                                            &l->lease_key)) {
+                               break;
+                       }
+               }
+
+               if (i == d->num_leases) {
+                       DBG_WARNING("lease not found\n");
+                       d->num_share_modes -= 1;
+                       return false;
+               }
+
+               e->lease_idx = i;
+       } else {
+               e->lease_idx = UINT32_MAX;
        }
+
        e->time.tv_sec = fsp->open_time.tv_sec;
        e->time.tv_usec = fsp->open_time.tv_usec;
        e->share_file_id = fsp->fh->gen_id;
index 22b79669ff0e638a7f8487a595a03dfe04115a9a..c021d978d449141f1d650a151d23d819dbc922bf 100644 (file)
@@ -173,9 +173,13 @@ void get_file_infos(struct file_id id,
                    struct timespec *write_time);
 bool is_valid_share_mode_entry(const struct share_mode_entry *e);
 bool share_mode_stale_pid(struct share_mode_data *d, uint32_t idx);
-bool set_share_mode(struct share_mode_lock *lck, struct files_struct *fsp,
-                   uid_t uid, uint64_t mid, uint16_t op_type,
-                   uint32_t lease_idx);
+bool set_share_mode(struct share_mode_lock *lck,
+                   struct files_struct *fsp,
+                   uid_t uid,
+                   uint64_t mid,
+                   uint16_t op_type,
+                   const struct GUID *client_guid,
+                   const struct smb2_lease_key *lease_key);
 struct share_mode_entry *find_share_mode_entry(struct share_mode_lock *lck,
                                               files_struct *fsp);
 void remove_stale_share_mode_entries(struct share_mode_data *d);
index 9c1088424214432ebba60b8a8452782335b37f43..412174b7f3c80a6b743e1976210c4b40a125ab61 100644 (file)
@@ -2241,6 +2241,8 @@ static NTSTATUS grant_fsp_oplock_type(struct smb_request *req,
        uint32_t i;
        uint32_t granted;
        uint32_t lease_idx = UINT32_MAX;
+       const struct GUID *client_guid = NULL;
+       const struct smb2_lease_key *lease_key = NULL;
        bool ok;
        NTSTATUS status;
 
@@ -2338,6 +2340,10 @@ static NTSTATUS grant_fsp_oplock_type(struct smb_request *req,
 
                }
                *lease = fsp->lease->lease;
+
+               lease_key = &fsp->lease->lease.lease_key;
+               client_guid = fsp_client_guid(fsp);
+
                DEBUG(10, ("lease_state=%d\n", lease->lease_state));
        } else {
                if (got_handle_lease) {
@@ -2355,10 +2361,14 @@ static NTSTATUS grant_fsp_oplock_type(struct smb_request *req,
                }
        }
 
-       ok = set_share_mode(lck, fsp, get_current_uid(fsp->conn),
-                           req ? req->mid : 0,
-                           fsp->oplock_type,
-                           lease_idx);
+       ok = set_share_mode(
+               lck,
+               fsp,
+               get_current_uid(fsp->conn),
+               req ? req->mid : 0,
+               fsp->oplock_type,
+               client_guid,
+               lease_key);
        if (!ok) {
                return NT_STATUS_NO_MEMORY;
        }
@@ -4323,9 +4333,14 @@ static NTSTATUS open_directory(connection_struct *conn,
                return status;
        }
 
-       ok = set_share_mode(lck, fsp, get_current_uid(conn),
-                           req ? req->mid : 0, NO_OPLOCK,
-                           UINT32_MAX);
+       ok = set_share_mode(
+               lck,
+               fsp,
+               get_current_uid(conn),
+               req ? req->mid : 0,
+               NO_OPLOCK,
+               NULL,
+               NULL);
        if (!ok) {
                TALLOC_FREE(lck);
                fd_close(fsp);