s3:locking: add downgrade_share_lease() helper function
[obnox/samba/samba-obnox.git] / source3 / locking / locking.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Locking functions
4    Copyright (C) Andrew Tridgell 1992-2000
5    Copyright (C) Jeremy Allison 1992-2006
6    Copyright (C) Volker Lendecke 2005
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
21    Revision History:
22
23    12 aug 96: Erik.Devriendt@te6.siemens.be
24    added support for shared memory implementation of share mode locking
25
26    May 1997. Jeremy Allison (jallison@whistle.com). Modified share mode
27    locking to deal with multiple share modes per open file.
28
29    September 1997. Jeremy Allison (jallison@whistle.com). Added oplock
30    support.
31
32    rewritten completely to use new tdb code. Tridge, Dec '99
33
34    Added POSIX locking support. Jeremy Allison (jeremy@valinux.com), Apr. 2000.
35    Added Unix Extensions POSIX locking support. Jeremy Allison Mar 2006.
36 */
37
38 #include "includes.h"
39 #include "system/filesys.h"
40 #include "locking/proto.h"
41 #include "smbd/globals.h"
42 #include "dbwrap/dbwrap.h"
43 #include "dbwrap/dbwrap_open.h"
44 #include "../libcli/security/security.h"
45 #include "serverid.h"
46 #include "messages.h"
47 #include "util_tdb.h"
48 #include "../librpc/gen_ndr/ndr_open_files.h"
49 #include "locking/leases_db.h"
50
51 #undef DBGC_CLASS
52 #define DBGC_CLASS DBGC_LOCKING
53
54 #define NO_LOCKING_COUNT (-1)
55
56 /****************************************************************************
57  Debugging aids :-).
58 ****************************************************************************/
59
60 const char *lock_type_name(enum brl_type lock_type)
61 {
62         switch (lock_type) {
63                 case READ_LOCK:
64                         return "READ";
65                 case WRITE_LOCK:
66                         return "WRITE";
67                 case PENDING_READ_LOCK:
68                         return "PENDING_READ";
69                 case PENDING_WRITE_LOCK:
70                         return "PENDING_WRITE";
71                 default:
72                         return "other";
73         }
74 }
75
76 const char *lock_flav_name(enum brl_flavour lock_flav)
77 {
78         return (lock_flav == WINDOWS_LOCK) ? "WINDOWS_LOCK" : "POSIX_LOCK";
79 }
80
81 /****************************************************************************
82  Utility function called to see if a file region is locked.
83  Called in the read/write codepath.
84 ****************************************************************************/
85
86 void init_strict_lock_struct(files_struct *fsp,
87                                 uint64_t smblctx,
88                                 br_off start,
89                                 br_off size,
90                                 enum brl_type lock_type,
91                                 struct lock_struct *plock)
92 {
93         SMB_ASSERT(lock_type == READ_LOCK || lock_type == WRITE_LOCK);
94
95         plock->context.smblctx = smblctx;
96         plock->context.tid = fsp->conn->cnum;
97         plock->context.pid = messaging_server_id(fsp->conn->sconn->msg_ctx);
98         plock->start = start;
99         plock->size = size;
100         plock->fnum = fsp->fnum;
101         plock->lock_type = lock_type;
102         plock->lock_flav = lp_posix_cifsu_locktype(fsp);
103 }
104
105 bool strict_lock_default(files_struct *fsp, struct lock_struct *plock)
106 {
107         struct byte_range_lock *br_lck;
108         int strict_locking = lp_strict_locking(fsp->conn->params);
109         bool ret = False;
110
111         if (plock->size == 0) {
112                 return True;
113         }
114
115         if (!lp_locking(fsp->conn->params) || !strict_locking) {
116                 return True;
117         }
118
119         if (strict_locking == Auto) {
120                 if  (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) &&
121                      (plock->lock_type == READ_LOCK ||
122                       plock->lock_type == WRITE_LOCK)) {
123                         DEBUG(10, ("is_locked: optimisation - exclusive oplock "
124                                    "on file %s\n", fsp_str_dbg(fsp)));
125                         return true;
126                 }
127                 if ((fsp->oplock_type == LEVEL_II_OPLOCK) &&
128                     (plock->lock_type == READ_LOCK)) {
129                         DEBUG(10, ("is_locked: optimisation - level II oplock "
130                                    "on file %s\n", fsp_str_dbg(fsp)));
131                         return true;
132                 }
133         }
134
135         br_lck = brl_get_locks_readonly(fsp);
136         if (!br_lck) {
137                 return true;
138         }
139         ret = brl_locktest(br_lck, plock);
140
141         if (!ret) {
142                 /*
143                  * We got a lock conflict. Retry with rw locks to enable
144                  * autocleanup. This is the slow path anyway.
145                  */
146                 br_lck = brl_get_locks(talloc_tos(), fsp);
147                 ret = brl_locktest(br_lck, plock);
148                 TALLOC_FREE(br_lck);
149         }
150
151         DEBUG(10, ("strict_lock_default: flavour = %s brl start=%ju "
152                    "len=%ju %s for fnum %ju file %s\n",
153                    lock_flav_name(plock->lock_flav),
154                    (uintmax_t)plock->start, (uintmax_t)plock->size,
155                    ret ? "unlocked" : "locked",
156                    (uintmax_t)plock->fnum, fsp_str_dbg(fsp)));
157
158         return ret;
159 }
160
161 void strict_unlock_default(files_struct *fsp, struct lock_struct *plock)
162 {
163 }
164
165 /****************************************************************************
166  Find out if a lock could be granted - return who is blocking us if we can't.
167 ****************************************************************************/
168
169 NTSTATUS query_lock(files_struct *fsp,
170                         uint64_t *psmblctx,
171                         uint64_t *pcount,
172                         uint64_t *poffset,
173                         enum brl_type *plock_type,
174                         enum brl_flavour lock_flav)
175 {
176         struct byte_range_lock *br_lck = NULL;
177
178         if (!fsp->can_lock) {
179                 return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
180         }
181
182         if (!lp_locking(fsp->conn->params)) {
183                 return NT_STATUS_OK;
184         }
185
186         br_lck = brl_get_locks_readonly(fsp);
187         if (!br_lck) {
188                 return NT_STATUS_NO_MEMORY;
189         }
190
191         return brl_lockquery(br_lck,
192                         psmblctx,
193                         messaging_server_id(fsp->conn->sconn->msg_ctx),
194                         poffset,
195                         pcount,
196                         plock_type,
197                         lock_flav);
198 }
199
200 static void increment_current_lock_count(files_struct *fsp,
201     enum brl_flavour lock_flav)
202 {
203         if (lock_flav == WINDOWS_LOCK &&
204             fsp->current_lock_count != NO_LOCKING_COUNT) {
205                 /* blocking ie. pending, locks also count here,
206                  * as this is an efficiency counter to avoid checking
207                  * the lock db. on close. JRA. */
208
209                 fsp->current_lock_count++;
210         } else {
211                 /* Notice that this has had a POSIX lock request.
212                  * We can't count locks after this so forget them.
213                  */
214                 fsp->current_lock_count = NO_LOCKING_COUNT;
215         }
216 }
217
218 static void decrement_current_lock_count(files_struct *fsp,
219     enum brl_flavour lock_flav)
220 {
221         if (lock_flav == WINDOWS_LOCK &&
222             fsp->current_lock_count != NO_LOCKING_COUNT) {
223                 SMB_ASSERT(fsp->current_lock_count > 0);
224                 fsp->current_lock_count--;
225         }
226 }
227
228 /****************************************************************************
229  Utility function called by locking requests.
230 ****************************************************************************/
231
232 struct byte_range_lock *do_lock(struct messaging_context *msg_ctx,
233                         files_struct *fsp,
234                         uint64_t smblctx,
235                         uint64_t count,
236                         uint64_t offset,
237                         enum brl_type lock_type,
238                         enum brl_flavour lock_flav,
239                         bool blocking_lock,
240                         NTSTATUS *perr,
241                         uint64_t *psmblctx)
242 {
243         struct byte_range_lock *br_lck = NULL;
244
245         /* silently return ok on print files as we don't do locking there */
246         if (fsp->print_file) {
247                 *perr = NT_STATUS_OK;
248                 return NULL;
249         }
250
251         if (!fsp->can_lock) {
252                 *perr = fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
253                 return NULL;
254         }
255
256         if (!lp_locking(fsp->conn->params)) {
257                 *perr = NT_STATUS_OK;
258                 return NULL;
259         }
260
261         /* NOTE! 0 byte long ranges ARE allowed and should be stored  */
262
263         DEBUG(10,("do_lock: lock flavour %s lock type %s start=%ju len=%ju "
264                 "blocking_lock=%s requested for %s file %s\n",
265                 lock_flav_name(lock_flav), lock_type_name(lock_type),
266                 (uintmax_t)offset, (uintmax_t)count, blocking_lock ? "true" :
267                 "false", fsp_fnum_dbg(fsp), fsp_str_dbg(fsp)));
268
269         br_lck = brl_get_locks(talloc_tos(), fsp);
270         if (!br_lck) {
271                 *perr = NT_STATUS_NO_MEMORY;
272                 return NULL;
273         }
274
275         *perr = brl_lock(msg_ctx,
276                         br_lck,
277                         smblctx,
278                         messaging_server_id(fsp->conn->sconn->msg_ctx),
279                         offset,
280                         count,
281                         lock_type,
282                         lock_flav,
283                         blocking_lock,
284                         psmblctx);
285
286         DEBUG(10, ("do_lock: returning status=%s\n", nt_errstr(*perr)));
287
288         increment_current_lock_count(fsp, lock_flav);
289         return br_lck;
290 }
291
292 /****************************************************************************
293  Utility function called by unlocking requests.
294 ****************************************************************************/
295
296 NTSTATUS do_unlock(struct messaging_context *msg_ctx,
297                         files_struct *fsp,
298                         uint64_t smblctx,
299                         uint64_t count,
300                         uint64_t offset,
301                         enum brl_flavour lock_flav)
302 {
303         bool ok = False;
304         struct byte_range_lock *br_lck = NULL;
305
306         if (!fsp->can_lock) {
307                 return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
308         }
309
310         if (!lp_locking(fsp->conn->params)) {
311                 return NT_STATUS_OK;
312         }
313
314         DEBUG(10, ("do_unlock: unlock start=%ju len=%ju requested for %s file "
315                    "%s\n", (uintmax_t)offset, (uintmax_t)count,
316                    fsp_fnum_dbg(fsp), fsp_str_dbg(fsp)));
317
318         br_lck = brl_get_locks(talloc_tos(), fsp);
319         if (!br_lck) {
320                 return NT_STATUS_NO_MEMORY;
321         }
322
323         ok = brl_unlock(msg_ctx,
324                         br_lck,
325                         smblctx,
326                         messaging_server_id(fsp->conn->sconn->msg_ctx),
327                         offset,
328                         count,
329                         lock_flav);
330
331         TALLOC_FREE(br_lck);
332
333         if (!ok) {
334                 DEBUG(10,("do_unlock: returning ERRlock.\n" ));
335                 return NT_STATUS_RANGE_NOT_LOCKED;
336         }
337
338         decrement_current_lock_count(fsp, lock_flav);
339         return NT_STATUS_OK;
340 }
341
342 /****************************************************************************
343  Cancel any pending blocked locks.
344 ****************************************************************************/
345
346 NTSTATUS do_lock_cancel(files_struct *fsp,
347                         uint64 smblctx,
348                         uint64_t count,
349                         uint64_t offset,
350                         enum brl_flavour lock_flav)
351 {
352         bool ok = False;
353         struct byte_range_lock *br_lck = NULL;
354
355         if (!fsp->can_lock) {
356                 return fsp->is_directory ?
357                         NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
358         }
359
360         if (!lp_locking(fsp->conn->params)) {
361                 return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
362         }
363
364         DEBUG(10, ("do_lock_cancel: cancel start=%ju len=%ju requested for "
365                    "%s file %s\n", (uintmax_t)offset, (uintmax_t)count,
366                    fsp_fnum_dbg(fsp), fsp_str_dbg(fsp)));
367
368         br_lck = brl_get_locks(talloc_tos(), fsp);
369         if (!br_lck) {
370                 return NT_STATUS_NO_MEMORY;
371         }
372
373         ok = brl_lock_cancel(br_lck,
374                         smblctx,
375                         messaging_server_id(fsp->conn->sconn->msg_ctx),
376                         offset,
377                         count,
378                         lock_flav);
379
380         TALLOC_FREE(br_lck);
381
382         if (!ok) {
383                 DEBUG(10,("do_lock_cancel: returning ERRcancelviolation.\n" ));
384                 return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
385         }
386
387         decrement_current_lock_count(fsp, lock_flav);
388         return NT_STATUS_OK;
389 }
390
391 /****************************************************************************
392  Remove any locks on this fd. Called from file_close().
393 ****************************************************************************/
394
395 void locking_close_file(struct messaging_context *msg_ctx,
396                         files_struct *fsp,
397                         enum file_close_type close_type)
398 {
399         struct byte_range_lock *br_lck;
400
401         if (!lp_locking(fsp->conn->params)) {
402                 return;
403         }
404
405         /* If we have no outstanding locks or pending
406          * locks then we don't need to look in the lock db.
407          */
408
409         if (fsp->current_lock_count == 0) {
410                 return;
411         }
412
413         br_lck = brl_get_locks(talloc_tos(),fsp);
414
415         if (br_lck) {
416                 cancel_pending_lock_requests_by_fid(fsp, br_lck, close_type);
417                 brl_close_fnum(msg_ctx, br_lck);
418                 TALLOC_FREE(br_lck);
419         }
420 }
421
422 /*******************************************************************
423  Print out a share mode.
424 ********************************************************************/
425
426 char *share_mode_str(TALLOC_CTX *ctx, int num, const struct share_mode_entry *e)
427 {
428         return talloc_asprintf(ctx, "share_mode_entry[%d]: "
429                  "pid = %s, share_access = 0x%x, private_options = 0x%x, "
430                  "access_mask = 0x%x, mid = 0x%llx, type= 0x%x, gen_id = %llu, "
431                  "uid = %u, flags = %u, file_id %s, name_hash = 0x%x",
432                  num,
433                  procid_str_static(&e->pid),
434                  e->share_access, e->private_options,
435                  e->access_mask, (unsigned long long)e->op_mid,
436                  e->op_type, (unsigned long long)e->share_file_id,
437                  (unsigned int)e->uid, (unsigned int)e->flags,
438                  file_id_string_tos(&e->id),
439                  (unsigned int)e->name_hash);
440 }
441
442 /*******************************************************************
443  Fetch a share mode where we know one MUST exist. This call reference
444  counts it internally to allow for nested lock fetches.
445 ********************************************************************/
446
447 struct share_mode_lock *get_existing_share_mode_lock(TALLOC_CTX *mem_ctx,
448                                                      const struct file_id id)
449 {
450         return get_share_mode_lock(mem_ctx, id, NULL, NULL, NULL);
451 }
452
453 /*******************************************************************
454  Sets the service name and filename for rename.
455  At this point we emit "file renamed" messages to all
456  process id's that have this file open.
457  Based on an initial code idea from SATOH Fumiyasu <fumiya@samba.gr.jp>
458 ********************************************************************/
459
460 bool rename_share_filename(struct messaging_context *msg_ctx,
461                         struct share_mode_lock *lck,
462                         struct file_id id,
463                         const char *servicepath,
464                         uint32_t orig_name_hash,
465                         uint32_t new_name_hash,
466                         const struct smb_filename *smb_fname_dst)
467 {
468         struct share_mode_data *d = lck->data;
469         size_t sp_len;
470         size_t bn_len;
471         size_t sn_len;
472         size_t msg_len;
473         char *frm = NULL;
474         int i;
475         bool strip_two_chars = false;
476         bool has_stream = smb_fname_dst->stream_name != NULL;
477         struct server_id self_pid = messaging_server_id(msg_ctx);
478
479         DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n",
480                    servicepath, smb_fname_dst->base_name));
481
482         /*
483          * rename_internal_fsp() and rename_internals() add './' to
484          * head of newname if newname does not contain a '/'.
485          */
486         if (smb_fname_dst->base_name[0] &&
487             smb_fname_dst->base_name[1] &&
488             smb_fname_dst->base_name[0] == '.' &&
489             smb_fname_dst->base_name[1] == '/') {
490                 strip_two_chars = true;
491         }
492
493         d->servicepath = talloc_strdup(d, servicepath);
494         d->base_name = talloc_strdup(d, smb_fname_dst->base_name +
495                                        (strip_two_chars ? 2 : 0));
496         d->stream_name = talloc_strdup(d, smb_fname_dst->stream_name);
497         if (d->base_name == NULL ||
498             (has_stream && d->stream_name == NULL) ||
499             d->servicepath == NULL) {
500                 DEBUG(0, ("rename_share_filename: talloc failed\n"));
501                 return False;
502         }
503         d->modified = True;
504
505         sp_len = strlen(d->servicepath);
506         bn_len = strlen(d->base_name);
507         sn_len = has_stream ? strlen(d->stream_name) : 0;
508
509         msg_len = MSG_FILE_RENAMED_MIN_SIZE + sp_len + 1 + bn_len + 1 +
510             sn_len + 1;
511
512         /* Set up the name changed message. */
513         frm = talloc_array(d, char, msg_len);
514         if (!frm) {
515                 return False;
516         }
517
518         push_file_id_24(frm, &id);
519
520         DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len ));
521
522         strlcpy(&frm[24],
523                 d->servicepath ? d->servicepath : "",
524                 sp_len+1);
525         strlcpy(&frm[24 + sp_len + 1],
526                 d->base_name ? d->base_name : "",
527                 bn_len+1);
528         strlcpy(&frm[24 + sp_len + 1 + bn_len + 1],
529                 d->stream_name ? d->stream_name : "",
530                 sn_len+1);
531
532         /* Send the messages. */
533         for (i=0; i<d->num_share_modes; i++) {
534                 struct share_mode_entry *se = &d->share_modes[i];
535                 if (!is_valid_share_mode_entry(se)) {
536                         continue;
537                 }
538
539                 /* If this is a hardlink to the inode
540                    with a different name, skip this. */
541                 if (se->name_hash != orig_name_hash) {
542                         continue;
543                 }
544
545                 se->name_hash = new_name_hash;
546
547                 /* But not to ourselves... */
548                 if (serverid_equal(&se->pid, &self_pid)) {
549                         continue;
550                 }
551
552                 if (share_mode_stale_pid(d, i)) {
553                         continue;
554                 }
555
556                 DEBUG(10,("rename_share_filename: sending rename message to "
557                           "pid %s file_id %s sharepath %s base_name %s "
558                           "stream_name %s\n",
559                           procid_str_static(&se->pid),
560                           file_id_string_tos(&id),
561                           d->servicepath, d->base_name,
562                         has_stream ? d->stream_name : ""));
563
564                 messaging_send_buf(msg_ctx, se->pid, MSG_SMB_FILE_RENAME,
565                                    (uint8 *)frm, msg_len);
566         }
567
568         return True;
569 }
570
571 void get_file_infos(struct file_id id,
572                     uint32_t name_hash,
573                     bool *delete_on_close,
574                     struct timespec *write_time)
575 {
576         struct share_mode_lock *lck;
577
578         if (delete_on_close) {
579                 *delete_on_close = false;
580         }
581
582         if (write_time) {
583                 ZERO_STRUCTP(write_time);
584         }
585
586         if (!(lck = fetch_share_mode_unlocked(talloc_tos(), id))) {
587                 return;
588         }
589
590         if (delete_on_close) {
591                 *delete_on_close = is_delete_on_close_set(lck, name_hash);
592         }
593
594         if (write_time) {
595                 *write_time = get_share_mode_write_time(lck);
596         }
597
598         TALLOC_FREE(lck);
599 }
600
601 bool is_valid_share_mode_entry(const struct share_mode_entry *e)
602 {
603         int num_props = 0;
604
605         if (e->stale) {
606                 return false;
607         }
608
609         num_props += ((e->op_type == NO_OPLOCK) ? 1 : 0);
610         num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0);
611         num_props += (LEVEL_II_OPLOCK_TYPE(e->op_type) ? 1 : 0);
612         num_props += (e->op_type == LEASE_OPLOCK);
613
614         if ((num_props > 1) && serverid_exists(&e->pid)) {
615                 smb_panic("Invalid share mode entry");
616         }
617         return (num_props != 0);
618 }
619
620 /*
621  * See if we need to remove a lease being referred to by a
622  * share mode that is being marked stale or deleted.
623  */
624
625 static void remove_share_mode_lease(struct share_mode_data *d,
626                                     struct share_mode_entry *e)
627 {
628         struct GUID client_guid;
629         struct smb2_lease_key lease_key;
630         uint16_t op_type;
631         uint32_t lease_idx;
632         uint32_t i;
633
634         op_type = e->op_type;
635         e->op_type = NO_OPLOCK;
636
637         d->modified = true;
638
639         if (op_type != LEASE_OPLOCK) {
640                 return;
641         }
642
643         /*
644          * This used to reference a lease. If there's no other one referencing
645          * it, remove it.
646          */
647
648         lease_idx = e->lease_idx;
649         e->lease_idx = UINT32_MAX;
650
651         for (i=0; i<d->num_share_modes; i++) {
652                 if (d->share_modes[i].stale) {
653                         continue;
654                 }
655                 if (e == &d->share_modes[i]) {
656                         /* Not ourselves. */
657                         continue;
658                 }
659                 if (d->share_modes[i].lease_idx == lease_idx) {
660                         break;
661                 }
662         }
663         if (i < d->num_share_modes) {
664                 /*
665                  * Found another one
666                  */
667                 return;
668         }
669
670         memcpy(&client_guid,
671                 &d->leases[lease_idx].client_guid,
672                 sizeof(client_guid));
673         lease_key = d->leases[lease_idx].lease_key;
674
675         d->num_leases -= 1;
676         d->leases[lease_idx] = d->leases[d->num_leases];
677
678         /*
679          * We changed the lease array. Fix all references to it.
680          */
681         for (i=0; i<d->num_share_modes; i++) {
682                 if (d->share_modes[i].lease_idx == d->num_leases) {
683                         d->share_modes[i].lease_idx = lease_idx;
684                         d->share_modes[i].lease = &d->leases[lease_idx];
685                 }
686         }
687
688         {
689                 NTSTATUS status;
690
691                 status = leases_db_del(&client_guid,
692                                         &lease_key,
693                                         &e->id);
694
695                 DEBUG(10, ("%s: leases_db_del returned %s\n", __func__,
696                            nt_errstr(status)));
697         }
698 }
699
700 /*
701  * In case d->share_modes[i] conflicts with something or otherwise is
702  * being used, we need to make sure the corresponding process still
703  * exists.
704  */
705 bool share_mode_stale_pid(struct share_mode_data *d, uint32_t idx)
706 {
707         struct share_mode_entry *e;
708
709         if (idx > d->num_share_modes) {
710                 DEBUG(1, ("Asking for index %u, only %u around\n",
711                           idx, (unsigned)d->num_share_modes));
712                 return false;
713         }
714         e = &d->share_modes[idx];
715         if (e->stale) {
716                 /*
717                  * Checked before
718                  */
719                 return true;
720         }
721         if (serverid_exists(&e->pid)) {
722                 DEBUG(10, ("PID %s (index %u out of %u) still exists\n",
723                            procid_str_static(&e->pid), idx,
724                            (unsigned)d->num_share_modes));
725                 return false;
726         }
727         DEBUG(10, ("PID %s (index %u out of %u) does not exist anymore\n",
728                    procid_str_static(&e->pid), idx,
729                    (unsigned)d->num_share_modes));
730
731         e->stale = true;
732
733         if (d->num_delete_tokens != 0) {
734                 uint32_t i, num_stale;
735
736                 /*
737                  * We cannot have any delete tokens
738                  * if there are no valid share modes.
739                  */
740
741                 num_stale = 0;
742
743                 for (i=0; i<d->num_share_modes; i++) {
744                         if (d->share_modes[i].stale) {
745                                 num_stale += 1;
746                         }
747                 }
748
749                 if (num_stale == d->num_share_modes) {
750                         /*
751                          * No non-stale share mode found
752                          */
753                         TALLOC_FREE(d->delete_tokens);
754                         d->num_delete_tokens = 0;
755                 }
756         }
757
758         remove_share_mode_lease(d, e);
759
760         d->modified = true;
761         return true;
762 }
763
764 void remove_stale_share_mode_entries(struct share_mode_data *d)
765 {
766         uint32_t i;
767
768         i = 0;
769         while (i < d->num_share_modes) {
770                 if (d->share_modes[i].stale) {
771                         struct share_mode_entry *m = d->share_modes;
772                         m[i] = m[d->num_share_modes-1];
773                         d->num_share_modes -= 1;
774                 } else {
775                         i += 1;
776                 }
777         }
778 }
779
780 bool set_share_mode(struct share_mode_lock *lck, struct files_struct *fsp,
781                     uid_t uid, uint64_t mid, uint16_t op_type,
782                     uint32_t lease_idx)
783 {
784         struct share_mode_data *d = lck->data;
785         struct share_mode_entry *tmp, *e;
786         struct share_mode_lease *lease = NULL;
787
788         if (lease_idx == UINT32_MAX) {
789                 lease = NULL;
790         } else if (lease_idx >= d->num_leases) {
791                 return false;
792         } else {
793                 lease = &d->leases[lease_idx];
794         }
795
796         tmp = talloc_realloc(d, d->share_modes, struct share_mode_entry,
797                              d->num_share_modes+1);
798         if (tmp == NULL) {
799                 return false;
800         }
801         d->share_modes = tmp;
802         e = &d->share_modes[d->num_share_modes];
803         d->num_share_modes += 1;
804         d->modified = true;
805
806         ZERO_STRUCTP(e);
807         e->pid = messaging_server_id(fsp->conn->sconn->msg_ctx);
808         e->share_access = fsp->share_access;
809         e->private_options = fsp->fh->private_options;
810         e->access_mask = fsp->access_mask;
811         e->op_mid = mid;
812         e->op_type = op_type;
813         e->lease_idx = lease_idx;
814         e->lease = lease;
815         e->time.tv_sec = fsp->open_time.tv_sec;
816         e->time.tv_usec = fsp->open_time.tv_usec;
817         e->id = fsp->file_id;
818         e->share_file_id = fsp->fh->gen_id;
819         e->uid = (uint32)uid;
820         e->flags = fsp->posix_open ? SHARE_MODE_FLAG_POSIX_OPEN : 0;
821         e->name_hash = fsp->name_hash;
822
823         return true;
824 }
825
826 static struct share_mode_entry *find_share_mode_entry(
827         struct share_mode_lock *lck, files_struct *fsp)
828 {
829         struct share_mode_data *d = lck->data;
830         struct server_id pid;
831         int i;
832
833         pid = messaging_server_id(fsp->conn->sconn->msg_ctx);
834
835         for (i=0; i<d->num_share_modes; i++) {
836                 struct share_mode_entry *e = &d->share_modes[i];
837
838                 if (!is_valid_share_mode_entry(e)) {
839                         continue;
840                 }
841                 if (!serverid_equal(&pid, &e->pid)) {
842                         continue;
843                 }
844                 if (!file_id_equal(&fsp->file_id, &e->id)) {
845                         continue;
846                 }
847                 if (fsp->fh->gen_id != e->share_file_id) {
848                         continue;
849                 }
850                 return e;
851         }
852         return NULL;
853 }
854
855 /*******************************************************************
856  Del the share mode of a file for this process. Return the number of
857  entries left.
858 ********************************************************************/
859
860 bool del_share_mode(struct share_mode_lock *lck, files_struct *fsp)
861 {
862         struct share_mode_entry *e;
863
864         e = find_share_mode_entry(lck, fsp);
865         if (e == NULL) {
866                 return False;
867         }
868         remove_share_mode_lease(lck->data, e);
869         *e = lck->data->share_modes[lck->data->num_share_modes-1];
870         lck->data->num_share_modes -= 1;
871         lck->data->modified = True;
872         return True;
873 }
874
875 bool mark_share_mode_disconnected(struct share_mode_lock *lck,
876                                   struct files_struct *fsp)
877 {
878         struct share_mode_entry *e;
879
880         if (lck->data->num_share_modes != 1) {
881                 return false;
882         }
883
884         if (fsp->op == NULL) {
885                 return false;
886         }
887         if (!fsp->op->global->durable) {
888                 return false;
889         }
890
891         e = find_share_mode_entry(lck, fsp);
892         if (e == NULL) {
893                 return false;
894         }
895
896         DEBUG(10, ("Marking share mode entry disconnected for durable handle\n"));
897
898         server_id_set_disconnected(&e->pid);
899
900         /*
901          * On reopen the caller needs to check that
902          * the client comes with the correct handle.
903          */
904         e->share_file_id = fsp->op->global->open_persistent_id;
905
906         lck->data->modified = true;
907         return true;
908 }
909
910 /*******************************************************************
911  Remove an oplock mid and mode entry from a share mode.
912 ********************************************************************/
913
914 bool remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
915 {
916         struct share_mode_data *d = lck->data;
917         struct share_mode_entry *e;
918
919         e = find_share_mode_entry(lck, fsp);
920         if (e == NULL) {
921                 return False;
922         }
923
924         remove_share_mode_lease(d, e);
925         d->modified = True;
926         return true;
927 }
928
929 /*******************************************************************
930  Downgrade a oplock type from exclusive to level II.
931 ********************************************************************/
932
933 bool downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
934 {
935         struct share_mode_entry *e;
936
937         e = find_share_mode_entry(lck, fsp);
938         if (e == NULL) {
939                 return False;
940         }
941
942         e->op_type = LEVEL_II_OPLOCK;
943         lck->data->modified = True;
944         return True;
945 }
946
947 NTSTATUS downgrade_share_lease(struct smbd_server_connection *sconn,
948                                struct share_mode_lock *lck,
949                                const struct smb2_lease_key *key,
950                                uint32_t new_lease_state,
951                                struct share_mode_lease **_l)
952 {
953         struct share_mode_data *d = lck->data;
954         struct share_mode_lease *l;
955         uint32_t i;
956
957         *_l = NULL;
958
959         for (i=0; i<d->num_leases; i++) {
960                 if (smb2_lease_equal(&sconn->client->connections->smb2.client.guid,
961                                      key,
962                                      &d->leases[i].client_guid,
963                                      &d->leases[i].lease_key)) {
964                         break;
965                 }
966         }
967         if (i == d->num_leases) {
968                 DEBUG(10, ("lease not found\n"));
969                 return NT_STATUS_INVALID_PARAMETER;
970         }
971
972         l = &d->leases[i];
973
974         if (!l->breaking) {
975                 DEBUG(1, ("Attempt to break from %d to %d - but we're not in breaking state\n",
976                            (int)l->current_state, (int)new_lease_state));
977                 return NT_STATUS_UNSUCCESSFUL;
978         }
979
980         /*
981          * Can't upgrade anything: l->breaking_to_requested (and l->current_state)
982          * must be a strict bitwise superset of new_lease_state
983          */
984         if ((new_lease_state & l->breaking_to_requested) != new_lease_state) {
985                 DEBUG(1, ("Attempt to upgrade from %d to %d - expected %d\n",
986                            (int)l->current_state, (int)new_lease_state,
987                            (int)l->breaking_to_requested));
988                 return NT_STATUS_REQUEST_NOT_ACCEPTED;
989         }
990
991         if (l->current_state != new_lease_state) {
992                 l->current_state = new_lease_state;
993                 d->modified = true;
994         }
995
996         if ((new_lease_state & ~l->breaking_to_required) != 0) {
997                 DEBUG(5, ("lease state %d not fully broken from %d to %d\n",
998                            (int)new_lease_state,
999                            (int)l->current_state,
1000                            (int)l->breaking_to_required));
1001                 l->breaking_to_requested = l->breaking_to_required;
1002                 if (l->current_state & (~SMB2_LEASE_READ)) {
1003                         /*
1004                          * Here we break in steps, as windows does
1005                          * see the breaking3 and v2_breaking3 tests.
1006                          */
1007                         l->breaking_to_requested |= SMB2_LEASE_READ;
1008                 }
1009                 d->modified = true;
1010                 *_l = l;
1011                 return NT_STATUS_OPLOCK_BREAK_IN_PROGRESS;
1012         }
1013
1014         DEBUG(10, ("breaking from %d to %d - expected %d\n",
1015                    (int)l->current_state, (int)new_lease_state,
1016                    (int)l->breaking_to_requested));
1017
1018         l->breaking_to_requested = 0;
1019         l->breaking_to_required = 0;
1020         l->breaking = false;
1021
1022         d->modified = true;
1023
1024         return NT_STATUS_OK;
1025 }
1026
1027 /****************************************************************************
1028  Adds a delete on close token.
1029 ****************************************************************************/
1030
1031 static bool add_delete_on_close_token(struct share_mode_data *d,
1032                         uint32_t name_hash,
1033                         const struct security_token *nt_tok,
1034                         const struct security_unix_token *tok)
1035 {
1036         struct delete_token *tmp, *dtl;
1037
1038         tmp = talloc_realloc(d, d->delete_tokens, struct delete_token,
1039                              d->num_delete_tokens+1);
1040         if (tmp == NULL) {
1041                 return false;
1042         }
1043         d->delete_tokens = tmp;
1044         dtl = &d->delete_tokens[d->num_delete_tokens];
1045
1046         dtl->name_hash = name_hash;
1047         dtl->delete_nt_token = dup_nt_token(d->delete_tokens, nt_tok);
1048         if (dtl->delete_nt_token == NULL) {
1049                 return false;
1050         }
1051         dtl->delete_token = copy_unix_token(d->delete_tokens, tok);
1052         if (dtl->delete_token == NULL) {
1053                 return false;
1054         }
1055         d->num_delete_tokens += 1;
1056         d->modified = true;
1057         return true;
1058 }
1059
1060 /****************************************************************************
1061  Sets the delete on close flag over all share modes on this file.
1062  Modify the share mode entry for all files open
1063  on this device and inode to tell other smbds we have
1064  changed the delete on close flag. This will be noticed
1065  in the close code, the last closer will delete the file
1066  if flag is set.
1067  This makes a copy of any struct security_unix_token into the
1068  lck entry. This function is used when the lock is already granted.
1069 ****************************************************************************/
1070
1071 void set_delete_on_close_lck(files_struct *fsp,
1072                         struct share_mode_lock *lck,
1073                         bool delete_on_close,
1074                         const struct security_token *nt_tok,
1075                         const struct security_unix_token *tok)
1076 {
1077         struct share_mode_data *d = lck->data;
1078         int i;
1079         bool ret;
1080
1081         if (delete_on_close) {
1082                 SMB_ASSERT(nt_tok != NULL);
1083                 SMB_ASSERT(tok != NULL);
1084         } else {
1085                 SMB_ASSERT(nt_tok == NULL);
1086                 SMB_ASSERT(tok == NULL);
1087         }
1088
1089         for (i=0; i<d->num_delete_tokens; i++) {
1090                 struct delete_token *dt = &d->delete_tokens[i];
1091                 if (dt->name_hash == fsp->name_hash) {
1092                         d->modified = true;
1093                         if (delete_on_close == false) {
1094                                 /* Delete this entry. */
1095                                 TALLOC_FREE(dt->delete_nt_token);
1096                                 TALLOC_FREE(dt->delete_token);
1097                                 *dt = d->delete_tokens[
1098                                         d->num_delete_tokens-1];
1099                                 d->num_delete_tokens -= 1;
1100                         } else {
1101                                 /* Replace this token with the
1102                                    given tok. */
1103                                 TALLOC_FREE(dt->delete_nt_token);
1104                                 dt->delete_nt_token = dup_nt_token(dt, nt_tok);
1105                                 SMB_ASSERT(dt->delete_nt_token != NULL);
1106                                 TALLOC_FREE(dt->delete_token);
1107                                 dt->delete_token = copy_unix_token(dt, tok);
1108                                 SMB_ASSERT(dt->delete_token != NULL);
1109                         }
1110                         return;
1111                 }
1112         }
1113
1114         if (!delete_on_close) {
1115                 /* Nothing to delete - not found. */
1116                 return;
1117         }
1118
1119         ret = add_delete_on_close_token(lck->data, fsp->name_hash, nt_tok, tok);
1120         SMB_ASSERT(ret);
1121 }
1122
1123 bool set_delete_on_close(files_struct *fsp, bool delete_on_close,
1124                         const struct security_token *nt_tok,
1125                         const struct security_unix_token *tok)
1126 {
1127         struct share_mode_lock *lck;
1128
1129         DEBUG(10,("set_delete_on_close: %s delete on close flag for "
1130                   "%s, file %s\n",
1131                   delete_on_close ? "Adding" : "Removing", fsp_fnum_dbg(fsp),
1132                   fsp_str_dbg(fsp)));
1133
1134         lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
1135         if (lck == NULL) {
1136                 return False;
1137         }
1138
1139         if (delete_on_close) {
1140                 set_delete_on_close_lck(fsp, lck, true,
1141                         nt_tok,
1142                         tok);
1143         } else {
1144                 set_delete_on_close_lck(fsp, lck, false,
1145                         NULL,
1146                         NULL);
1147         }
1148
1149         if (fsp->is_directory) {
1150                 SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name));
1151                 send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
1152                                                fsp->fsp_name->base_name);
1153         }
1154
1155         TALLOC_FREE(lck);
1156
1157         fsp->delete_on_close = delete_on_close;
1158
1159         return True;
1160 }
1161
1162 static struct delete_token *find_delete_on_close_token(
1163         struct share_mode_data *d, uint32_t name_hash)
1164 {
1165         uint32_t i;
1166
1167         DEBUG(10, ("find_delete_on_close_token: name_hash = 0x%x\n",
1168                    (unsigned int)name_hash));
1169
1170         for (i=0; i<d->num_delete_tokens; i++) {
1171                 struct delete_token *dt = &d->delete_tokens[i];
1172
1173                 DEBUG(10, ("find__delete_on_close_token: dt->name_hash = 0x%x\n",
1174                            (unsigned int)dt->name_hash ));
1175                 if (dt->name_hash == name_hash) {
1176                         return dt;
1177                 }
1178         }
1179         return NULL;
1180 }
1181
1182 /****************************************************************************
1183  Return the NT token and UNIX token if there's a match. Return true if
1184  found, false if not.
1185 ****************************************************************************/
1186
1187 bool get_delete_on_close_token(struct share_mode_lock *lck,
1188                                         uint32_t name_hash,
1189                                         const struct security_token **pp_nt_tok,
1190                                         const struct security_unix_token **pp_tok)
1191 {
1192         struct delete_token *dt;
1193
1194         dt = find_delete_on_close_token(lck->data, name_hash);
1195         if (dt == NULL) {
1196                 return false;
1197         }
1198         *pp_nt_tok = dt->delete_nt_token;
1199         *pp_tok =  dt->delete_token;
1200         return true;
1201 }
1202
1203 bool is_delete_on_close_set(struct share_mode_lock *lck, uint32_t name_hash)
1204 {
1205         return find_delete_on_close_token(lck->data, name_hash) != NULL;
1206 }
1207
1208 bool set_sticky_write_time(struct file_id fileid, struct timespec write_time)
1209 {
1210         struct share_mode_lock *lck;
1211
1212         DEBUG(5,("set_sticky_write_time: %s id=%s\n",
1213                  timestring(talloc_tos(),
1214                             convert_timespec_to_time_t(write_time)),
1215                  file_id_string_tos(&fileid)));
1216
1217         lck = get_existing_share_mode_lock(talloc_tos(), fileid);
1218         if (lck == NULL) {
1219                 return False;
1220         }
1221
1222         if (timespec_compare(&lck->data->changed_write_time, &write_time) != 0) {
1223                 lck->data->modified = True;
1224                 lck->data->changed_write_time = write_time;
1225         }
1226
1227         TALLOC_FREE(lck);
1228         return True;
1229 }
1230
1231 bool set_write_time(struct file_id fileid, struct timespec write_time)
1232 {
1233         struct share_mode_lock *lck;
1234
1235         DEBUG(5,("set_write_time: %s id=%s\n",
1236                  timestring(talloc_tos(),
1237                             convert_timespec_to_time_t(write_time)),
1238                  file_id_string_tos(&fileid)));
1239
1240         lck = get_existing_share_mode_lock(talloc_tos(), fileid);
1241         if (lck == NULL) {
1242                 return False;
1243         }
1244
1245         if (timespec_compare(&lck->data->old_write_time, &write_time) != 0) {
1246                 lck->data->modified = True;
1247                 lck->data->old_write_time = write_time;
1248         }
1249
1250         TALLOC_FREE(lck);
1251         return True;
1252 }
1253
1254 struct timespec get_share_mode_write_time(struct share_mode_lock *lck)
1255 {
1256         struct share_mode_data *d = lck->data;
1257
1258         if (!null_timespec(d->changed_write_time)) {
1259                 return d->changed_write_time;
1260         }
1261         return d->old_write_time;
1262 }