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