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