262402b79956ca4b5c837801c3f0c4b56f2a63fa
[gd/samba-autobuild/.git] / source3 / locking / share_mode_lock.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 "dbwrap/dbwrap_private.h"
46 #include "../libcli/security/security.h"
47 #include "serverid.h"
48 #include "messages.h"
49 #include "util_tdb.h"
50 #include "../librpc/gen_ndr/ndr_open_files.h"
51 #include "source3/lib/dbwrap/dbwrap_watch.h"
52 #include "locking/leases_db.h"
53 #include "../lib/util/memcache.h"
54 #include "lib/util/tevent_ntstatus.h"
55 #include "g_lock.h"
56
57 #undef DBGC_CLASS
58 #define DBGC_CLASS DBGC_LOCKING
59
60 #define NO_LOCKING_COUNT (-1)
61
62 /* the locking database handle */
63 static struct g_lock_ctx *lock_ctx;
64 static struct db_context *share_entries_db;
65
66 static bool locking_init_internal(bool read_only)
67 {
68         struct db_context *backend;
69         char *db_path;
70
71         brl_init(read_only);
72
73         if (lock_ctx != NULL) {
74                 return True;
75         }
76
77         db_path = lock_path(talloc_tos(), "locking.tdb");
78         if (db_path == NULL) {
79                 return false;
80         }
81
82         backend = db_open(NULL, db_path,
83                           SMB_OPEN_DATABASE_TDB_HASH_SIZE,
84                           TDB_DEFAULT|
85                           TDB_VOLATILE|
86                           TDB_CLEAR_IF_FIRST|
87                           TDB_INCOMPATIBLE_HASH|
88                           TDB_SEQNUM,
89                           read_only?O_RDONLY:O_RDWR|O_CREAT, 0644,
90                           DBWRAP_LOCK_ORDER_NONE,
91                           DBWRAP_FLAG_NONE);
92         TALLOC_FREE(db_path);
93         if (!backend) {
94                 DEBUG(0,("ERROR: Failed to initialise locking database\n"));
95                 return False;
96         }
97
98         lock_ctx = g_lock_ctx_init_backend(
99                 NULL, global_messaging_context(), &backend);
100         if (lock_ctx == NULL) {
101                 TALLOC_FREE(backend);
102                 return false;
103         }
104         g_lock_set_lock_order(lock_ctx, DBWRAP_LOCK_ORDER_1);
105
106         db_path = lock_path(talloc_tos(), "share_entries.tdb");
107         if (db_path == NULL) {
108                 TALLOC_FREE(lock_ctx);
109                 return false;
110         }
111
112         share_entries_db = db_open(
113                 NULL, db_path,
114                 SMB_OPEN_DATABASE_TDB_HASH_SIZE,
115                 TDB_DEFAULT|
116                 TDB_VOLATILE|
117                 TDB_CLEAR_IF_FIRST|
118                 TDB_INCOMPATIBLE_HASH,
119                 read_only?O_RDONLY:O_RDWR|O_CREAT, 0644,
120                 DBWRAP_LOCK_ORDER_3, DBWRAP_FLAG_NONE);
121         TALLOC_FREE(db_path);
122
123         if (share_entries_db == NULL) {
124                 TALLOC_FREE(lock_ctx);
125                 return false;
126         }
127
128         if (!posix_locking_init(read_only)) {
129                 TALLOC_FREE(share_entries_db);
130                 TALLOC_FREE(lock_ctx);
131                 return False;
132         }
133
134         return True;
135 }
136
137 bool locking_init(void)
138 {
139         return locking_init_internal(false);
140 }
141
142 bool locking_init_readonly(void)
143 {
144         return locking_init_internal(true);
145 }
146
147 /*******************************************************************
148  Deinitialize the share_mode management.
149 ******************************************************************/
150
151 bool locking_end(void)
152 {
153         brl_shutdown();
154         TALLOC_FREE(lock_ctx);
155         return true;
156 }
157
158 /*******************************************************************
159  Form a static locking key for a dev/inode pair.
160 ******************************************************************/
161
162 static TDB_DATA locking_key(const struct file_id *id)
163 {
164         return make_tdb_data((const uint8_t *)id, sizeof(*id));
165 }
166
167 /*******************************************************************
168  Share mode cache utility functions that store/delete/retrieve
169  entries from memcache.
170
171  For now share the statcache (global cache) memory space. If
172  a lock record gets orphaned (which shouldn't happen as we're
173  using the same locking_key data as lookup) it will eventually
174  fall out of the cache via the normal LRU trim mechanism. If
175  necessary we can always make this a separate (smaller) cache.
176 ******************************************************************/
177
178 static DATA_BLOB memcache_key(const struct file_id *id)
179 {
180         return data_blob_const((const void *)id, sizeof(*id));
181 }
182
183 static void share_mode_memcache_store(struct share_mode_data *d)
184 {
185         const DATA_BLOB key = memcache_key(&d->id);
186         struct file_id_buf idbuf;
187
188         DBG_DEBUG("stored entry for file %s seq %"PRIx64" key %s\n",
189                   d->base_name,
190                   d->sequence_number,
191                   file_id_str_buf(d->id, &idbuf));
192
193         /* Ensure everything stored in the cache is pristine. */
194         d->modified = false;
195         d->fresh = false;
196
197         /*
198          * Ensure the memory going into the cache
199          * doesn't have a destructor so it can be
200          * cleanly evicted by the memcache LRU
201          * mechanism.
202          */
203         talloc_set_destructor(d, NULL);
204
205         /* Cache will own d after this call. */
206         memcache_add_talloc(NULL,
207                         SHARE_MODE_LOCK_CACHE,
208                         key,
209                         &d);
210 }
211
212 /*
213  * NB. We use ndr_pull_hyper on a stack-created
214  * struct ndr_pull with no talloc allowed, as we
215  * need this to be really fast as an ndr-peek into
216  * the first 10 bytes of the blob.
217  */
218
219 static enum ndr_err_code get_share_mode_blob_header(
220         const uint8_t *buf, size_t buflen, uint64_t *pseq, uint16_t *pflags)
221 {
222         struct ndr_pull ndr = {
223                 .data = discard_const_p(uint8_t, buf),
224                 .data_size = buflen,
225         };
226         NDR_CHECK(ndr_pull_hyper(&ndr, NDR_SCALARS, pseq));
227         NDR_CHECK(ndr_pull_uint16(&ndr, NDR_SCALARS, pflags));
228         return NDR_ERR_SUCCESS;
229 }
230
231 struct fsp_update_share_mode_flags_state {
232         enum ndr_err_code ndr_err;
233         uint16_t share_mode_flags;
234 };
235
236 static void fsp_update_share_mode_flags_fn(
237         const uint8_t *buf,
238         size_t buflen,
239         bool *modified_dependent,
240         void *private_data)
241 {
242         struct fsp_update_share_mode_flags_state *state = private_data;
243         uint64_t seq;
244
245         state->ndr_err = get_share_mode_blob_header(
246                 buf, buflen, &seq, &state->share_mode_flags);
247 }
248
249 static NTSTATUS fsp_update_share_mode_flags(struct files_struct *fsp)
250 {
251         struct fsp_update_share_mode_flags_state state = {0};
252         int seqnum = g_lock_seqnum(lock_ctx);
253         NTSTATUS status;
254
255         if (seqnum == fsp->share_mode_flags_seqnum) {
256                 return NT_STATUS_OK;
257         }
258
259         status = share_mode_do_locked(
260                 fsp->file_id, fsp_update_share_mode_flags_fn, &state);
261         if (!NT_STATUS_IS_OK(status)) {
262                 DBG_DEBUG("share_mode_do_locked returned %s\n",
263                           nt_errstr(status));
264                 return status;
265         }
266
267         if (!NDR_ERR_CODE_IS_SUCCESS(state.ndr_err)) {
268                 DBG_DEBUG("get_share_mode_blob_header returned %s\n",
269                           ndr_errstr(state.ndr_err));
270                 return ndr_map_error2ntstatus(state.ndr_err);
271         }
272
273         fsp->share_mode_flags_seqnum = seqnum;
274         fsp->share_mode_flags = state.share_mode_flags;
275
276         return NT_STATUS_OK;
277 }
278
279 bool file_has_read_lease(struct files_struct *fsp)
280 {
281         NTSTATUS status;
282
283         status = fsp_update_share_mode_flags(fsp);
284         if (!NT_STATUS_IS_OK(status)) {
285                 /* Safe default for leases */
286                 return true;
287         }
288
289         return (fsp->share_mode_flags & SHARE_MODE_LEASE_READ) != 0;
290 }
291
292 static int share_mode_data_nofree_destructor(struct share_mode_data *d)
293 {
294         return -1;
295 }
296
297 static struct share_mode_data *share_mode_memcache_fetch(
298         TALLOC_CTX *mem_ctx,
299         const TDB_DATA id_key,
300         const uint8_t *buf,
301         size_t buflen)
302 {
303         enum ndr_err_code ndr_err;
304         struct share_mode_data *d;
305         uint64_t sequence_number;
306         uint16_t flags;
307         void *ptr;
308         struct file_id id;
309         struct file_id_buf idbuf;
310         DATA_BLOB key;
311
312         /* Ensure this is a locking_key record. */
313         if (id_key.dsize != sizeof(id)) {
314                 return NULL;
315         }
316
317         memcpy(&id, id_key.dptr, id_key.dsize);
318         key = memcache_key(&id);
319
320         ptr = memcache_lookup_talloc(NULL,
321                         SHARE_MODE_LOCK_CACHE,
322                         key);
323         if (ptr == NULL) {
324                 DBG_DEBUG("failed to find entry for key %s\n",
325                           file_id_str_buf(id, &idbuf));
326                 return NULL;
327         }
328         /* sequence number key is at start of blob. */
329         ndr_err = get_share_mode_blob_header(
330                 buf, buflen, &sequence_number, &flags);
331         if (ndr_err != NDR_ERR_SUCCESS) {
332                 /* Bad blob. Remove entry. */
333                 DBG_DEBUG("bad blob %u key %s\n",
334                           (unsigned int)ndr_err,
335                           file_id_str_buf(id, &idbuf));
336                 memcache_delete(NULL,
337                         SHARE_MODE_LOCK_CACHE,
338                         key);
339                 return NULL;
340         }
341
342         d = (struct share_mode_data *)ptr;
343         if (d->sequence_number != sequence_number) {
344                 DBG_DEBUG("seq changed (cached %"PRIx64") (new %"PRIx64") "
345                           "for key %s\n",
346                           d->sequence_number,
347                           sequence_number,
348                           file_id_str_buf(id, &idbuf));
349                 /* Cache out of date. Remove entry. */
350                 memcache_delete(NULL,
351                         SHARE_MODE_LOCK_CACHE,
352                         key);
353                 return NULL;
354         }
355
356         /* Move onto mem_ctx. */
357         d = talloc_move(mem_ctx, &ptr);
358
359         /*
360          * Now we own d, prevent the cache from freeing it
361          * when we delete the entry.
362          */
363         talloc_set_destructor(d, share_mode_data_nofree_destructor);
364
365         /* Remove from the cache. We own it now. */
366         memcache_delete(NULL,
367                         SHARE_MODE_LOCK_CACHE,
368                         key);
369
370         /* And reset the destructor to none. */
371         talloc_set_destructor(d, NULL);
372
373         DBG_DEBUG("fetched entry for file %s seq %"PRIx64" key %s\n",
374                   d->base_name,
375                   d->sequence_number,
376                   file_id_str_buf(id, &idbuf));
377
378         return d;
379 }
380
381 /*
382  * 132 is the sizeof an ndr-encoded struct share_mode_entry_buf.
383  * Reading/writing entries will immediately error out if this
384  * size differs (push/pull is done without allocs).
385  */
386
387 struct share_mode_entry_buf {
388         uint8_t buf[132];
389 };
390 #define SHARE_MODE_ENTRY_SIZE (sizeof(struct share_mode_entry_buf))
391
392 static bool share_mode_entry_put(
393         const struct share_mode_entry *e,
394         struct share_mode_entry_buf *dst)
395 {
396         DATA_BLOB blob = { .data = dst->buf, .length = sizeof(dst->buf) };
397         enum ndr_err_code ndr_err;
398
399         if (DEBUGLEVEL>=10) {
400                 DBG_DEBUG("share_mode_entry:\n");
401                 NDR_PRINT_DEBUG(share_mode_entry, discard_const_p(void, e));
402         }
403
404         ndr_err = ndr_push_struct_into_fixed_blob(
405                 &blob,
406                 e,
407                 (ndr_push_flags_fn_t)ndr_push_share_mode_entry);
408         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
409                 DBG_WARNING("ndr_push_share_mode_entry failed: %s\n",
410                             ndr_errstr(ndr_err));
411                 return false;
412         }
413
414         return true;
415 }
416
417 static bool share_mode_entry_get(
418         const uint8_t ptr[SHARE_MODE_ENTRY_SIZE], struct share_mode_entry *e)
419 {
420         enum ndr_err_code ndr_err = NDR_ERR_SUCCESS;
421         DATA_BLOB blob = {
422                 .data = discard_const_p(uint8_t, ptr),
423                 .length = SHARE_MODE_ENTRY_SIZE,
424         };
425
426         ndr_err = ndr_pull_struct_blob_all_noalloc(
427                 &blob, e, (ndr_pull_flags_fn_t)ndr_pull_share_mode_entry);
428         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
429                 DBG_WARNING("ndr_pull_share_mode_entry failed\n");
430                 return false;
431         }
432         return true;
433 }
434
435 /*******************************************************************
436  Get all share mode entries for a dev/inode pair.
437 ********************************************************************/
438
439 static struct share_mode_data *parse_share_modes(
440         TALLOC_CTX *mem_ctx,
441         const TDB_DATA key,
442         const uint8_t *buf,
443         size_t buflen)
444 {
445         struct share_mode_data *d;
446         enum ndr_err_code ndr_err;
447         DATA_BLOB blob;
448
449         /* See if we already have a cached copy of this key. */
450         d = share_mode_memcache_fetch(mem_ctx, key, buf, buflen);
451         if (d != NULL) {
452                 return d;
453         }
454
455         d = talloc(mem_ctx, struct share_mode_data);
456         if (d == NULL) {
457                 DEBUG(0, ("talloc failed\n"));
458                 goto fail;
459         }
460
461         blob = (DATA_BLOB) {
462                 .data = discard_const_p(uint8_t, buf),
463                 .length = buflen,
464         };
465         ndr_err = ndr_pull_struct_blob_all(
466                 &blob, d, d, (ndr_pull_flags_fn_t)ndr_pull_share_mode_data);
467         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
468                 DBG_WARNING("ndr_pull_share_mode_data failed: %s\n",
469                             ndr_errstr(ndr_err));
470                 goto fail;
471         }
472
473         if (DEBUGLEVEL >= 10) {
474                 DEBUG(10, ("parse_share_modes:\n"));
475                 NDR_PRINT_DEBUG(share_mode_data, d);
476         }
477
478         /*
479          * We have a non-zero locking.tdb record that was correctly
480          * parsed. This means a share_entries.tdb entry exists,
481          * otherwise we'd have paniced before in
482          * share_mode_data_store()
483          */
484         d->have_share_modes = true;
485
486         return d;
487 fail:
488         TALLOC_FREE(d);
489         return NULL;
490 }
491
492 /*******************************************************************
493  If modified, store the share_mode_data back into the database.
494 ********************************************************************/
495
496 static NTSTATUS share_mode_data_store(struct share_mode_data *d)
497 {
498         TDB_DATA key = locking_key(&d->id);
499         DATA_BLOB blob = { 0 };
500         NTSTATUS status;
501
502         if (!d->modified) {
503                 DBG_DEBUG("not modified\n");
504                 return NT_STATUS_OK;
505         }
506
507         if (DEBUGLEVEL >= 10) {
508                 DBG_DEBUG("\n");
509                 NDR_PRINT_DEBUG(share_mode_data, d);
510         }
511
512         d->sequence_number += 1;
513
514         if (d->have_share_modes) {
515                 enum ndr_err_code ndr_err;
516
517                 ndr_err = ndr_push_struct_blob(
518                         &blob,
519                         d,
520                         d,
521                         (ndr_push_flags_fn_t)ndr_push_share_mode_data);
522                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
523                         DBG_DEBUG("ndr_push_share_mode_data failed: %s\n",
524                                   ndr_errstr(ndr_err));
525                         return ndr_map_error2ntstatus(ndr_err);
526                 }
527         } else {
528                 bool share_entries_exist;
529                 share_entries_exist = dbwrap_exists(share_entries_db, key);
530                 SMB_ASSERT(!share_entries_exist);
531         }
532
533         status = g_lock_write_data(lock_ctx, key, blob.data, blob.length);
534         TALLOC_FREE(blob.data);
535         if (!NT_STATUS_IS_OK(status)) {
536                 DBG_DEBUG("g_lock_write_data failed: %s\n",
537                           nt_errstr(status));
538         }
539
540         return status;
541 }
542
543 /*******************************************************************
544  Allocate a new share_mode_data struct, mark it unmodified.
545  fresh is set to note that currently there is no database entry.
546 ********************************************************************/
547
548 static struct share_mode_data *fresh_share_mode_lock(
549         TALLOC_CTX *mem_ctx, const char *servicepath,
550         const struct smb_filename *smb_fname,
551         const struct timespec *old_write_time)
552 {
553         struct share_mode_data *d;
554
555         if ((servicepath == NULL) || (smb_fname == NULL) ||
556             (old_write_time == NULL)) {
557                 return NULL;
558         }
559
560         d = talloc_zero(mem_ctx, struct share_mode_data);
561         if (d == NULL) {
562                 goto fail;
563         }
564         /* New record - new sequence number. */
565         generate_random_buffer((uint8_t *)&d->sequence_number, 8);
566
567         d->base_name = talloc_strdup(d, smb_fname->base_name);
568         if (d->base_name == NULL) {
569                 goto fail;
570         }
571         if (smb_fname->stream_name != NULL) {
572                 d->stream_name = talloc_strdup(d, smb_fname->stream_name);
573                 if (d->stream_name == NULL) {
574                         goto fail;
575                 }
576         }
577         d->servicepath = talloc_strdup(d, servicepath);
578         if (d->servicepath == NULL) {
579                 goto fail;
580         }
581         d->old_write_time = full_timespec_to_nt_time(old_write_time);
582         d->flags = SHARE_MODE_SHARE_DELETE |
583                 SHARE_MODE_SHARE_WRITE |
584                 SHARE_MODE_SHARE_READ;
585         d->modified = false;
586         d->fresh = true;
587         return d;
588 fail:
589         DEBUG(0, ("talloc failed\n"));
590         TALLOC_FREE(d);
591         return NULL;
592 }
593
594 /*
595  * Key that's locked with g_lock
596  */
597 static uint8_t share_mode_lock_key_data[sizeof(struct file_id)];
598 static TDB_DATA share_mode_lock_key = {
599         .dptr = share_mode_lock_key_data,
600         .dsize = sizeof(share_mode_lock_key_data),
601 };
602 static size_t share_mode_lock_key_refcount = 0;
603
604 /*
605  * We can only ever have one share mode locked. Use a static
606  * share_mode_data pointer that is shared by multiple nested
607  * share_mode_lock structures, explicitly refcounted.
608  */
609 static struct share_mode_data *static_share_mode_data = NULL;
610 static size_t static_share_mode_data_refcount = 0;
611
612 /*******************************************************************
613  Either fetch a share mode from the database, or allocate a fresh
614  one if the record doesn't exist.
615 ********************************************************************/
616
617 struct get_static_share_mode_data_state {
618         TALLOC_CTX *mem_ctx;
619         struct file_id id;
620         const char *servicepath;
621         const struct smb_filename *smb_fname;
622         const struct timespec *old_write_time;
623         NTSTATUS status;
624 };
625
626 static void get_static_share_mode_data_fn(
627         struct server_id exclusive,
628         size_t num_shared,
629         struct server_id *shared,
630         const uint8_t *data,
631         size_t datalen,
632         void *private_data)
633 {
634         struct get_static_share_mode_data_state *state = private_data;
635         struct share_mode_data *d = NULL;
636
637         if (datalen == 0) {
638                 if (state->smb_fname == NULL) {
639                         state->status = NT_STATUS_NOT_FOUND;
640                         return;
641                 }
642                 d = fresh_share_mode_lock(
643                         state->mem_ctx,
644                         state->servicepath,
645                         state->smb_fname,
646                         state->old_write_time);
647                 if (d == NULL) {
648                         state->status = NT_STATUS_NO_MEMORY;
649                         return;
650                 }
651         } else {
652                 TDB_DATA key = locking_key(&state->id);
653                 d = parse_share_modes(lock_ctx, key, data, datalen);
654                 if (d == NULL) {
655                         state->status = NT_STATUS_INTERNAL_DB_CORRUPTION;
656                         return;
657                 }
658         }
659
660         d->id = state->id;
661         static_share_mode_data = d;
662 }
663
664 static NTSTATUS get_static_share_mode_data(
665         struct file_id id,
666         const char *servicepath,
667         const struct smb_filename *smb_fname,
668         const struct timespec *old_write_time)
669 {
670         struct get_static_share_mode_data_state state = {
671                 .mem_ctx = lock_ctx,
672                 .id = id,
673                 .servicepath = servicepath,
674                 .smb_fname = smb_fname,
675                 .old_write_time = old_write_time,
676         };
677         NTSTATUS status;
678
679         SMB_ASSERT(static_share_mode_data == NULL);
680
681         status = g_lock_dump(
682                 lock_ctx,
683                 share_mode_lock_key,
684                 get_static_share_mode_data_fn,
685                 &state);
686         if (!NT_STATUS_IS_OK(status)) {
687                 DBG_DEBUG("g_lock_dump failed: %s\n",
688                           nt_errstr(status));
689                 return status;
690         }
691         if (!NT_STATUS_IS_OK(state.status)) {
692                 DBG_DEBUG("get_static_share_mode_data_fn failed: %s\n",
693                           nt_errstr(state.status));
694                 return state.status;
695         }
696
697         return NT_STATUS_OK;
698 }
699
700 /*******************************************************************
701  Get a share_mode_lock, Reference counted to allow nested calls.
702 ********************************************************************/
703
704 static int share_mode_lock_destructor(struct share_mode_lock *lck);
705
706 struct share_mode_lock *get_share_mode_lock(
707         TALLOC_CTX *mem_ctx,
708         struct file_id id,
709         const char *servicepath,
710         const struct smb_filename *smb_fname,
711         const struct timespec *old_write_time)
712 {
713         TDB_DATA key = locking_key(&id);
714         struct share_mode_lock *lck = NULL;
715         NTSTATUS status;
716         int cmp;
717
718         lck = talloc(mem_ctx, struct share_mode_lock);
719         if (lck == NULL) {
720                 DEBUG(1, ("talloc failed\n"));
721                 return NULL;
722         }
723
724         if (static_share_mode_data != NULL) {
725                 if (!file_id_equal(&static_share_mode_data->id, &id)) {
726                         DEBUG(1, ("Can not lock two share modes "
727                                   "simultaneously\n"));
728                         goto fail;
729                 }
730                 goto done;
731         }
732
733         if (share_mode_lock_key_refcount == 0) {
734                 status = g_lock_lock(
735                         lock_ctx,
736                         key,
737                         G_LOCK_WRITE,
738                         (struct timeval) { .tv_sec = 3600 });
739                 if (!NT_STATUS_IS_OK(status)) {
740                         DBG_DEBUG("g_lock_lock failed: %s\n",
741                                   nt_errstr(status));
742                         goto fail;
743                 }
744                 memcpy(share_mode_lock_key_data, key.dptr, key.dsize);
745         }
746
747         cmp = tdb_data_cmp(share_mode_lock_key, key);
748         if (cmp != 0) {
749                 DBG_WARNING("Can not lock two share modes simultaneously\n");
750                 goto fail;
751         }
752
753         SMB_ASSERT(share_mode_lock_key_refcount < SIZE_MAX);
754         share_mode_lock_key_refcount += 1;
755
756         SMB_ASSERT(static_share_mode_data_refcount == 0);
757
758         status = get_static_share_mode_data(
759                 id,
760                 servicepath,
761                 smb_fname,
762                 old_write_time);
763         if (!NT_STATUS_IS_OK(status)) {
764                 DBG_DEBUG("get_static_share_mode_data failed: %s\n",
765                           nt_errstr(status));
766                 share_mode_lock_key_refcount -= 1;
767                 goto fail;
768         }
769 done:
770         static_share_mode_data_refcount += 1;
771         lck->data = static_share_mode_data;
772
773         talloc_set_destructor(lck, share_mode_lock_destructor);
774
775         return lck;
776 fail:
777         TALLOC_FREE(lck);
778         if (share_mode_lock_key_refcount == 0) {
779                 status = g_lock_unlock(lock_ctx, share_mode_lock_key);
780                 if (!NT_STATUS_IS_OK(status)) {
781                         DBG_ERR("g_lock_unlock failed: %s\n",
782                                 nt_errstr(status));
783                 }
784         }
785         return NULL;
786 }
787
788 static int share_mode_lock_destructor(struct share_mode_lock *lck)
789 {
790         NTSTATUS status;
791
792         SMB_ASSERT(static_share_mode_data_refcount > 0);
793         static_share_mode_data_refcount -= 1;
794
795         if (static_share_mode_data_refcount > 0) {
796                 return 0;
797         }
798
799         status = share_mode_data_store(static_share_mode_data);
800         if (!NT_STATUS_IS_OK(status)) {
801                 DBG_ERR("share_mode_data_store failed: %s\n",
802                         nt_errstr(status));
803                 smb_panic("Could not store share mode data\n");
804         }
805
806         SMB_ASSERT(share_mode_lock_key_refcount > 0);
807         share_mode_lock_key_refcount -= 1;
808
809         if (share_mode_lock_key_refcount == 0) {
810                 status = g_lock_unlock(lock_ctx, share_mode_lock_key);
811                 if (!NT_STATUS_IS_OK(status)) {
812                         DBG_ERR("g_lock_unlock failed: %s\n",
813                                 nt_errstr(status));
814                         smb_panic("Could not unlock share mode\n");
815                 }
816         }
817
818         if (static_share_mode_data->have_share_modes) {
819                 /*
820                  * This is worth keeping. Without share modes,
821                  * share_mode_data_store above has left nothing in the
822                  * database.
823                  */
824                 share_mode_memcache_store(static_share_mode_data);
825                 static_share_mode_data = NULL;
826         } else {
827                 /*
828                  * The next opener of this file will find an empty
829                  * locking.tdb record. Don't store the share_mode_data
830                  * in the memcache, fresh_share_mode_lock() will
831                  * generate a fresh seqnum anyway, obsoleting the
832                  * cache entry.
833                  */
834                 TALLOC_FREE(static_share_mode_data);
835         }
836
837         return 0;
838 }
839
840 struct share_mode_do_locked_state {
841         TDB_DATA key;
842         void (*fn)(const uint8_t *buf,
843                    size_t buflen,
844                    bool *modified_dependent,
845                    void *private_data);
846         void *private_data;
847 };
848
849 static void share_mode_do_locked_fn(
850         struct server_id exclusive,
851         size_t num_shared,
852         struct server_id *shared,
853         const uint8_t *data,
854         size_t datalen,
855         void *private_data)
856 {
857         struct share_mode_do_locked_state *state = private_data;
858         bool modified_dependent = false;
859         TDB_DATA value = {
860                 .dptr = discard_const_p(uint8_t, data), .dsize = datalen,
861         };
862
863         state->fn(value.dptr,
864                   value.dsize,
865                   &modified_dependent,
866                   state->private_data);
867
868         if (modified_dependent) {
869                 g_lock_wake_watchers(lock_ctx, state->key);
870         }
871 }
872
873 NTSTATUS share_mode_do_locked(
874         struct file_id id,
875         void (*fn)(const uint8_t *buf,
876                    size_t buflen,
877                    bool *modified_dependent,
878                    void *private_data),
879         void *private_data)
880 {
881         TDB_DATA key = locking_key(&id);
882         size_t data_refcount, key_refcount;
883         struct share_mode_do_locked_state state = {
884                 .key = key, .fn = fn, .private_data = private_data,
885         };
886         NTSTATUS status;
887
888         if (share_mode_lock_key_refcount == 0) {
889                 status = g_lock_lock(
890                         lock_ctx,
891                         key,
892                         G_LOCK_WRITE,
893                         (struct timeval) { .tv_sec = 3600 });
894                 if (!NT_STATUS_IS_OK(status)) {
895                         DBG_DEBUG("g_lock_lock failed: %s\n",
896                                   nt_errstr(status));
897                         return status;
898                 }
899                 memcpy(share_mode_lock_key_data, key.dptr, key.dsize);
900         }
901
902         SMB_ASSERT(share_mode_lock_key_refcount < SIZE_MAX);
903         share_mode_lock_key_refcount += 1;
904
905         key_refcount = share_mode_lock_key_refcount;
906         data_refcount = static_share_mode_data_refcount;
907
908         status = g_lock_dump(
909                 lock_ctx, key, share_mode_do_locked_fn, &state);
910         if (!NT_STATUS_IS_OK(status)) {
911                 DBG_DEBUG("g_lock_dump failed: %s\n",
912                           nt_errstr(status));
913         }
914
915         SMB_ASSERT(data_refcount == static_share_mode_data_refcount);
916         SMB_ASSERT(key_refcount == share_mode_lock_key_refcount);
917         share_mode_lock_key_refcount -= 1;
918
919         if (share_mode_lock_key_refcount == 0) {
920                 status = g_lock_unlock(lock_ctx, key);
921                 if (!NT_STATUS_IS_OK(status)) {
922                         DBG_DEBUG("g_lock_unlock failed: %s\n",
923                                   nt_errstr(status));
924                 }
925         }
926
927         return status;
928 }
929
930 static void share_mode_wakeup_waiters_fn(
931         const uint8_t *buf,
932         size_t buflen,
933         bool *modified_dependent,
934         void *private_data)
935 {
936         *modified_dependent = true;
937 }
938
939 NTSTATUS share_mode_wakeup_waiters(struct file_id id)
940 {
941         return share_mode_do_locked(id, share_mode_wakeup_waiters_fn, NULL);
942 }
943
944 bool share_mode_have_entries(struct share_mode_lock *lck)
945 {
946         return lck->data->have_share_modes;
947 }
948
949 struct share_mode_watch_state {
950         bool blockerdead;
951         struct server_id blocker;
952 };
953
954 static void share_mode_watch_done(struct tevent_req *subreq);
955
956 struct tevent_req *share_mode_watch_send(
957         TALLOC_CTX *mem_ctx,
958         struct tevent_context *ev,
959         struct file_id id,
960         struct server_id blocker)
961 {
962         TDB_DATA key = locking_key(&id);
963         struct tevent_req *req = NULL, *subreq = NULL;
964         struct share_mode_watch_state *state = NULL;
965
966         req = tevent_req_create(
967                 mem_ctx, &state, struct share_mode_watch_state);
968         if (req == NULL) {
969                 return NULL;
970         }
971
972         subreq = g_lock_watch_data_send(state, ev, lock_ctx, key, blocker);
973         if (tevent_req_nomem(subreq, req)) {
974                 return tevent_req_post(req, ev);
975         }
976         tevent_req_set_callback(subreq, share_mode_watch_done, req);
977         return req;
978 }
979
980 static void share_mode_watch_done(struct tevent_req *subreq)
981 {
982         struct tevent_req *req = tevent_req_callback_data(
983                 subreq, struct tevent_req);
984         struct share_mode_watch_state *state = tevent_req_data(
985                 req, struct share_mode_watch_state);
986         NTSTATUS status;
987
988         status = g_lock_watch_data_recv(
989                 subreq, &state->blockerdead, &state->blocker);
990         if (tevent_req_nterror(req, status)) {
991                 return;
992         }
993         tevent_req_done(req);
994 }
995
996 NTSTATUS share_mode_watch_recv(
997         struct tevent_req *req, bool *blockerdead, struct server_id *blocker)
998 {
999         struct share_mode_watch_state *state = tevent_req_data(
1000                 req, struct share_mode_watch_state);
1001         NTSTATUS status;
1002
1003         if (tevent_req_is_nterror(req, &status)) {
1004                 return status;
1005         }
1006         if (blockerdead != NULL) {
1007                 *blockerdead = state->blockerdead;
1008         }
1009         if (blocker != NULL) {
1010                 *blocker = state->blocker;
1011         }
1012         return NT_STATUS_OK;
1013 }
1014
1015 struct fetch_share_mode_unlocked_state {
1016         TALLOC_CTX *mem_ctx;
1017         TDB_DATA key;
1018         struct share_mode_lock *lck;
1019 };
1020
1021 static void fetch_share_mode_unlocked_parser(
1022         struct server_id exclusive,
1023         size_t num_shared,
1024         struct server_id *shared,
1025         const uint8_t *data,
1026         size_t datalen,
1027         void *private_data)
1028 {
1029         struct fetch_share_mode_unlocked_state *state = private_data;
1030
1031         if (datalen == 0) {
1032                 /* Likely a ctdb tombstone record, ignore it */
1033                 return;
1034         }
1035
1036         state->lck = talloc(state->mem_ctx, struct share_mode_lock);
1037         if (state->lck == NULL) {
1038                 DEBUG(0, ("talloc failed\n"));
1039                 return;
1040         }
1041
1042         state->lck->data = parse_share_modes(
1043                 state->lck, state->key, data, datalen);
1044 }
1045
1046 /*******************************************************************
1047  Get a share_mode_lock without locking the database or reference
1048  counting. Used by smbstatus to display existing share modes.
1049 ********************************************************************/
1050
1051 struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx,
1052                                                   struct file_id id)
1053 {
1054         struct fetch_share_mode_unlocked_state state = {
1055                 .mem_ctx = mem_ctx,
1056                 .key = locking_key(&id),
1057         };
1058         NTSTATUS status;
1059
1060         status = g_lock_dump(
1061                 lock_ctx, state.key, fetch_share_mode_unlocked_parser, &state);
1062         if (!NT_STATUS_IS_OK(status)) {
1063                 DBG_DEBUG("g_lock_dump failed: %s\n", nt_errstr(status));
1064                 return NULL;
1065         }
1066         return state.lck;
1067 }
1068
1069 struct fetch_share_mode_state {
1070         struct file_id id;
1071         struct share_mode_lock *lck;
1072         NTSTATUS status;
1073 };
1074
1075 static void fetch_share_mode_fn(
1076         struct server_id exclusive,
1077         size_t num_shared,
1078         struct server_id *shared,
1079         const uint8_t *data,
1080         size_t datalen,
1081         void *private_data);
1082 static void fetch_share_mode_done(struct tevent_req *subreq);
1083
1084 /**
1085  * @brief Get a share_mode_lock without locking or refcounting
1086  *
1087  * This can be used in a clustered Samba environment where the async dbwrap
1088  * request is sent over a socket to the local ctdbd. If the send queue is full
1089  * and the caller was issuing multiple async dbwrap requests in a loop, the
1090  * caller knows it's probably time to stop sending requests for now and try
1091  * again later.
1092  *
1093  * @param[in]  mem_ctx The talloc memory context to use.
1094  *
1095  * @param[in]  ev      The event context to work on.
1096  *
1097  * @param[in]  id      The file id for the locking.tdb key
1098  *
1099  * @param[out] queued  This boolean out parameter tells the caller whether the
1100  *                     async request is blocked in a full send queue:
1101  *
1102  *                     false := request is dispatched
1103  *
1104  *                     true  := send queue is full, request waiting to be
1105  *                              dispatched
1106  *
1107  * @return             The new async request, NULL on error.
1108  **/
1109 struct tevent_req *fetch_share_mode_send(TALLOC_CTX *mem_ctx,
1110                                          struct tevent_context *ev,
1111                                          struct file_id id,
1112                                          bool *queued)
1113 {
1114         struct tevent_req *req = NULL, *subreq = NULL;
1115         struct fetch_share_mode_state *state = NULL;
1116
1117         *queued = false;
1118
1119         req = tevent_req_create(mem_ctx, &state,
1120                                 struct fetch_share_mode_state);
1121         if (req == NULL) {
1122                 return NULL;
1123         }
1124         state->id = id;
1125
1126         subreq = g_lock_dump_send(
1127                 state,
1128                 ev,
1129                 lock_ctx,
1130                 locking_key(&id),
1131                 fetch_share_mode_fn,
1132                 state);
1133         if (tevent_req_nomem(subreq, req)) {
1134                 return tevent_req_post(req, ev);
1135         }
1136         tevent_req_set_callback(subreq, fetch_share_mode_done, req);
1137         return req;
1138 }
1139
1140 static void fetch_share_mode_fn(
1141         struct server_id exclusive,
1142         size_t num_shared,
1143         struct server_id *shared,
1144         const uint8_t *data,
1145         size_t datalen,
1146         void *private_data)
1147 {
1148         struct fetch_share_mode_state *state = talloc_get_type_abort(
1149                 private_data, struct fetch_share_mode_state);
1150
1151         state->lck = talloc(state, struct share_mode_lock);
1152         if (state->lck == NULL) {
1153                 DBG_WARNING("talloc failed\n");
1154                 state->status = NT_STATUS_NO_MEMORY;
1155                 return;
1156         }
1157
1158         state->lck->data = parse_share_modes(
1159                 state->lck, locking_key(&state->id), data, datalen);
1160 }
1161
1162 static void fetch_share_mode_done(struct tevent_req *subreq)
1163 {
1164         struct tevent_req *req = tevent_req_callback_data(
1165                 subreq, struct tevent_req);
1166         struct fetch_share_mode_state *state = tevent_req_data(
1167                 req, struct fetch_share_mode_state);
1168         NTSTATUS status;
1169
1170         status = g_lock_dump_recv(subreq);
1171         TALLOC_FREE(subreq);
1172         if (tevent_req_nterror(req, status)) {
1173                 return;
1174         }
1175         if (tevent_req_nterror(req, state->status)) {
1176                 return;
1177         }
1178         tevent_req_done(req);
1179 }
1180
1181 NTSTATUS fetch_share_mode_recv(struct tevent_req *req,
1182                                TALLOC_CTX *mem_ctx,
1183                                struct share_mode_lock **_lck)
1184 {
1185         struct fetch_share_mode_state *state = tevent_req_data(
1186                 req, struct fetch_share_mode_state);
1187         struct share_mode_lock *lck = NULL;
1188
1189         NTSTATUS status;
1190
1191         if (tevent_req_is_nterror(req, &status)) {
1192                 tevent_req_received(req);
1193                 return status;
1194         }
1195
1196         if (state->lck->data == NULL) {
1197                 tevent_req_received(req);
1198                 return NT_STATUS_NOT_FOUND;
1199         }
1200
1201         lck = talloc_move(mem_ctx, &state->lck);
1202
1203         if (DEBUGLEVEL >= 10) {
1204                 DBG_DEBUG("share_mode_data:\n");
1205                 NDR_PRINT_DEBUG(share_mode_data, lck->data);
1206         }
1207
1208         *_lck = lck;
1209         tevent_req_received(req);
1210         return NT_STATUS_OK;
1211 }
1212
1213 struct share_mode_forall_state {
1214         TDB_DATA key;
1215         int (*fn)(struct file_id fid,
1216                   const struct share_mode_data *data,
1217                   void *private_data);
1218         void *private_data;
1219 };
1220
1221 static void share_mode_forall_dump_fn(
1222         struct server_id exclusive,
1223         size_t num_shared,
1224         struct server_id *shared,
1225         const uint8_t *data,
1226         size_t datalen,
1227         void *private_data)
1228 {
1229         struct share_mode_forall_state *state = private_data;
1230         struct file_id fid;
1231         struct share_mode_data *d;
1232
1233         if (state->key.dsize != sizeof(fid)) {
1234                 DBG_DEBUG("Got invalid key length %zu\n", state->key.dsize);
1235                 return;
1236         }
1237         memcpy(&fid, state->key.dptr, sizeof(fid));
1238
1239         d = parse_share_modes(talloc_tos(), state->key, data, datalen);
1240         if (d == NULL) {
1241                 DBG_DEBUG("parse_share_modes() failed\n");
1242                 return;
1243         }
1244
1245         state->fn(fid, d, state->private_data);
1246         TALLOC_FREE(d);
1247 }
1248
1249 static int share_mode_forall_fn(TDB_DATA key, void *private_data)
1250 {
1251         struct share_mode_forall_state *state = private_data;
1252         NTSTATUS status;
1253
1254         state->key = key;
1255
1256         status = g_lock_dump(
1257                 lock_ctx, key, share_mode_forall_dump_fn, private_data);
1258         if (!NT_STATUS_IS_OK(status)) {
1259                 DBG_DEBUG("g_lock_dump failed: %s\n",
1260                           nt_errstr(status));
1261         }
1262         return 0;
1263 }
1264
1265 int share_mode_forall(int (*fn)(struct file_id fid,
1266                                 const struct share_mode_data *data,
1267                                 void *private_data),
1268                       void *private_data)
1269 {
1270         struct share_mode_forall_state state = {
1271                 .fn = fn,
1272                 .private_data = private_data
1273         };
1274         int ret;
1275
1276         if (lock_ctx == NULL) {
1277                 return 0;
1278         }
1279
1280         ret = g_lock_locks(
1281                 lock_ctx, share_mode_forall_fn, &state);
1282         if (ret < 0) {
1283                 DBG_DEBUG("g_lock_locks failed\n");
1284         }
1285         return ret;
1286 }
1287
1288 struct share_entry_forall_state {
1289         struct file_id fid;
1290         const struct share_mode_data *data;
1291         int (*fn)(struct file_id fid,
1292                   const struct share_mode_data *data,
1293                   const struct share_mode_entry *entry,
1294                   void *private_data);
1295         void *private_data;
1296         int ret;
1297 };
1298
1299 static bool share_entry_traverse_walker(
1300         struct share_mode_entry *e,
1301         bool *modified,
1302         void *private_data)
1303 {
1304         struct share_entry_forall_state *state = private_data;
1305
1306         state->ret = state->fn(
1307                 state->fid, state->data, e, state->private_data);
1308         return (state->ret != 0);
1309 }
1310
1311 static int share_entry_traverse_fn(struct file_id fid,
1312                                    const struct share_mode_data *data,
1313                                    void *private_data)
1314 {
1315         struct share_entry_forall_state *state = private_data;
1316         struct share_mode_lock lck = {
1317                 .data = discard_const_p(struct share_mode_data, data)
1318         };
1319         bool ok;
1320
1321         state->fid = fid;
1322         state->data = data;
1323
1324         ok = share_mode_forall_entries(
1325                 &lck, share_entry_traverse_walker, state);
1326         if (!ok) {
1327                 DBG_DEBUG("share_mode_forall_entries failed\n");
1328                 return false;
1329         }
1330
1331         return state->ret;
1332 }
1333
1334 /*******************************************************************
1335  Call the specified function on each entry under management by the
1336  share mode system.
1337 ********************************************************************/
1338
1339 int share_entry_forall(int (*fn)(struct file_id fid,
1340                                  const struct share_mode_data *data,
1341                                  const struct share_mode_entry *entry,
1342                                  void *private_data),
1343                       void *private_data)
1344 {
1345         struct share_entry_forall_state state = {
1346                 .fn = fn, .private_data = private_data };
1347
1348         return share_mode_forall(share_entry_traverse_fn, &state);
1349 }
1350
1351 struct cleanup_disconnected_state {
1352         struct share_mode_lock *lck;
1353         uint64_t open_persistent_id;
1354         size_t num_disconnected;
1355         bool found_connected;
1356 };
1357
1358 static bool cleanup_disconnected_lease(struct share_mode_entry *e,
1359                                        void *private_data)
1360 {
1361         struct cleanup_disconnected_state *state = private_data;
1362         NTSTATUS status;
1363
1364         status = leases_db_del(
1365                 &e->client_guid, &e->lease_key, &state->lck->data->id);
1366
1367         if (!NT_STATUS_IS_OK(status)) {
1368                 DBG_DEBUG("leases_db_del failed: %s\n",
1369                           nt_errstr(status));
1370         }
1371
1372         return false;
1373 }
1374
1375 static bool share_mode_find_connected_fn(
1376         struct share_mode_entry *e,
1377         bool *modified,
1378         void *private_data)
1379 {
1380         struct cleanup_disconnected_state *state = private_data;
1381         struct share_mode_data *d = state->lck->data;
1382         bool disconnected;
1383
1384         disconnected = server_id_is_disconnected(&e->pid);
1385         if (!disconnected) {
1386                 struct file_id_buf tmp1;
1387                 struct server_id_buf tmp2;
1388                 DBG_INFO("file (file-id='%s', servicepath='%s', "
1389                          "base_name='%s%s%s') "
1390                          "is used by server %s ==> do not cleanup\n",
1391                          file_id_str_buf(d->id, &tmp1),
1392                          d->servicepath,
1393                          d->base_name,
1394                          (d->stream_name == NULL)
1395                          ? "" : "', stream_name='",
1396                          (d->stream_name == NULL)
1397                          ? "" : d->stream_name,
1398                          server_id_str_buf(e->pid, &tmp2));
1399                 state->found_connected = true;
1400                 return true;
1401         }
1402
1403         if (state->open_persistent_id != e->share_file_id) {
1404                 struct file_id_buf tmp;
1405                 DBG_INFO("entry for file "
1406                          "(file-id='%s', servicepath='%s', "
1407                          "base_name='%s%s%s') "
1408                          "has share_file_id %"PRIu64" but expected "
1409                          "%"PRIu64"==> do not cleanup\n",
1410                          file_id_str_buf(d->id, &tmp),
1411                          d->servicepath,
1412                          d->base_name,
1413                          (d->stream_name == NULL)
1414                          ? "" : "', stream_name='",
1415                          (d->stream_name == NULL)
1416                          ? "" : d->stream_name,
1417                          e->share_file_id,
1418                          state->open_persistent_id);
1419                 state->found_connected = true;
1420                 return true;
1421         }
1422
1423         state->num_disconnected += 1;
1424
1425         return false;
1426 }
1427
1428 bool share_mode_cleanup_disconnected(struct file_id fid,
1429                                      uint64_t open_persistent_id)
1430 {
1431         struct cleanup_disconnected_state state = {
1432                 .open_persistent_id = open_persistent_id
1433         };
1434         struct share_mode_data *data;
1435         bool ret = false;
1436         TALLOC_CTX *frame = talloc_stackframe();
1437         struct file_id_buf idbuf;
1438         NTSTATUS status;
1439         bool ok;
1440
1441         state.lck = get_existing_share_mode_lock(frame, fid);
1442         if (state.lck == NULL) {
1443                 DBG_INFO("Could not fetch share mode entry for %s\n",
1444                          file_id_str_buf(fid, &idbuf));
1445                 goto done;
1446         }
1447         data = state.lck->data;
1448
1449         ok = share_mode_forall_entries(
1450                 state.lck, share_mode_find_connected_fn, &state);
1451         if (!ok) {
1452                 DBG_DEBUG("share_mode_forall_entries failed\n");
1453                 goto done;
1454         }
1455         if (state.found_connected) {
1456                 DBG_DEBUG("Found connected entry\n");
1457                 goto done;
1458         }
1459
1460         ok = share_mode_forall_leases(
1461                 state.lck, cleanup_disconnected_lease, &state);
1462         if (!ok) {
1463                 DBG_DEBUG("failed to clean up leases associated "
1464                           "with file (file-id='%s', servicepath='%s', "
1465                           "base_name='%s%s%s') and open_persistent_id %"PRIu64" "
1466                           "==> do not cleanup\n",
1467                           file_id_str_buf(fid, &idbuf),
1468                           data->servicepath,
1469                           data->base_name,
1470                           (data->stream_name == NULL)
1471                           ? "" : "', stream_name='",
1472                           (data->stream_name == NULL)
1473                           ? "" : data->stream_name,
1474                           open_persistent_id);
1475         }
1476
1477         ok = brl_cleanup_disconnected(fid, open_persistent_id);
1478         if (!ok) {
1479                 DBG_DEBUG("failed to clean up byte range locks associated "
1480                           "with file (file-id='%s', servicepath='%s', "
1481                           "base_name='%s%s%s') and open_persistent_id %"PRIu64" "
1482                           "==> do not cleanup\n",
1483                           file_id_str_buf(fid, &idbuf),
1484                           data->servicepath,
1485                           data->base_name,
1486                           (data->stream_name == NULL)
1487                           ? "" : "', stream_name='",
1488                           (data->stream_name == NULL)
1489                           ? "" : data->stream_name,
1490                           open_persistent_id);
1491                 goto done;
1492         }
1493
1494         DBG_DEBUG("cleaning up %zu entries for file "
1495                   "(file-id='%s', servicepath='%s', "
1496                   "base_name='%s%s%s') "
1497                   "from open_persistent_id %"PRIu64"\n",
1498                   state.num_disconnected,
1499                   file_id_str_buf(fid, &idbuf),
1500                   data->servicepath,
1501                   data->base_name,
1502                   (data->stream_name == NULL)
1503                   ? "" : "', stream_name='",
1504                   (data->stream_name == NULL)
1505                   ? "" : data->stream_name,
1506                   open_persistent_id);
1507
1508         /*
1509          * No connected share entries left, wipe them all
1510          */
1511         status = dbwrap_delete(share_entries_db, locking_key(&fid));
1512         if (!NT_STATUS_IS_OK(status)) {
1513                 DBG_DEBUG("dbwrap_delete failed: %s\n",
1514                           nt_errstr(status));
1515                 goto done;
1516         }
1517
1518         data->have_share_modes = false;
1519         data->modified = true;
1520
1521         ret = true;
1522 done:
1523         talloc_free(frame);
1524         return ret;
1525 }
1526
1527 static int share_mode_entry_cmp(
1528         struct server_id pid1,
1529         uint64_t share_file_id1,
1530         struct server_id pid2,
1531         uint64_t share_file_id2)
1532 {
1533         int cmp;
1534
1535         cmp = server_id_cmp(&pid1, &pid2);
1536         if (cmp != 0) {
1537                 return cmp;
1538         }
1539         if (share_file_id1 != share_file_id2) {
1540                 return (share_file_id1 < share_file_id2) ? -1 : 1;
1541         }
1542         return 0;
1543 }
1544
1545 static size_t share_mode_entry_find(
1546         const uint8_t *data,
1547         size_t num_share_modes,
1548         struct server_id pid,
1549         uint64_t share_file_id,
1550         struct share_mode_entry *e,
1551         bool *match)
1552 {
1553         ssize_t left, right, middle;
1554
1555         if (num_share_modes == 0) {
1556                 *match = false;
1557                 return 0;
1558         }
1559
1560         left = 0;
1561         right = (num_share_modes-1);
1562
1563         while (left <= right) {
1564                 const uint8_t *middle_ptr = NULL;
1565                 int cmp;
1566                 bool ok;
1567
1568                 middle = left + ((right - left) / 2);
1569                 middle_ptr = data + middle * SHARE_MODE_ENTRY_SIZE;
1570
1571                 DBG_DEBUG("left=%zu, right=%zu, middle=%zu, middle_ptr=%p\n",
1572                           left,
1573                           right,
1574                           middle,
1575                           middle_ptr);
1576
1577                 ok = share_mode_entry_get(middle_ptr, e);
1578                 if (!ok) {
1579                         DBG_DEBUG("share_mode_entry_get failed\n");
1580                         return false;
1581                 }
1582
1583                 cmp = share_mode_entry_cmp(
1584                         e->pid, e->share_file_id, pid, share_file_id);
1585                 if (cmp == 0) {
1586                         *match = true;
1587                         return middle;
1588                 }
1589
1590                 if (cmp < 0) {
1591                         right = middle-1;
1592                 } else {
1593                         left = middle+1;
1594                 }
1595         }
1596
1597         *match = false;
1598         return left;
1599 }
1600
1601 struct set_share_mode_state {
1602         struct share_mode_entry e;
1603         bool created_share_mode_record;
1604         NTSTATUS status;
1605 };
1606
1607 static void set_share_mode_fn(
1608         struct db_record *rec,
1609         TDB_DATA data,
1610         void *private_data)
1611 {
1612         struct set_share_mode_state *state = private_data;
1613         size_t idx, num_share_modes;
1614         struct share_mode_entry tmp;
1615         struct share_mode_entry_buf buf;
1616         bool ok, found;
1617
1618         TDB_DATA dbufs[3];
1619         size_t num_dbufs = 0;
1620
1621         if ((data.dsize % SHARE_MODE_ENTRY_SIZE) != 0) {
1622                 DBG_WARNING("Got invalid record size %zu\n", data.dsize);
1623                 state->status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1624                 return;
1625         }
1626         num_share_modes = data.dsize / SHARE_MODE_ENTRY_SIZE;
1627
1628         ok = share_mode_entry_put(&state->e, &buf);
1629         if (!ok) {
1630                 DBG_DEBUG("share_mode_entry_put failed\n");
1631                 state->status = NT_STATUS_INTERNAL_ERROR;
1632                 return;
1633         }
1634
1635         DBG_DEBUG("num_share_modes=%zu\n", num_share_modes);
1636
1637         idx = share_mode_entry_find(
1638                 data.dptr,
1639                 num_share_modes,
1640                 state->e.pid,
1641                 state->e.share_file_id,
1642                 &tmp,
1643                 &found);
1644         if (found) {
1645                 DBG_WARNING("Found duplicate share mode\n");
1646                 state->status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1647                 return;
1648         }
1649
1650         DBG_DEBUG("idx=%zu, found=%d\n", idx, (int)found);
1651
1652         if (idx > 0) {
1653                 dbufs[num_dbufs] = (TDB_DATA) {
1654                         .dptr = data.dptr,
1655                         .dsize = idx * SHARE_MODE_ENTRY_SIZE,
1656                 };
1657                 num_dbufs += 1;
1658         }
1659
1660         dbufs[num_dbufs] = (TDB_DATA) {
1661                 .dptr = buf.buf, .dsize = SHARE_MODE_ENTRY_SIZE,
1662         };
1663         num_dbufs += 1;
1664
1665         if (idx < num_share_modes) {
1666                 dbufs[num_dbufs] = (TDB_DATA) {
1667                         .dptr = data.dptr + idx * SHARE_MODE_ENTRY_SIZE,
1668                         .dsize = (num_share_modes-idx) * SHARE_MODE_ENTRY_SIZE,
1669                 };
1670                 num_dbufs += 1;
1671         }
1672
1673         {
1674                 size_t i;
1675                 for (i=0; i<num_dbufs; i++) {
1676                         DBG_DEBUG("dbufs[%zu]=(%p, %zu)\n",
1677                                   i,
1678                                   dbufs[i].dptr,
1679                                   dbufs[i].dsize);
1680                 }
1681         }
1682
1683         state->created_share_mode_record = (num_share_modes == 0);
1684         state->status = dbwrap_record_storev(rec, dbufs, num_dbufs, 0);
1685 }
1686
1687 bool set_share_mode(struct share_mode_lock *lck,
1688                     struct files_struct *fsp,
1689                     uid_t uid,
1690                     uint64_t mid,
1691                     uint16_t op_type,
1692                     uint32_t share_access,
1693                     uint32_t access_mask)
1694 {
1695         struct share_mode_data *d = lck->data;
1696         struct set_share_mode_state state = {
1697                 .status = NT_STATUS_OK,
1698                 .e.pid = messaging_server_id(fsp->conn->sconn->msg_ctx),
1699                 .e.share_access = share_access,
1700                 .e.private_options = fsp->fh->private_options,
1701                 .e.access_mask = access_mask,
1702                 .e.op_mid = mid,
1703                 .e.op_type = op_type,
1704                 .e.time.tv_sec = fsp->open_time.tv_sec,
1705                 .e.time.tv_usec = fsp->open_time.tv_usec,
1706                 .e.share_file_id = fsp->fh->gen_id,
1707                 .e.uid = (uint32_t)uid,
1708                 .e.flags = (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) ?
1709                 SHARE_MODE_FLAG_POSIX_OPEN : 0,
1710                 .e.name_hash = fsp->name_hash,
1711         };
1712         NTSTATUS status;
1713
1714         if (op_type == LEASE_OPLOCK) {
1715                 const struct GUID *client_guid = fsp_client_guid(fsp);
1716                 state.e.client_guid = *client_guid;
1717                 state.e.lease_key = fsp->lease->lease.lease_key;
1718         }
1719
1720         status = dbwrap_do_locked(
1721                 share_entries_db,
1722                 locking_key(&d->id),
1723                 set_share_mode_fn,
1724                 &state);
1725         if (!NT_STATUS_IS_OK(status)) {
1726                 DBG_WARNING("dbwrap_do_locked failed: %s\n",
1727                             nt_errstr(status));
1728                 return false;
1729         }
1730         if (!NT_STATUS_IS_OK(state.status)) {
1731                 DBG_WARNING("set_share_mode_fn failed: %s\n",
1732                             nt_errstr(state.status));
1733                 return false;
1734         }
1735
1736         if (state.created_share_mode_record) {
1737                 d->have_share_modes = true;
1738                 d->modified = true;
1739         }
1740
1741         return true;
1742 }
1743
1744 struct share_mode_forall_entries_state {
1745         struct share_mode_lock *lck;
1746         bool (*fn)(struct share_mode_entry *e,
1747                    bool *modified,
1748                    void *private_data);
1749         void *private_data;
1750         bool ok;
1751 };
1752
1753 static bool share_mode_for_one_entry(
1754         struct share_mode_forall_entries_state *state,
1755         size_t *i,
1756         uint8_t *data,
1757         size_t *num_share_modes,
1758         bool *writeback)
1759 {
1760         DATA_BLOB blob = {
1761                 .data = data + (*i) * SHARE_MODE_ENTRY_SIZE,
1762                 .length = SHARE_MODE_ENTRY_SIZE,
1763         };
1764         struct share_mode_entry e = {.pid.pid=0};
1765         enum ndr_err_code ndr_err = NDR_ERR_SUCCESS;
1766         bool modified = false;
1767         bool stop = false;
1768         struct server_id e_pid;
1769         uint64_t e_share_file_id;
1770
1771         ndr_err = ndr_pull_struct_blob_all_noalloc(
1772                 &blob,
1773                 &e,
1774                 (ndr_pull_flags_fn_t)ndr_pull_share_mode_entry);
1775         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1776                 DBG_WARNING("ndr_pull_share_mode_entry failed\n");
1777                 *i += 1;
1778                 return false;
1779         }
1780         if (DEBUGLEVEL >= 10) {
1781                 DBG_DEBUG("entry[%zu]:\n", *i);
1782                 NDR_PRINT_DEBUG(share_mode_entry, &e);
1783         }
1784
1785         e_pid = e.pid;
1786         e_share_file_id = e.share_file_id;
1787
1788         stop = state->fn(&e, &modified, state->private_data);
1789
1790         DBG_DEBUG("entry[%zu]: modified=%d, e.stale=%d\n",
1791                   *i,
1792                   (int)modified,
1793                   (int)e.stale);
1794
1795         if (modified) {
1796                 if (DEBUGLEVEL>=10) {
1797                         DBG_DEBUG("share_mode_entry:\n");
1798                         NDR_PRINT_DEBUG(share_mode_entry, &e);
1799                 }
1800
1801                 /*
1802                  * Make sure sorting order is kept intact
1803                  */
1804                 SMB_ASSERT(server_id_equal(&e_pid, &e.pid));
1805                 SMB_ASSERT(e_share_file_id == e.share_file_id);
1806
1807                 ndr_err = ndr_push_struct_into_fixed_blob(
1808                         &blob,
1809                         &e,
1810                         (ndr_push_flags_fn_t)
1811                         ndr_push_share_mode_entry);
1812                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1813                         DBG_WARNING("ndr_push_share_mode_entry "
1814                                     "failed: %s\n",
1815                                     ndr_errstr(ndr_err));
1816                         /*
1817                          * Not much we can do, just ignore it
1818                          */
1819                 }
1820                 *i += 1;
1821                 *writeback = true;
1822                 return stop;
1823         }
1824
1825         if (e.stale) {
1826                 if (*i < *num_share_modes) {
1827                         memmove(blob.data,
1828                                 blob.data + SHARE_MODE_ENTRY_SIZE,
1829                                 (*num_share_modes - *i - 1) *
1830                                 SHARE_MODE_ENTRY_SIZE);
1831                 }
1832                 *num_share_modes -= 1;
1833                 *writeback = true;
1834                 return stop;
1835         }
1836
1837         if (stop) {
1838                 return true;
1839         }
1840
1841         *i += 1;
1842         return false;
1843 }
1844
1845 static void share_mode_forall_entries_fn(
1846         struct db_record *rec,
1847         TDB_DATA data,
1848         void *private_data)
1849 {
1850         struct share_mode_forall_entries_state *state = private_data;
1851         struct share_mode_data *d = state->lck->data;
1852         size_t num_share_modes;
1853         bool writeback = false;
1854         NTSTATUS status;
1855         bool stop = false;
1856         size_t i;
1857
1858         if ((data.dsize % SHARE_MODE_ENTRY_SIZE) != 0) {
1859                 DBG_WARNING("Invalid data size %zu\n", data.dsize);
1860                 return;
1861         }
1862         num_share_modes = data.dsize / SHARE_MODE_ENTRY_SIZE;
1863
1864         DBG_DEBUG("num_share_modes=%zu\n", num_share_modes);
1865
1866         i = 0;
1867         while (i<num_share_modes) {
1868                 stop = share_mode_for_one_entry(
1869                         state, &i, data.dptr, &num_share_modes, &writeback);
1870                 if (stop) {
1871                         break;
1872                 }
1873         }
1874
1875         DBG_DEBUG("num_share_modes=%zu, writeback=%d\n",
1876                   num_share_modes,
1877                   (int)writeback);
1878
1879         if (!writeback) {
1880                 state->ok = true;
1881                 return;
1882         }
1883
1884         if (num_share_modes == 0) {
1885                 if (data.dsize != 0) {
1886                         d->have_share_modes = false;
1887                         d->modified = true;
1888                 }
1889                 status = dbwrap_record_delete(rec);
1890         } else {
1891                 TDB_DATA value = {
1892                         .dptr = data.dptr,
1893                         .dsize = num_share_modes * SHARE_MODE_ENTRY_SIZE,
1894                 };
1895                 status = dbwrap_record_store(rec, value, 0);
1896         }
1897
1898         if (!NT_STATUS_IS_OK(status)) {
1899                 DBG_DEBUG("Storing record with %zu entries failed: %s\n",
1900                           num_share_modes,
1901                           nt_errstr(status));
1902                 return;
1903         }
1904
1905
1906         state->ok = true;
1907 }
1908
1909 bool share_mode_forall_entries(
1910         struct share_mode_lock *lck,
1911         bool (*fn)(struct share_mode_entry *e,
1912                    bool *modified,
1913                    void *private_data),
1914         void *private_data)
1915 {
1916         struct share_mode_forall_entries_state state = {
1917                 .lck = lck,
1918                 .fn = fn,
1919                 .private_data = private_data,
1920         };
1921         NTSTATUS status;
1922
1923         status = dbwrap_do_locked(
1924                 share_entries_db,
1925                 locking_key(&lck->data->id),
1926                 share_mode_forall_entries_fn,
1927                 &state);
1928         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
1929                 status = NT_STATUS_OK;
1930                 state.ok = true;
1931         }
1932         if (!NT_STATUS_IS_OK(status)) {
1933                 DBG_DEBUG("dbwrap_do_locked failed: %s\n",
1934                           nt_errstr(status));
1935                 return false;
1936         }
1937
1938         return state.ok;
1939 }
1940
1941 struct share_mode_count_entries_state {
1942         size_t num_share_modes;
1943         NTSTATUS status;
1944 };
1945
1946 static void share_mode_count_entries_fn(
1947         TDB_DATA key, TDB_DATA data, void *private_data)
1948 {
1949         struct share_mode_count_entries_state *state = private_data;
1950
1951         if ((data.dsize % SHARE_MODE_ENTRY_SIZE) != 0) {
1952                 DBG_WARNING("Invalid data size %zu\n", data.dsize);
1953                 state->status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1954                 return;
1955         }
1956         state->num_share_modes = data.dsize / SHARE_MODE_ENTRY_SIZE;
1957         state->status = NT_STATUS_OK;
1958 }
1959
1960 NTSTATUS share_mode_count_entries(struct file_id fid, size_t *num_share_modes)
1961 {
1962         struct share_mode_count_entries_state state = {
1963                 .status = NT_STATUS_NOT_FOUND,
1964         };
1965         NTSTATUS status;
1966
1967         status = dbwrap_parse_record(
1968                 share_entries_db,
1969                 locking_key(&fid),
1970                 share_mode_count_entries_fn,
1971                 &state);
1972         if (!NT_STATUS_IS_OK(status)) {
1973                 DBG_DEBUG("dbwrap_parse_record failed: %s\n",
1974                           nt_errstr(status));
1975                 return status;
1976         }
1977         if (!NT_STATUS_IS_OK(state.status)) {
1978                 DBG_DEBUG("share_mode_forall_entries_fn failed: %s\n",
1979                           nt_errstr(state.status));
1980                 return state.status;
1981         }
1982
1983         *num_share_modes = state.num_share_modes;
1984         return NT_STATUS_OK;
1985 }
1986
1987 struct share_mode_entry_do_state {
1988         struct server_id pid;
1989         uint64_t share_file_id;
1990         void (*fn)(struct share_mode_entry *e,
1991                    size_t num_share_modes,
1992                    bool *modified,
1993                    void *private_data);
1994         void *private_data;
1995         size_t num_share_modes;
1996         NTSTATUS status;
1997 };
1998
1999 static void share_mode_entry_do_fn(
2000         struct db_record *rec,
2001         TDB_DATA data,
2002         void *private_data)
2003 {
2004         struct share_mode_entry_do_state *state = private_data;
2005         size_t idx;
2006         bool found = false;
2007         bool modified;
2008         struct share_mode_entry e;
2009         struct share_mode_entry_buf buf;
2010         TDB_DATA dbufs[3];
2011         size_t num_dbufs = 0;
2012
2013         if ((data.dsize % SHARE_MODE_ENTRY_SIZE) != 0) {
2014                 DBG_WARNING("Invalid data size %zu\n", data.dsize);
2015                 state->status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2016                 return;
2017         }
2018         state->num_share_modes = data.dsize / SHARE_MODE_ENTRY_SIZE;
2019
2020         DBG_DEBUG("state->num_share_modes=%zu\n", state->num_share_modes);
2021
2022         idx = share_mode_entry_find(
2023                 data.dptr,
2024                 state->num_share_modes,
2025                 state->pid,
2026                 state->share_file_id,
2027                 &e,
2028                 &found);
2029         if (!found) {
2030                 DBG_WARNING("Did not find share mode entry for %"PRIu64"\n",
2031                             state->share_file_id);
2032                 state->status = NT_STATUS_NOT_FOUND;
2033                 return;
2034         }
2035
2036         state->fn(&e, state->num_share_modes, &modified, state->private_data);
2037
2038         if (!e.stale && !modified) {
2039                 state->status = NT_STATUS_OK;
2040                 return;
2041         }
2042
2043         if (idx > 0) {
2044                 dbufs[num_dbufs] = (TDB_DATA) {
2045                         .dptr = data.dptr,
2046                         .dsize = idx * SHARE_MODE_ENTRY_SIZE,
2047                 };
2048                 num_dbufs += 1;
2049         }
2050
2051         if (!e.stale) {
2052                 bool ok;
2053
2054                 if (state->num_share_modes != 1) {
2055                         /*
2056                          * Make sure the sorting order stays intact
2057                          */
2058                         SMB_ASSERT(server_id_equal(&e.pid, &state->pid));
2059                         SMB_ASSERT(e.share_file_id == state->share_file_id);
2060                 }
2061
2062                 ok = share_mode_entry_put(&e, &buf);
2063                 if (!ok) {
2064                         DBG_DEBUG("share_mode_entry_put failed\n");
2065                         state->status = NT_STATUS_INTERNAL_ERROR;
2066                         return;
2067                 }
2068
2069                 dbufs[num_dbufs] = (TDB_DATA) {
2070                         .dptr = buf.buf, .dsize = SHARE_MODE_ENTRY_SIZE,
2071                 };
2072                 num_dbufs += 1;
2073         }
2074
2075         idx += 1;
2076
2077         if (idx < state->num_share_modes) {
2078                 size_t behind = state->num_share_modes - idx;
2079                 dbufs[num_dbufs] = (TDB_DATA) {
2080                         .dptr = data.dptr + idx * SHARE_MODE_ENTRY_SIZE,
2081                         .dsize = behind * SHARE_MODE_ENTRY_SIZE,
2082                 };
2083                 num_dbufs += 1;
2084         }
2085
2086         if (e.stale) {
2087                 state->num_share_modes -= 1;
2088         }
2089
2090         if (state->num_share_modes == 0) {
2091                 state->status = dbwrap_record_delete(rec);
2092                 if (!NT_STATUS_IS_OK(state->status)) {
2093                         DBG_DEBUG("dbwrap_record_delete failed: %s\n",
2094                                   nt_errstr(state->status));
2095                 }
2096                 return;
2097         }
2098
2099         state->status = dbwrap_record_storev(rec, dbufs, num_dbufs, 0);
2100         if (!NT_STATUS_IS_OK(state->status)) {
2101                 DBG_DEBUG("dbwrap_record_storev failed: %s\n",
2102                           nt_errstr(state->status));
2103                 return;
2104         }
2105 }
2106
2107 static bool share_mode_entry_do(
2108         struct share_mode_lock *lck,
2109         struct server_id pid,
2110         uint64_t share_file_id,
2111         void (*fn)(struct share_mode_entry *e,
2112                    size_t num_share_modes,
2113                    bool *modified,
2114                    void *private_data),
2115         void *private_data)
2116 {
2117         struct share_mode_data *d = lck->data;
2118         struct share_mode_entry_do_state state = {
2119                 .pid = pid,
2120                 .share_file_id = share_file_id,
2121                 .fn = fn,
2122                 .private_data = private_data,
2123         };
2124         NTSTATUS status;
2125         bool have_share_modes;
2126
2127         status = dbwrap_do_locked(
2128                 share_entries_db,
2129                 locking_key(&d->id),
2130                 share_mode_entry_do_fn,
2131                 &state);
2132         if (!NT_STATUS_IS_OK(status)) {
2133                 DBG_DEBUG("share_mode_forall_entries failed: %s\n",
2134                           nt_errstr(status));
2135                 return false;
2136         }
2137         if (!NT_STATUS_IS_OK(state.status)) {
2138                 DBG_DEBUG("share_mode_entry_do_fn failed: %s\n",
2139                           nt_errstr(status));
2140                 return false;
2141         }
2142
2143         have_share_modes = (state.num_share_modes != 0);
2144         if (d->have_share_modes != have_share_modes) {
2145                 d->have_share_modes = have_share_modes;
2146                 d->modified = true;
2147         }
2148
2149         return true;
2150 }
2151
2152 struct del_share_mode_state {
2153         bool ok;
2154 };
2155
2156 static void del_share_mode_fn(
2157         struct share_mode_entry *e,
2158         size_t num_share_modes,
2159         bool *modified,
2160         void *private_data)
2161 {
2162         struct del_share_mode_state *state = private_data;
2163         e->stale = true;
2164         state->ok = true;
2165 }
2166
2167 bool del_share_mode(struct share_mode_lock *lck, files_struct *fsp)
2168 {
2169         struct del_share_mode_state state = { .ok = false };
2170         bool ok;
2171
2172         ok = share_mode_entry_do(
2173                 lck,
2174                 messaging_server_id(fsp->conn->sconn->msg_ctx),
2175                 fsp->fh->gen_id,
2176                 del_share_mode_fn,
2177                 &state);
2178         if (!ok) {
2179                 DBG_DEBUG("share_mode_entry_do failed\n");
2180                 return false;
2181         }
2182         if (!state.ok) {
2183                 DBG_DEBUG("del_share_mode_fn failed\n");
2184                 return false;
2185         }
2186         return true;
2187 }
2188
2189 struct remove_share_oplock_state {
2190         bool ok;
2191 };
2192
2193 static void remove_share_oplock_fn(
2194         struct share_mode_entry *e,
2195         size_t num_share_modes,
2196         bool *modified,
2197         void *private_data)
2198 {
2199         struct remove_share_oplock_state *state = private_data;
2200
2201         e->op_type = NO_OPLOCK;
2202         *modified = true;
2203         state->ok = true;
2204 }
2205
2206 bool remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
2207 {
2208         struct remove_share_oplock_state state = { .ok = false };
2209         bool ok;
2210
2211         ok = share_mode_entry_do(
2212                 lck,
2213                 messaging_server_id(fsp->conn->sconn->msg_ctx),
2214                 fsp->fh->gen_id,
2215                 remove_share_oplock_fn,
2216                 &state);
2217         if (!ok) {
2218                 DBG_DEBUG("share_mode_entry_do failed\n");
2219                 return false;
2220         }
2221         if (!state.ok) {
2222                 DBG_DEBUG("remove_share_oplock_fn failed\n");
2223                 return false;
2224         }
2225
2226         if (fsp->oplock_type == LEASE_OPLOCK) {
2227                 remove_lease_if_stale(
2228                         lck,
2229                         fsp_client_guid(fsp),
2230                         &fsp->lease->lease.lease_key);
2231         }
2232
2233         share_mode_wakeup_waiters(fsp->file_id);
2234
2235         return true;
2236 }
2237
2238 struct downgrade_share_oplock_state {
2239         bool ok;
2240 };
2241
2242 static void downgrade_share_oplock_fn(
2243         struct share_mode_entry *e,
2244         size_t num_share_modes,
2245         bool *modified,
2246         void *private_data)
2247 {
2248         struct downgrade_share_oplock_state *state = private_data;
2249
2250         e->op_type = LEVEL_II_OPLOCK;
2251         *modified = true;
2252         state->ok = true;
2253 }
2254
2255 bool downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
2256 {
2257         struct downgrade_share_oplock_state state = { .ok = false };
2258         bool ok;
2259
2260         ok = share_mode_entry_do(
2261                 lck,
2262                 messaging_server_id(fsp->conn->sconn->msg_ctx),
2263                 fsp->fh->gen_id,
2264                 downgrade_share_oplock_fn,
2265                 &state);
2266         if (!ok) {
2267                 DBG_DEBUG("share_mode_entry_do failed\n");
2268                 return false;
2269         }
2270         if (!state.ok) {
2271                 DBG_DEBUG("downgrade_share_oplock_fn failed\n");
2272                 return false;
2273         }
2274
2275         lck->data->flags |= SHARE_MODE_LEASE_READ;
2276         lck->data->modified = true;
2277
2278         return true;
2279 }
2280
2281 struct mark_share_mode_disconnected_state {
2282         uint64_t open_persistent_id;
2283         bool ok;
2284 };
2285
2286 static void mark_share_mode_disconnected_fn(
2287         struct share_mode_entry *e,
2288         size_t num_share_modes,
2289         bool *modified,
2290         void *private_data)
2291 {
2292         struct mark_share_mode_disconnected_state *state = private_data;
2293
2294         if (num_share_modes != 1) {
2295                 state->ok = false;
2296                 return;
2297         }
2298
2299         server_id_set_disconnected(&e->pid);
2300         e->share_file_id = state->open_persistent_id;
2301         *modified = true;
2302         state->ok = true;
2303 }
2304
2305 bool mark_share_mode_disconnected(struct share_mode_lock *lck,
2306                                   struct files_struct *fsp)
2307 {
2308         struct mark_share_mode_disconnected_state state;
2309         bool ok;
2310
2311         if (fsp->op == NULL) {
2312                 return false;
2313         }
2314         if (!fsp->op->global->durable) {
2315                 return false;
2316         }
2317
2318         state = (struct mark_share_mode_disconnected_state) {
2319                 .open_persistent_id = fsp->op->global->open_persistent_id,
2320         };
2321
2322         ok = share_mode_entry_do(
2323                 lck,
2324                 messaging_server_id(fsp->conn->sconn->msg_ctx),
2325                 fsp->fh->gen_id,
2326                 mark_share_mode_disconnected_fn,
2327                 &state);
2328         if (!ok) {
2329                 DBG_DEBUG("share_mode_entry_do failed\n");
2330                 return false;
2331         }
2332         if (!state.ok) {
2333                 DBG_DEBUG("mark_share_mode_disconnected_fn failed\n");
2334                 return false;
2335         }
2336
2337         lck->data->modified = true;
2338         return true;
2339 }
2340
2341 struct reset_share_mode_entry_state {
2342         struct server_id old_pid;
2343         uint64_t old_share_file_id;
2344         struct server_id new_pid;
2345         uint64_t new_mid;
2346         uint64_t new_share_file_id;
2347         bool ok;
2348 };
2349
2350 static void reset_share_mode_entry_fn(
2351         struct db_record *rec, TDB_DATA value, void *private_data)
2352 {
2353         struct reset_share_mode_entry_state *state = private_data;
2354         struct share_mode_entry e;
2355         struct share_mode_entry_buf e_buf;
2356         TDB_DATA newval = { .dptr = e_buf.buf, .dsize = sizeof(e_buf.buf) };
2357         NTSTATUS status;
2358         int ret;
2359         bool ok;
2360
2361         if (value.dsize != SHARE_MODE_ENTRY_SIZE) {
2362                 DBG_WARNING("Expect one entry, got %zu bytes\n",
2363                             value.dsize);
2364                 return;
2365         }
2366
2367         ok = share_mode_entry_get(value.dptr, &e);
2368         if (!ok) {
2369                 DBG_WARNING("share_mode_entry_get failed\n");
2370                 return;
2371         }
2372
2373         ret = share_mode_entry_cmp(
2374                 state->old_pid,
2375                 state->old_share_file_id,
2376                 e.pid,
2377                 e.share_file_id);
2378         if (ret != 0) {
2379                 struct server_id_buf tmp1, tmp2;
2380                 DBG_WARNING("Expected pid=%s, file_id=%"PRIu64", "
2381                             "got pid=%s, file_id=%"PRIu64"\n",
2382                             server_id_str_buf(state->old_pid, &tmp1),
2383                             state->old_share_file_id,
2384                             server_id_str_buf(e.pid, &tmp2),
2385                             e.share_file_id);
2386                 return;
2387         }
2388
2389         e.pid = state->new_pid;
2390         e.op_mid = state->new_mid;
2391         e.share_file_id = state->new_share_file_id;
2392
2393         ok = share_mode_entry_put(&e, &e_buf);
2394         if (!ok) {
2395                 DBG_WARNING("share_mode_entry_put failed\n");
2396                 return;
2397         }
2398
2399         status = dbwrap_record_store(rec, newval, 0);
2400         if (!NT_STATUS_IS_OK(status)) {
2401                 DBG_WARNING("dbwrap_record_store failed: %s\n",
2402                             nt_errstr(status));
2403                 return;
2404         }
2405
2406         state->ok = true;
2407 }
2408
2409 bool reset_share_mode_entry(
2410         struct share_mode_lock *lck,
2411         struct server_id old_pid,
2412         uint64_t old_share_file_id,
2413         struct server_id new_pid,
2414         uint64_t new_mid,
2415         uint64_t new_share_file_id)
2416 {
2417         struct share_mode_data *d = lck->data;
2418         struct reset_share_mode_entry_state state = {
2419                 .old_pid = old_pid,
2420                 .old_share_file_id = old_share_file_id,
2421                 .new_pid = new_pid,
2422                 .new_mid = new_mid,
2423                 .new_share_file_id = new_share_file_id,
2424         };
2425         NTSTATUS status;
2426
2427         status = dbwrap_do_locked(
2428                 share_entries_db,
2429                 locking_key(&d->id),
2430                 reset_share_mode_entry_fn,
2431                 &state);
2432         if (!NT_STATUS_IS_OK(status)) {
2433                 DBG_WARNING("dbwrap_do_locked failed: %s\n",
2434                             nt_errstr(status));
2435                 return false;
2436         }
2437         if (!state.ok) {
2438                 DBG_WARNING("reset_share_mode_fn failed\n");
2439                 return false;
2440         }
2441         d->have_share_modes = true;
2442
2443         return true;
2444 }