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