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