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