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