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