smbd: Don't pass lease_idx down to set_share_mode()
[gd/samba-autobuild/.git] / source3 / locking / locking.c
index e9bec6d763ec1af6dbf63c2c3004040887aa8325..ddae920398683f6bb7135e16476723a9b1bda494 100644 (file)
@@ -150,6 +150,9 @@ bool strict_lock_check_default(files_struct *fsp, struct lock_struct *plock)
                 * autocleanup. This is the slow path anyway.
                 */
                br_lck = brl_get_locks(talloc_tos(), fsp);
+               if (br_lck == NULL) {
+                       return true;
+               }
                ret = brl_locktest(br_lck, plock);
                TALLOC_FREE(br_lck);
        }
@@ -657,8 +660,6 @@ bool is_valid_share_mode_entry(const struct share_mode_entry *e)
 static void remove_share_mode_lease(struct share_mode_data *d,
                                    struct share_mode_entry *e)
 {
-       struct GUID client_guid;
-       struct smb2_lease_key lease_key;
        uint16_t op_type;
        uint32_t lease_idx;
        uint32_t i;
@@ -681,14 +682,19 @@ static void remove_share_mode_lease(struct share_mode_data *d,
        e->lease_idx = UINT32_MAX;
 
        for (i=0; i<d->num_share_modes; i++) {
-               if (d->share_modes[i].stale) {
+               struct share_mode_entry *e2 = &d->share_modes[i];
+
+               if (e2->stale) {
                        continue;
                }
-               if (e == &d->share_modes[i]) {
+               if (e == e2) {
                        /* Not ourselves. */
                        continue;
                }
-               if (d->share_modes[i].lease_idx == lease_idx) {
+               if (smb2_lease_equal(&e->client_guid,
+                                    &e->lease_key,
+                                    &e2->client_guid,
+                                    &e2->lease_key)) {
                        break;
                }
        }
@@ -699,11 +705,6 @@ static void remove_share_mode_lease(struct share_mode_data *d,
                return;
        }
 
-       memcpy(&client_guid,
-               &d->leases[lease_idx].client_guid,
-               sizeof(client_guid));
-       lease_key = d->leases[lease_idx].lease_key;
-
        d->num_leases -= 1;
        d->leases[lease_idx] = d->leases[d->num_leases];
 
@@ -719,9 +720,9 @@ static void remove_share_mode_lease(struct share_mode_data *d,
        {
                NTSTATUS status;
 
-               status = leases_db_del(&client_guid,
-                                       &lease_key,
-                                       &d->id);
+               status = leases_db_del(&e->client_guid,
+                                      &e->lease_key,
+                                      &d->id);
 
                DEBUG(10, ("%s: leases_db_del returned %s\n", __func__,
                           nt_errstr(status)));
@@ -805,24 +806,23 @@ void remove_stale_share_mode_entries(struct share_mode_data *d)
                        struct share_mode_entry *m = d->share_modes;
                        m[i] = m[d->num_share_modes-1];
                        d->num_share_modes -= 1;
-               } else {
-                       i += 1;
+                       continue;
                }
+               i += 1;
        }
 }
 
-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) {
@@ -840,7 +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 (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;
@@ -879,8 +913,7 @@ struct share_mode_entry *find_share_mode_entry(
 }
 
 /*******************************************************************
- Del the share mode of a file for this process. Return the number of
- entries left.
+ Del the share mode of a file for this process.
 ********************************************************************/
 
 bool del_share_mode(struct share_mode_lock *lck, files_struct *fsp)
@@ -970,86 +1003,6 @@ bool downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
        return True;
 }
 
-NTSTATUS downgrade_share_lease(struct smbd_server_connection *sconn,
-                              struct share_mode_lock *lck,
-                              const struct smb2_lease_key *key,
-                              uint32_t new_lease_state,
-                              struct share_mode_lease **_l)
-{
-       struct share_mode_data *d = lck->data;
-       struct share_mode_lease *l;
-       uint32_t i;
-
-       *_l = NULL;
-
-       for (i=0; i<d->num_leases; i++) {
-               if (smb2_lease_equal(&sconn->client->connections->smb2.client.guid,
-                                    key,
-                                    &d->leases[i].client_guid,
-                                    &d->leases[i].lease_key)) {
-                       break;
-               }
-       }
-       if (i == d->num_leases) {
-               DEBUG(10, ("lease not found\n"));
-               return NT_STATUS_INVALID_PARAMETER;
-       }
-
-       l = &d->leases[i];
-
-       if (!l->breaking) {
-               DEBUG(1, ("Attempt to break from %d to %d - but we're not in breaking state\n",
-                          (int)l->current_state, (int)new_lease_state));
-               return NT_STATUS_UNSUCCESSFUL;
-       }
-
-       /*
-        * Can't upgrade anything: l->breaking_to_requested (and l->current_state)
-        * must be a strict bitwise superset of new_lease_state
-        */
-       if ((new_lease_state & l->breaking_to_requested) != new_lease_state) {
-               DEBUG(1, ("Attempt to upgrade from %d to %d - expected %d\n",
-                          (int)l->current_state, (int)new_lease_state,
-                          (int)l->breaking_to_requested));
-               return NT_STATUS_REQUEST_NOT_ACCEPTED;
-       }
-
-       if (l->current_state != new_lease_state) {
-               l->current_state = new_lease_state;
-               d->modified = true;
-       }
-
-       if ((new_lease_state & ~l->breaking_to_required) != 0) {
-               DEBUG(5, ("lease state %d not fully broken from %d to %d\n",
-                          (int)new_lease_state,
-                          (int)l->current_state,
-                          (int)l->breaking_to_required));
-               l->breaking_to_requested = l->breaking_to_required;
-               if (l->current_state & (~SMB2_LEASE_READ)) {
-                       /*
-                        * Here we break in steps, as windows does
-                        * see the breaking3 and v2_breaking3 tests.
-                        */
-                       l->breaking_to_requested |= SMB2_LEASE_READ;
-               }
-               d->modified = true;
-               *_l = l;
-               return NT_STATUS_OPLOCK_BREAK_IN_PROGRESS;
-       }
-
-       DEBUG(10, ("breaking from %d to %d - expected %d\n",
-                  (int)l->current_state, (int)new_lease_state,
-                  (int)l->breaking_to_requested));
-
-       l->breaking_to_requested = 0;
-       l->breaking_to_required = 0;
-       l->breaking = false;
-
-       d->modified = true;
-
-       return NT_STATUS_OK;
-}
-
 /****************************************************************************
  Adds a delete on close token.
 ****************************************************************************/