s3:locking: fix debug level for NT_STATUS_NOT_FOUND messanges in get_static_share_mod...
[metze/samba/wip.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 "lib/util/time_basic.h"
40 #include "system/filesys.h"
41 #include "lib/util/server_id.h"
42 #include "share_mode_lock_private.h"
43 struct share_mode_lock {
44         struct file_id id;
45         struct share_mode_data *cached_data;
46 };
47 #define SHARE_MODE_ENTRY_PREPARE_STATE_LCK_SPACE 1
48 #include "share_mode_lock.h"
49 #include "locking/proto.h"
50 #include "smbd/globals.h"
51 #include "dbwrap/dbwrap.h"
52 #include "dbwrap/dbwrap_open.h"
53 #include "dbwrap/dbwrap_private.h"
54 #include "../libcli/security/security.h"
55 #include "serverid.h"
56 #include "messages.h"
57 #include "util_tdb.h"
58 #include "../librpc/gen_ndr/ndr_open_files.h"
59 #include "source3/lib/dbwrap/dbwrap_watch.h"
60 #include "locking/leases_db.h"
61 #include "../lib/util/memcache.h"
62 #include "lib/util/tevent_ntstatus.h"
63 #include "g_lock.h"
64 #include "smbd/fd_handle.h"
65 #include "lib/global_contexts.h"
66
67 #undef DBGC_CLASS
68 #define DBGC_CLASS DBGC_LOCKING
69
70 #define DBG_GET_SHARE_MODE_LOCK(__status, ...) \
71         DBG_PREFIX( \
72                 NT_STATUS_EQUAL(__status, NT_STATUS_NOT_FOUND) ? \
73                 DBGLVL_DEBUG : DBGLVL_ERR, \
74                 (__VA_ARGS__))
75
76 /* the locking database handle */
77 static struct g_lock_ctx *lock_ctx;
78 static struct g_lock_lock_cb_state *current_share_mode_glck = NULL;
79
80 static bool share_mode_g_lock_within_cb(TDB_DATA key);
81
82 static NTSTATUS share_mode_g_lock_dump(TDB_DATA key,
83                                        void (*fn)(struct server_id exclusive,
84                                                   size_t num_shared,
85                                                   const struct server_id *shared,
86                                                   const uint8_t *data,
87                                                   size_t datalen,
88                                                   void *private_data),
89                                        void *private_data)
90 {
91         if (share_mode_g_lock_within_cb(key)) {
92                 return g_lock_lock_cb_dump(current_share_mode_glck,
93                                            fn, private_data);
94         }
95
96         return g_lock_dump(lock_ctx, key, fn, private_data);
97 }
98
99 static NTSTATUS share_mode_g_lock_writev(TDB_DATA key,
100                                          const TDB_DATA *dbufs,
101                                          size_t num_dbufs)
102 {
103         if (share_mode_g_lock_within_cb(key)) {
104                 return g_lock_lock_cb_writev(current_share_mode_glck,
105                                              dbufs, num_dbufs);
106         }
107
108         return g_lock_writev_data(lock_ctx, key, dbufs, num_dbufs);
109 }
110
111 static bool locking_init_internal(bool read_only)
112 {
113         struct db_context *backend;
114         char *db_path;
115
116         brl_init(read_only);
117
118         if (lock_ctx != NULL) {
119                 return True;
120         }
121
122         db_path = lock_path(talloc_tos(), "locking.tdb");
123         if (db_path == NULL) {
124                 return false;
125         }
126
127         backend = db_open(NULL, db_path,
128                           SMBD_VOLATILE_TDB_HASH_SIZE,
129                           SMBD_VOLATILE_TDB_FLAGS |
130                           TDB_SEQNUM,
131                           read_only?O_RDONLY:O_RDWR|O_CREAT, 0644,
132                           DBWRAP_LOCK_ORDER_NONE,
133                           DBWRAP_FLAG_NONE);
134         TALLOC_FREE(db_path);
135         if (!backend) {
136                 DEBUG(0,("ERROR: Failed to initialise locking database\n"));
137                 return False;
138         }
139
140         lock_ctx = g_lock_ctx_init_backend(
141                 NULL, global_messaging_context(), &backend);
142         if (lock_ctx == NULL) {
143                 TALLOC_FREE(backend);
144                 return false;
145         }
146         g_lock_set_lock_order(lock_ctx, DBWRAP_LOCK_ORDER_1);
147
148         if (!posix_locking_init(read_only)) {
149                 TALLOC_FREE(lock_ctx);
150                 return False;
151         }
152
153         return True;
154 }
155
156 bool locking_init(void)
157 {
158         return locking_init_internal(false);
159 }
160
161 bool locking_init_readonly(void)
162 {
163         return locking_init_internal(true);
164 }
165
166 /*******************************************************************
167  Deinitialize the share_mode management.
168 ******************************************************************/
169
170 bool locking_end(void)
171 {
172         brl_shutdown();
173         TALLOC_FREE(lock_ctx);
174         return true;
175 }
176
177 /*******************************************************************
178  Form a static locking key for a dev/inode pair.
179 ******************************************************************/
180
181 static TDB_DATA locking_key(const struct file_id *id)
182 {
183         return make_tdb_data((const uint8_t *)id, sizeof(*id));
184 }
185
186 /*******************************************************************
187  Share mode cache utility functions that store/delete/retrieve
188  entries from memcache.
189
190  For now share the statcache (global cache) memory space. If
191  a lock record gets orphaned (which shouldn't happen as we're
192  using the same locking_key data as lookup) it will eventually
193  fall out of the cache via the normal LRU trim mechanism. If
194  necessary we can always make this a separate (smaller) cache.
195 ******************************************************************/
196
197 static DATA_BLOB memcache_key(const struct file_id *id)
198 {
199         return data_blob_const((const void *)id, sizeof(*id));
200 }
201
202 static void share_mode_memcache_store(struct share_mode_data *d)
203 {
204         const DATA_BLOB key = memcache_key(&d->id);
205         struct file_id_buf idbuf;
206
207         DBG_DEBUG("stored entry for file %s epoch %"PRIx64" key %s\n",
208                   d->base_name,
209                   d->unique_content_epoch,
210                   file_id_str_buf(d->id, &idbuf));
211
212         /* Ensure everything stored in the cache is pristine. */
213         SMB_ASSERT(!d->modified);
214         SMB_ASSERT(!d->not_stored);
215
216         /*
217          * Ensure the memory going into the cache
218          * doesn't have a destructor so it can be
219          * cleanly evicted by the memcache LRU
220          * mechanism.
221          */
222         talloc_set_destructor(d, NULL);
223
224         /* Cache will own d after this call. */
225         memcache_add_talloc(NULL,
226                         SHARE_MODE_LOCK_CACHE,
227                         key,
228                         &d);
229 }
230
231 /*
232  * NB. We use ndr_pull_hyper on a stack-created
233  * struct ndr_pull with no talloc allowed, as we
234  * need this to be really fast as an ndr-peek into
235  * the first 10 bytes of the blob.
236  */
237
238 static enum ndr_err_code get_share_mode_blob_header(
239         const uint8_t *buf, size_t buflen, uint64_t *pepoch, uint16_t *pflags)
240 {
241         struct ndr_pull ndr = {
242                 .data = discard_const_p(uint8_t, buf),
243                 .data_size = buflen,
244         };
245         NDR_CHECK(ndr_pull_hyper(&ndr, NDR_SCALARS, pepoch));
246         NDR_CHECK(ndr_pull_uint16(&ndr, NDR_SCALARS, pflags));
247         return NDR_ERR_SUCCESS;
248 }
249
250 static int share_mode_data_nofree_destructor(struct share_mode_data *d)
251 {
252         return -1;
253 }
254
255 static struct share_mode_data *share_mode_memcache_fetch(
256         TALLOC_CTX *mem_ctx,
257         struct file_id id,
258         const uint8_t *buf,
259         size_t buflen)
260 {
261         const DATA_BLOB key = memcache_key(&id);
262         enum ndr_err_code ndr_err;
263         struct share_mode_data *d;
264         uint64_t unique_content_epoch;
265         uint16_t flags;
266         void *ptr;
267         struct file_id_buf idbuf;
268
269         ptr = memcache_lookup_talloc(NULL,
270                         SHARE_MODE_LOCK_CACHE,
271                         key);
272         if (ptr == NULL) {
273                 DBG_DEBUG("failed to find entry for key %s\n",
274                           file_id_str_buf(id, &idbuf));
275                 return NULL;
276         }
277         /* sequence number key is at start of blob. */
278         ndr_err = get_share_mode_blob_header(
279                 buf, buflen, &unique_content_epoch, &flags);
280         if (ndr_err != NDR_ERR_SUCCESS) {
281                 /* Bad blob. Remove entry. */
282                 DBG_DEBUG("bad blob %u key %s\n",
283                           (unsigned int)ndr_err,
284                           file_id_str_buf(id, &idbuf));
285                 memcache_delete(NULL,
286                         SHARE_MODE_LOCK_CACHE,
287                         key);
288                 return NULL;
289         }
290
291         d = (struct share_mode_data *)ptr;
292         if (d->unique_content_epoch != unique_content_epoch) {
293                 DBG_DEBUG("epoch changed (cached %"PRIx64") (new %"PRIx64") "
294                           "for key %s\n",
295                           d->unique_content_epoch,
296                           unique_content_epoch,
297                           file_id_str_buf(id, &idbuf));
298                 /* Cache out of date. Remove entry. */
299                 memcache_delete(NULL,
300                         SHARE_MODE_LOCK_CACHE,
301                         key);
302                 return NULL;
303         }
304
305         /* Move onto mem_ctx. */
306         d = talloc_move(mem_ctx, &ptr);
307
308         /*
309          * Now we own d, prevent the cache from freeing it
310          * when we delete the entry.
311          */
312         talloc_set_destructor(d, share_mode_data_nofree_destructor);
313
314         /* Remove from the cache. We own it now. */
315         memcache_delete(NULL,
316                         SHARE_MODE_LOCK_CACHE,
317                         key);
318
319         /* And reset the destructor to none. */
320         talloc_set_destructor(d, NULL);
321
322         DBG_DEBUG("fetched entry for file %s epoch %"PRIx64" key %s\n",
323                   d->base_name,
324                   d->unique_content_epoch,
325                   file_id_str_buf(id, &idbuf));
326
327         return d;
328 }
329
330 /*
331  * 132 is the sizeof an ndr-encoded struct share_mode_entry_buf.
332  * Reading/writing entries will immediately error out if this
333  * size differs (push/pull is done without allocs).
334  */
335
336 struct share_mode_entry_buf {
337         uint8_t buf[132];
338 };
339 #define SHARE_MODE_ENTRY_SIZE (sizeof(struct share_mode_entry_buf))
340
341 static bool share_mode_entry_put(
342         const struct share_mode_entry *e,
343         struct share_mode_entry_buf *dst)
344 {
345         DATA_BLOB blob = { .data = dst->buf, .length = sizeof(dst->buf) };
346         enum ndr_err_code ndr_err;
347
348         if (DEBUGLEVEL>=10) {
349                 DBG_DEBUG("share_mode_entry:\n");
350                 NDR_PRINT_DEBUG(share_mode_entry, discard_const_p(void, e));
351         }
352
353         ndr_err = ndr_push_struct_into_fixed_blob(
354                 &blob,
355                 e,
356                 (ndr_push_flags_fn_t)ndr_push_share_mode_entry);
357         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
358                 DBG_WARNING("ndr_push_share_mode_entry failed: %s\n",
359                             ndr_errstr(ndr_err));
360                 return false;
361         }
362
363         return true;
364 }
365
366 static bool share_mode_entry_get(
367         const uint8_t ptr[SHARE_MODE_ENTRY_SIZE], struct share_mode_entry *e)
368 {
369         enum ndr_err_code ndr_err = NDR_ERR_SUCCESS;
370         DATA_BLOB blob = {
371                 .data = discard_const_p(uint8_t, ptr),
372                 .length = SHARE_MODE_ENTRY_SIZE,
373         };
374
375         ndr_err = ndr_pull_struct_blob_all_noalloc(
376                 &blob, e, (ndr_pull_flags_fn_t)ndr_pull_share_mode_entry);
377         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
378                 DBG_WARNING("ndr_pull_share_mode_entry failed\n");
379                 return false;
380         }
381         return true;
382 }
383
384 /*
385  * locking.tdb records consist of
386  *
387  * uint32_t share_mode_data_len
388  * uint8_t [share_mode_data]       This is struct share_mode_data in NDR
389  *
390  * 0 [SHARE_MODE_ENTRY_SIZE]       Sorted array of share modes,
391  * 1 [SHARE_MODE_ENTRY_SIZE]       filling up the rest of the data in the
392  * 2 [SHARE_MODE_ENTRY_SIZE]       g_lock.c maintained record in locking.tdb
393  */
394
395 struct locking_tdb_data {
396         const uint8_t *share_mode_data_buf;
397         size_t share_mode_data_len;
398         const uint8_t *share_entries;
399         size_t num_share_entries;
400 };
401
402 static bool locking_tdb_data_get(
403         struct locking_tdb_data *data, const uint8_t *buf, size_t buflen)
404 {
405         uint32_t share_mode_data_len, share_entries_len;
406
407         if (buflen == 0) {
408                 *data = (struct locking_tdb_data) { 0 };
409                 return true;
410         }
411         if (buflen < sizeof(uint32_t)) {
412                 return false;
413         }
414
415         share_mode_data_len = PULL_LE_U32(buf, 0);
416
417         buf += sizeof(uint32_t);
418         buflen -= sizeof(uint32_t);
419
420         if (buflen < share_mode_data_len) {
421                 return false;
422         }
423
424         share_entries_len = buflen - share_mode_data_len;
425
426         if ((share_entries_len % SHARE_MODE_ENTRY_SIZE) != 0) {
427                 return false;
428         }
429
430         *data = (struct locking_tdb_data) {
431                 .share_mode_data_buf = buf,
432                 .share_mode_data_len = share_mode_data_len,
433                 .share_entries = buf + share_mode_data_len,
434                 .num_share_entries = share_entries_len / SHARE_MODE_ENTRY_SIZE,
435         };
436
437         return true;
438 }
439
440 struct locking_tdb_data_fetch_state {
441         TALLOC_CTX *mem_ctx;
442         uint8_t *data;
443         size_t datalen;
444 };
445
446 static void locking_tdb_data_fetch_fn(
447         struct server_id exclusive,
448         size_t num_shared,
449         const struct server_id *shared,
450         const uint8_t *data,
451         size_t datalen,
452         void *private_data)
453 {
454         struct locking_tdb_data_fetch_state *state = private_data;
455         state->datalen = datalen;
456         state->data = talloc_memdup(state->mem_ctx, data, datalen);
457 }
458
459 static NTSTATUS locking_tdb_data_fetch(
460         TDB_DATA key, TALLOC_CTX *mem_ctx, struct locking_tdb_data **ltdb)
461 {
462         struct locking_tdb_data_fetch_state state = { 0 };
463         struct locking_tdb_data *result = NULL;
464         NTSTATUS status;
465         bool ok;
466
467         result = talloc_zero(mem_ctx, struct locking_tdb_data);
468         if (result == NULL) {
469                 return NT_STATUS_NO_MEMORY;
470         }
471         state.mem_ctx = result;
472
473         status = share_mode_g_lock_dump(key, locking_tdb_data_fetch_fn, &state);
474         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
475                 /*
476                  * Just return an empty record
477                  */
478                 goto done;
479         }
480         if (!NT_STATUS_IS_OK(status)) {
481                 DBG_ERR("share_mode_g_lock_dump failed: %s\n",
482                         nt_errstr(status));
483                 return status;
484         }
485         if (state.datalen == 0) {
486                 goto done;
487         }
488
489         ok = locking_tdb_data_get(result, state.data, state.datalen);
490         if (!ok) {
491                 DBG_ERR("locking_tdb_data_get failed for %zu bytes\n",
492                           state.datalen);
493                 TALLOC_FREE(result);
494                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
495         }
496
497 done:
498         *ltdb = result;
499         return NT_STATUS_OK;
500 }
501
502 static NTSTATUS locking_tdb_data_store(
503         TDB_DATA key,
504         const struct locking_tdb_data *ltdb,
505         const TDB_DATA *share_mode_dbufs,
506         size_t num_share_mode_dbufs)
507 {
508         uint8_t share_mode_data_len_buf[4];
509         TDB_DATA dbufs[num_share_mode_dbufs+3];
510         NTSTATUS status;
511
512         if ((ltdb->share_mode_data_len == 0) &&
513             (ltdb->num_share_entries == 0) &&
514             (num_share_mode_dbufs == 0)) {
515                 /*
516                  * Nothing to write
517                  */
518                 status = share_mode_g_lock_writev(key, NULL, 0);
519                 if (!NT_STATUS_IS_OK(status)) {
520                         DBG_ERR("share_mode_g_lock_writev(NULL) failed: %s\n",
521                                 nt_errstr(status));
522                 }
523                 return status;
524         }
525
526         PUSH_LE_U32(share_mode_data_len_buf, 0, ltdb->share_mode_data_len);
527
528         dbufs[0] = (TDB_DATA) {
529                 .dptr = share_mode_data_len_buf,
530                 .dsize = sizeof(share_mode_data_len_buf),
531         };
532         dbufs[1] = (TDB_DATA) {
533                 .dptr = discard_const_p(uint8_t, ltdb->share_mode_data_buf),
534                 .dsize = ltdb->share_mode_data_len,
535         };
536
537         if (ltdb->num_share_entries > SIZE_MAX/SHARE_MODE_ENTRY_SIZE) {
538                 /* overflow */
539                 return NT_STATUS_BUFFER_OVERFLOW;
540         }
541         dbufs[2] = (TDB_DATA) {
542                 .dptr = discard_const_p(uint8_t, ltdb->share_entries),
543                 .dsize = ltdb->num_share_entries * SHARE_MODE_ENTRY_SIZE,
544         };
545
546         if (num_share_mode_dbufs != 0) {
547                 memcpy(&dbufs[3],
548                        share_mode_dbufs,
549                        num_share_mode_dbufs * sizeof(TDB_DATA));
550         }
551
552         status = share_mode_g_lock_writev(key, dbufs, ARRAY_SIZE(dbufs));
553         if (!NT_STATUS_IS_OK(status)) {
554                 DBG_ERR("share_mode_g_lock_writev() failed: %s\n",
555                         nt_errstr(status));
556         }
557         return status;
558 }
559
560 /*******************************************************************
561  Get all share mode entries for a dev/inode pair.
562 ********************************************************************/
563
564 static struct share_mode_data *parse_share_modes(
565         TALLOC_CTX *mem_ctx,
566         struct file_id id,
567         const uint8_t *buf,
568         size_t buflen)
569 {
570         struct share_mode_data *d;
571         enum ndr_err_code ndr_err;
572         DATA_BLOB blob;
573
574         /* See if we already have a cached copy of this key. */
575         d = share_mode_memcache_fetch(mem_ctx, id, buf, buflen);
576         if (d != NULL) {
577                 return d;
578         }
579
580         d = talloc(mem_ctx, struct share_mode_data);
581         if (d == NULL) {
582                 DEBUG(0, ("talloc failed\n"));
583                 goto fail;
584         }
585
586         blob = (DATA_BLOB) {
587                 .data = discard_const_p(uint8_t, buf),
588                 .length = buflen,
589         };
590         ndr_err = ndr_pull_struct_blob_all(
591                 &blob, d, d, (ndr_pull_flags_fn_t)ndr_pull_share_mode_data);
592         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
593                 DBG_WARNING("ndr_pull_share_mode_data failed: %s\n",
594                             ndr_errstr(ndr_err));
595                 goto fail;
596         }
597
598         if (DEBUGLEVEL >= 10) {
599                 DEBUG(10, ("parse_share_modes:\n"));
600                 NDR_PRINT_DEBUG(share_mode_data, d);
601         }
602
603         return d;
604 fail:
605         TALLOC_FREE(d);
606         return NULL;
607 }
608
609 static NTSTATUS share_mode_data_ltdb_store(struct share_mode_data *d,
610                                            TDB_DATA key,
611                                            struct locking_tdb_data *ltdb,
612                                            const TDB_DATA *share_mode_dbufs,
613                                            size_t num_share_mode_dbufs)
614 {
615         DATA_BLOB blob = { 0 };
616         NTSTATUS status;
617
618         if (!d->modified) {
619                 DBG_DEBUG("share_mode_data not modified\n");
620                 goto store;
621         }
622
623         d->unique_content_epoch = generate_unique_u64(d->unique_content_epoch);
624
625         if (DEBUGLEVEL >= 10) {
626                 DBG_DEBUG("\n");
627                 NDR_PRINT_DEBUG(share_mode_data, d);
628         }
629
630         if (ltdb->num_share_entries != 0 || num_share_mode_dbufs != 0) {
631                 enum ndr_err_code ndr_err;
632
633                 ndr_err = ndr_push_struct_blob(
634                         &blob,
635                         ltdb,
636                         d,
637                         (ndr_push_flags_fn_t)ndr_push_share_mode_data);
638                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
639                         DBG_ERR("ndr_push_share_mode_data failed: %s\n",
640                                   ndr_errstr(ndr_err));
641                         return ndr_map_error2ntstatus(ndr_err);
642                 }
643         }
644
645         ltdb->share_mode_data_buf = blob.data;
646         ltdb->share_mode_data_len = blob.length;
647
648 store:
649         status = locking_tdb_data_store(key,
650                                         ltdb,
651                                         share_mode_dbufs,
652                                         num_share_mode_dbufs);
653         if (!NT_STATUS_IS_OK(status)) {
654                 DBG_ERR("locking_tdb_data_store failed: %s\n",
655                         nt_errstr(status));
656                 return status;
657         }
658
659         d->modified = false;
660         d->not_stored = (ltdb->share_mode_data_len == 0);
661
662         return NT_STATUS_OK;
663 }
664
665 /*******************************************************************
666  If modified, store the share_mode_data back into the database.
667 ********************************************************************/
668
669 static NTSTATUS share_mode_data_store(struct share_mode_data *d)
670 {
671         TDB_DATA key = locking_key(&d->id);
672         struct locking_tdb_data *ltdb = NULL;
673         NTSTATUS status;
674
675         if (!d->modified) {
676                 DBG_DEBUG("not modified\n");
677                 return NT_STATUS_OK;
678         }
679
680         if (DEBUGLEVEL >= 10) {
681                 DBG_DEBUG("\n");
682                 NDR_PRINT_DEBUG(share_mode_data, d);
683         }
684
685         status = locking_tdb_data_fetch(key, d, &ltdb);
686         if (!NT_STATUS_IS_OK(status)) {
687                 DBG_ERR("locking_tdb_data_fetch failed: %s\n",
688                         nt_errstr(status));
689                 return status;
690         }
691
692         status = share_mode_data_ltdb_store(d, key, ltdb, NULL, 0);
693         TALLOC_FREE(ltdb);
694         if (!NT_STATUS_IS_OK(status)) {
695                 DBG_ERR("share_mode_data_ltdb_store failed: %s\n",
696                         nt_errstr(status));
697                 return status;
698         }
699
700         return NT_STATUS_OK;
701 }
702
703 /*******************************************************************
704  Allocate a new share_mode_data struct, mark it unmodified.
705  fresh is set to note that currently there is no database entry.
706 ********************************************************************/
707
708 static struct share_mode_data *fresh_share_mode_lock(
709         TALLOC_CTX *mem_ctx, const char *servicepath,
710         const struct smb_filename *smb_fname,
711         const struct timespec *old_write_time)
712 {
713         struct share_mode_data *d;
714
715         if ((servicepath == NULL) || (smb_fname == NULL) ||
716             (old_write_time == NULL)) {
717                 return NULL;
718         }
719
720         d = talloc_zero(mem_ctx, struct share_mode_data);
721         if (d == NULL) {
722                 goto fail;
723         }
724         d->unique_content_epoch = generate_unique_u64(0);
725
726         d->base_name = talloc_strdup(d, smb_fname->base_name);
727         if (d->base_name == NULL) {
728                 goto fail;
729         }
730         if (smb_fname->stream_name != NULL) {
731                 d->stream_name = talloc_strdup(d, smb_fname->stream_name);
732                 if (d->stream_name == NULL) {
733                         goto fail;
734                 }
735         }
736         d->servicepath = talloc_strdup(d, servicepath);
737         if (d->servicepath == NULL) {
738                 goto fail;
739         }
740         d->old_write_time = full_timespec_to_nt_time(old_write_time);
741         d->flags = SHARE_MODE_SHARE_DELETE |
742                 SHARE_MODE_SHARE_WRITE |
743                 SHARE_MODE_SHARE_READ;
744         d->modified = false;
745         d->not_stored = true;
746         return d;
747 fail:
748         DEBUG(0, ("talloc failed\n"));
749         TALLOC_FREE(d);
750         return NULL;
751 }
752
753 /*
754  * Key that's locked with g_lock
755  */
756 static struct file_id share_mode_lock_key_id = {};
757 static TDB_DATA share_mode_lock_key = {
758         .dptr = (uint8_t *)&share_mode_lock_key_id,
759         .dsize = sizeof(share_mode_lock_key_id),
760 };
761 static size_t share_mode_lock_key_refcount = 0;
762
763 static bool share_mode_g_lock_within_cb(TDB_DATA key)
764 {
765         int cmp;
766
767         if (current_share_mode_glck == NULL) {
768                 return false;
769         }
770
771         cmp = tdb_data_cmp(share_mode_lock_key, key);
772         if (cmp != 0) {
773                 struct file_id_buf existing;
774
775                 DBG_ERR("Can not lock two share modes "
776                         "simultaneously: existing %s requested %s\n",
777                         file_id_str_buf(share_mode_lock_key_id, &existing),
778                         tdb_data_dbg(key));
779                 smb_panic(__location__);
780                 return false;
781         }
782
783         return true;
784 }
785
786 /*
787  * We can only ever have one share mode locked. Use a static
788  * share_mode_data pointer that is shared by multiple nested
789  * share_mode_lock structures, explicitly refcounted.
790  */
791 static struct share_mode_data *static_share_mode_data = NULL;
792
793 /*******************************************************************
794  Either fetch a share mode from the database, or allocate a fresh
795  one if the record doesn't exist.
796 ********************************************************************/
797
798 struct get_static_share_mode_data_state {
799         TALLOC_CTX *mem_ctx;
800         struct file_id id;
801         const char *servicepath;
802         const struct smb_filename *smb_fname;
803         const struct timespec *old_write_time;
804         NTSTATUS status;
805 };
806
807 static void get_static_share_mode_data_fn(
808         struct server_id exclusive,
809         size_t num_shared,
810         const struct server_id *shared,
811         const uint8_t *data,
812         size_t datalen,
813         void *private_data)
814 {
815         struct get_static_share_mode_data_state *state = private_data;
816         struct share_mode_data *d = NULL;
817         struct locking_tdb_data ltdb = { 0 };
818
819         if (datalen != 0) {
820                 bool ok;
821
822                 ok = locking_tdb_data_get(&ltdb, data, datalen);
823                 if (!ok) {
824                         DBG_ERR("locking_tdb_data_get failed\n");
825                         state->status = NT_STATUS_INTERNAL_DB_CORRUPTION;
826                         return;
827                 }
828         }
829
830         if (ltdb.share_mode_data_len == 0) {
831                 if (state->smb_fname == NULL) {
832                         state->status = NT_STATUS_NOT_FOUND;
833                         return;
834                 }
835                 d = fresh_share_mode_lock(
836                         state->mem_ctx,
837                         state->servicepath,
838                         state->smb_fname,
839                         state->old_write_time);
840                 if (d == NULL) {
841                         state->status = NT_STATUS_NO_MEMORY;
842                         return;
843                 }
844         } else {
845                 d = parse_share_modes(
846                         lock_ctx,
847                         state->id,
848                         ltdb.share_mode_data_buf,
849                         ltdb.share_mode_data_len);
850                 if (d == NULL) {
851                         state->status = NT_STATUS_INTERNAL_DB_CORRUPTION;
852                         return;
853                 }
854         }
855
856         d->id = state->id;
857         static_share_mode_data = d;
858 }
859
860 static NTSTATUS get_static_share_mode_data(
861         struct file_id id,
862         const char *servicepath,
863         const struct smb_filename *smb_fname,
864         const struct timespec *old_write_time)
865 {
866         struct get_static_share_mode_data_state state = {
867                 .mem_ctx = lock_ctx,
868                 .id = id,
869                 .servicepath = servicepath,
870                 .smb_fname = smb_fname,
871                 .old_write_time = old_write_time,
872         };
873         NTSTATUS status;
874
875         SMB_ASSERT(static_share_mode_data == NULL);
876
877         status = share_mode_g_lock_dump(
878                 share_mode_lock_key,
879                 get_static_share_mode_data_fn,
880                 &state);
881         if (!NT_STATUS_IS_OK(status)) {
882                 DBG_GET_SHARE_MODE_LOCK(status,
883                         "share_mode_g_lock_dump failed: %s\n",
884                         nt_errstr(status));
885                 return status;
886         }
887         if (!NT_STATUS_IS_OK(state.status)) {
888                 DBG_GET_SHARE_MODE_LOCK(state.status,
889                         "get_static_share_mode_data_fn failed: %s\n",
890                         nt_errstr(state.status));
891                 return state.status;
892         }
893
894         return NT_STATUS_OK;
895 }
896
897 struct file_id share_mode_lock_file_id(const struct share_mode_lock *lck)
898 {
899         return lck->id;
900 }
901
902 NTSTATUS share_mode_lock_access_private_data(struct share_mode_lock *lck,
903                                              struct share_mode_data **data)
904 {
905         /*
906          * For now we always have lck->cached_data,
907          * but we may change that in future.
908          */
909         SMB_ASSERT(lck->cached_data != NULL);
910         *data = lck->cached_data;
911         return NT_STATUS_OK;
912 }
913
914 /*******************************************************************
915  Get a share_mode_lock, Reference counted to allow nested calls.
916 ********************************************************************/
917
918 static int share_mode_lock_destructor(struct share_mode_lock *lck);
919
920 static bool share_mode_lock_skip_g_lock;
921
922 static NTSTATUS get_share_mode_lock_internal(
923         struct file_id id,
924         const char *servicepath,
925         const struct smb_filename *smb_fname,
926         const struct timespec *old_write_time,
927         struct share_mode_lock *lck)
928 {
929         NTSTATUS status;
930
931         *lck = (struct share_mode_lock) {
932                 .id = id,
933         };
934
935         if (share_mode_lock_key_refcount == 0) {
936                 if (!share_mode_lock_skip_g_lock) {
937                         TDB_DATA key = locking_key(&id);
938
939                         status = g_lock_lock(
940                                 lock_ctx,
941                                 key,
942                                 G_LOCK_WRITE,
943                                 (struct timeval) { .tv_sec = 3600 },
944                                 NULL, NULL);
945                         if (!NT_STATUS_IS_OK(status)) {
946                                 DBG_DEBUG("g_lock_lock failed: %s\n",
947                                           nt_errstr(status));
948                                 return status;
949                         }
950                 }
951                 share_mode_lock_key_id = id;
952         }
953
954         if (!file_id_equal(&share_mode_lock_key_id, &id)) {
955                 struct file_id_buf existing;
956                 struct file_id_buf requested;
957
958                 DBG_ERR("Can not lock two share modes "
959                         "simultaneously: existing %s requested %s\n",
960                         file_id_str_buf(share_mode_lock_key_id, &existing),
961                         file_id_str_buf(id, &requested));
962                 smb_panic(__location__);
963                 goto fail;
964         }
965
966         SMB_ASSERT(share_mode_lock_key_refcount < SIZE_MAX);
967         share_mode_lock_key_refcount += 1;
968
969         if (static_share_mode_data != NULL) {
970                 goto done;
971         }
972
973         status = get_static_share_mode_data(
974                 id,
975                 servicepath,
976                 smb_fname,
977                 old_write_time);
978         if (!NT_STATUS_IS_OK(status)) {
979                 DBG_DEBUG("get_static_share_mode_data failed: %s\n",
980                           nt_errstr(status));
981                 share_mode_lock_key_refcount -= 1;
982                 goto fail;
983         }
984 done:
985         lck->cached_data = static_share_mode_data;
986
987         if (CHECK_DEBUGLVL(DBGLVL_DEBUG)) {
988                 struct file_id_buf returned;
989
990                 DBG_DEBUG("Returning %s (data_cached=%u key_refcount=%zu)\n",
991                           file_id_str_buf(id, &returned),
992                           static_share_mode_data != NULL,
993                           share_mode_lock_key_refcount);
994         }
995
996         return NT_STATUS_OK;
997 fail:
998         if (share_mode_lock_key_refcount == 0) {
999                 if (!share_mode_lock_skip_g_lock) {
1000                         NTSTATUS ulstatus = g_lock_unlock(lock_ctx, share_mode_lock_key);
1001                         if (!NT_STATUS_IS_OK(ulstatus)) {
1002                                 DBG_ERR("g_lock_unlock failed: %s\n",
1003                                         nt_errstr(ulstatus));
1004                         }
1005                 }
1006         }
1007         return status;
1008 }
1009
1010 static NTSTATUS put_share_mode_lock_internal(struct share_mode_lock *lck)
1011 {
1012         NTSTATUS status;
1013
1014         SMB_ASSERT(share_mode_lock_key_refcount > 0);
1015         share_mode_lock_key_refcount -= 1;
1016
1017         if (share_mode_lock_key_refcount > 0) {
1018                 return NT_STATUS_OK;
1019         }
1020
1021         status = share_mode_data_store(static_share_mode_data);
1022         if (!NT_STATUS_IS_OK(status)) {
1023                 DBG_ERR("share_mode_data_store failed: %s\n",
1024                         nt_errstr(status));
1025                 return status;
1026         }
1027
1028         if (!share_mode_lock_skip_g_lock) {
1029                 status = g_lock_unlock(lock_ctx, share_mode_lock_key);
1030                 if (!NT_STATUS_IS_OK(status)) {
1031                         DBG_ERR("g_lock_unlock failed: %s\n",
1032                                 nt_errstr(status));
1033                         return status;
1034                 }
1035         }
1036
1037         if (!static_share_mode_data->not_stored) {
1038                 /*
1039                  * This is worth keeping. Without share modes,
1040                  * share_mode_data_store above has left nothing in the
1041                  * database.
1042                  */
1043                 share_mode_memcache_store(static_share_mode_data);
1044                 static_share_mode_data = NULL;
1045         }
1046
1047         TALLOC_FREE(static_share_mode_data);
1048         return NT_STATUS_OK;
1049 }
1050
1051 static int share_mode_lock_destructor(struct share_mode_lock *lck)
1052 {
1053         NTSTATUS status;
1054
1055         status = put_share_mode_lock_internal(lck);
1056         if (!NT_STATUS_IS_OK(status)) {
1057                 DBG_ERR("put_share_mode_lock_internal failed: %s\n",
1058                         nt_errstr(status));
1059                 smb_panic("put_share_mode_lock_internal failed\n");
1060         }
1061
1062         return 0;
1063 }
1064
1065 /*******************************************************************
1066  Fetch a share mode where we know one MUST exist. This call reference
1067  counts it internally to allow for nested lock fetches.
1068 ********************************************************************/
1069
1070 struct share_mode_lock *get_existing_share_mode_lock(TALLOC_CTX *mem_ctx,
1071                                                      const struct file_id id)
1072 {
1073         struct share_mode_lock *lck = NULL;
1074         NTSTATUS status;
1075
1076         lck = talloc(mem_ctx, struct share_mode_lock);
1077         if (lck == NULL) {
1078                 return NULL;
1079         }
1080
1081         status = get_share_mode_lock_internal(id,
1082                                               NULL, /* servicepath */
1083                                               NULL, /* smb_fname */
1084                                               NULL, /* old_write_time */
1085                                               lck);
1086         if (!NT_STATUS_IS_OK(status)) {
1087                 DBG_GET_SHARE_MODE_LOCK(status,
1088                         "get_share_mode_lock_internal() failed - %s\n",
1089                         nt_errstr(status));
1090                 TALLOC_FREE(lck);
1091                 return NULL;
1092         }
1093
1094         talloc_set_destructor(lck, share_mode_lock_destructor);
1095         return lck;
1096 }
1097
1098 static void share_mode_wakeup_waiters_fn(
1099         struct share_mode_lock *lck,
1100         void *private_data)
1101 {
1102         if (share_mode_g_lock_within_cb(share_mode_lock_key)) {
1103                 g_lock_lock_cb_wake_watchers(current_share_mode_glck);
1104                 return;
1105         }
1106
1107         g_lock_wake_watchers(lock_ctx, share_mode_lock_key);
1108 }
1109
1110 NTSTATUS share_mode_wakeup_waiters(struct file_id id)
1111 {
1112         return share_mode_do_locked_vfs_denied(id,
1113                                                share_mode_wakeup_waiters_fn,
1114                                                NULL);
1115 }
1116
1117 struct fsp_update_share_mode_flags_state {
1118         struct files_struct *fsp;
1119         enum ndr_err_code ndr_err;
1120         uint64_t share_mode_epoch;
1121         uint16_t share_mode_flags;
1122 };
1123
1124 static void fsp_update_share_mode_flags_fn(
1125         struct server_id exclusive,
1126         size_t num_shared,
1127         const struct server_id *shared,
1128         const uint8_t *data,
1129         size_t datalen,
1130         void *private_data)
1131 {
1132         struct fsp_update_share_mode_flags_state *state = private_data;
1133         struct locking_tdb_data ltdb = { 0 };
1134
1135         if (datalen != 0) {
1136                 bool ok = locking_tdb_data_get(&ltdb, data, datalen);
1137                 if (!ok) {
1138                         DBG_DEBUG("locking_tdb_data_get failed\n");
1139                         return;
1140                 }
1141         }
1142
1143         if (ltdb.share_mode_data_len == 0) {
1144                 /* Likely a ctdb tombstone record, ignore it */
1145                 return;
1146         }
1147
1148         if (exclusive.pid != 0) {
1149                 struct server_id self =
1150                         messaging_server_id(state->fsp->conn->sconn->msg_ctx);
1151                 bool is_self = server_id_equal(&self, &exclusive);
1152
1153                 if (!is_self) {
1154                         /*
1155                          * If someone else is holding an exclusive
1156                          * lock, pretend there's a read lease
1157                          */
1158                         state->share_mode_flags = SHARE_MODE_LEASE_READ;
1159                         return;
1160                 }
1161         }
1162
1163         state->ndr_err = get_share_mode_blob_header(ltdb.share_mode_data_buf,
1164                                                     ltdb.share_mode_data_len,
1165                                                     &state->share_mode_epoch,
1166                                                     &state->share_mode_flags);
1167 }
1168
1169 static NTSTATUS fsp_update_share_mode_flags(struct files_struct *fsp)
1170 {
1171         struct fsp_update_share_mode_flags_state state = { .fsp = fsp, };
1172         int seqnum = g_lock_seqnum(lock_ctx);
1173         TDB_DATA key = {0};
1174         NTSTATUS status;
1175
1176         if (seqnum == fsp->share_mode_flags_seqnum) {
1177                 return NT_STATUS_OK;
1178         }
1179
1180         key = locking_key(&fsp->file_id);
1181         status = share_mode_g_lock_dump(key,
1182                              fsp_update_share_mode_flags_fn,
1183                              &state);
1184         if (!NT_STATUS_IS_OK(status)) {
1185                 /* no DBG_GET_SHARE_MODE_LOCK here! */
1186                 DBG_ERR("share_mode_g_lock_dump returned %s\n",
1187                         nt_errstr(status));
1188                 return status;
1189         }
1190
1191         if (!NDR_ERR_CODE_IS_SUCCESS(state.ndr_err)) {
1192                 DBG_ERR("get_share_mode_blob_header returned %s\n",
1193                         ndr_errstr(state.ndr_err));
1194                 return ndr_map_error2ntstatus(state.ndr_err);
1195         }
1196
1197         fsp->share_mode_flags_seqnum = seqnum;
1198         fsp->share_mode_flags = state.share_mode_flags;
1199
1200         return NT_STATUS_OK;
1201 }
1202
1203 bool file_has_read_lease(struct files_struct *fsp)
1204 {
1205         NTSTATUS status;
1206
1207         status = fsp_update_share_mode_flags(fsp);
1208         if (!NT_STATUS_IS_OK(status)) {
1209                 /* Safe default for leases */
1210                 return true;
1211         }
1212
1213         return (fsp->share_mode_flags & SHARE_MODE_LEASE_READ) != 0;
1214 }
1215
1216 #define share_mode_lock_assert_private_data(__lck) \
1217         _share_mode_lock_assert_private_data(__lck, __func__, __location__)
1218 static struct share_mode_data *_share_mode_lock_assert_private_data(
1219                                         struct share_mode_lock *lck,
1220                                         const char *caller_function,
1221                                         const char *caller_location)
1222 {
1223         struct share_mode_data *d = NULL;
1224         NTSTATUS status;
1225
1226         status = share_mode_lock_access_private_data(lck, &d);
1227         if (!NT_STATUS_IS_OK(status)) {
1228                 struct file_id id = share_mode_lock_file_id(lck);
1229                 struct file_id_buf id_buf;
1230                 /* Any error recovery possible here ? */
1231                 D_ERR("%s:%s(): share_mode_lock_access_private_data() "
1232                       "failed for id=%s - %s\n",
1233                       caller_location, caller_function,
1234                       file_id_str_buf(id, &id_buf),
1235                       nt_errstr(status));
1236                 smb_panic(caller_location);
1237                 return NULL;
1238         }
1239
1240         return d;
1241 }
1242
1243 NTTIME share_mode_changed_write_time(struct share_mode_lock *lck)
1244 {
1245         struct share_mode_data *d = share_mode_lock_assert_private_data(lck);
1246         return d->changed_write_time;
1247 }
1248
1249 void share_mode_set_changed_write_time(struct share_mode_lock *lck, struct timespec write_time)
1250 {
1251         struct file_id fileid = share_mode_lock_file_id(lck);
1252         struct share_mode_data *d = share_mode_lock_assert_private_data(lck);
1253         struct file_id_buf ftmp;
1254         struct timeval_buf tbuf;
1255         NTTIME nt = full_timespec_to_nt_time(&write_time);
1256
1257         DBG_INFO("%s id=%s\n",
1258                  timespec_string_buf(&write_time, true, &tbuf),
1259                  file_id_str_buf(fileid, &ftmp));
1260
1261         if (d->changed_write_time != nt) {
1262                 d->modified = true;
1263                 d->changed_write_time = nt;
1264         }
1265 }
1266
1267 void share_mode_set_old_write_time(struct share_mode_lock *lck, struct timespec write_time)
1268 {
1269         struct file_id fileid = share_mode_lock_file_id(lck);
1270         struct share_mode_data *d = share_mode_lock_assert_private_data(lck);
1271         struct file_id_buf ftmp;
1272         struct timeval_buf tbuf;
1273         NTTIME nt = full_timespec_to_nt_time(&write_time);
1274
1275         DBG_INFO("%s id=%s\n",
1276                  timespec_string_buf(&write_time, true, &tbuf),
1277                  file_id_str_buf(fileid, &ftmp));
1278
1279         if (d->changed_write_time != nt) {
1280                 d->modified = true;
1281                 d->old_write_time = nt;
1282         }
1283 }
1284
1285 const char *share_mode_servicepath(struct share_mode_lock *lck)
1286 {
1287         struct share_mode_data *d = share_mode_lock_assert_private_data(lck);
1288         return d->servicepath;
1289 }
1290
1291 char *share_mode_filename(TALLOC_CTX *mem_ctx, struct share_mode_lock *lck)
1292 {
1293         struct share_mode_data *d = share_mode_lock_assert_private_data(lck);
1294         bool has_stream = (d->stream_name != NULL);
1295         char *fname = NULL;
1296
1297         fname = talloc_asprintf(
1298                 mem_ctx,
1299                 "%s%s%s",
1300                 d->base_name,
1301                 has_stream ? ":" : "",
1302                 has_stream ? d->stream_name : "");
1303         return fname;
1304 }
1305
1306 char *share_mode_data_dump(
1307         TALLOC_CTX *mem_ctx, struct share_mode_lock *lck)
1308 {
1309         struct share_mode_data *d = share_mode_lock_assert_private_data(lck);
1310         struct ndr_print *p = talloc(mem_ctx, struct ndr_print);
1311         char *ret = NULL;
1312
1313         if (p == NULL) {
1314                 return NULL;
1315         }
1316
1317         *p = (struct ndr_print) {
1318                 .print = ndr_print_string_helper,
1319                 .depth = 1,
1320                 .private_data = talloc_strdup(mem_ctx, ""),
1321         };
1322
1323         if (p->private_data == NULL) {
1324                 TALLOC_FREE(p);
1325                 return NULL;
1326         }
1327
1328         ndr_print_share_mode_data(p, "SHARE_MODE_DATA", d);
1329
1330         ret = p->private_data;
1331
1332         TALLOC_FREE(p);
1333
1334         return ret;
1335 }
1336
1337 void share_mode_flags_get(
1338         struct share_mode_lock *lck,
1339         uint32_t *access_mask,
1340         uint32_t *share_mode,
1341         uint32_t *lease_type)
1342 {
1343         struct share_mode_data *d = share_mode_lock_assert_private_data(lck);
1344         uint16_t flags = d->flags;
1345
1346         if (access_mask != NULL) {
1347                 *access_mask =
1348                         ((flags & SHARE_MODE_ACCESS_READ) ?
1349                          FILE_READ_DATA : 0) |
1350                         ((flags & SHARE_MODE_ACCESS_WRITE) ?
1351                          FILE_WRITE_DATA : 0) |
1352                         ((flags & SHARE_MODE_ACCESS_DELETE) ?
1353                          DELETE_ACCESS : 0);
1354         }
1355         if (share_mode != NULL) {
1356                 *share_mode =
1357                         ((flags & SHARE_MODE_SHARE_READ) ?
1358                          FILE_SHARE_READ : 0) |
1359                         ((flags & SHARE_MODE_SHARE_WRITE) ?
1360                          FILE_SHARE_WRITE : 0) |
1361                         ((flags & SHARE_MODE_SHARE_DELETE) ?
1362                          FILE_SHARE_DELETE : 0);
1363         }
1364         if (lease_type != NULL) {
1365                 *lease_type =
1366                         ((flags & SHARE_MODE_LEASE_READ) ?
1367                          SMB2_LEASE_READ : 0) |
1368                         ((flags & SHARE_MODE_LEASE_WRITE) ?
1369                          SMB2_LEASE_WRITE : 0) |
1370                         ((flags & SHARE_MODE_LEASE_HANDLE) ?
1371                          SMB2_LEASE_HANDLE : 0);
1372         }
1373 }
1374
1375 void share_mode_flags_set(
1376         struct share_mode_lock *lck,
1377         uint32_t access_mask,
1378         uint32_t share_mode,
1379         uint32_t lease_type,
1380         bool *modified)
1381 {
1382         struct share_mode_data *d = share_mode_lock_assert_private_data(lck);
1383         uint16_t flags = 0;
1384
1385         flags |= (access_mask & (FILE_READ_DATA | FILE_EXECUTE)) ?
1386                 SHARE_MODE_ACCESS_READ : 0;
1387         flags |= (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ?
1388                 SHARE_MODE_ACCESS_WRITE : 0;
1389         flags |= (access_mask & (DELETE_ACCESS)) ?
1390                 SHARE_MODE_ACCESS_DELETE : 0;
1391
1392         flags |= (share_mode & FILE_SHARE_READ) ?
1393                 SHARE_MODE_SHARE_READ : 0;
1394         flags |= (share_mode & FILE_SHARE_WRITE) ?
1395                 SHARE_MODE_SHARE_WRITE : 0;
1396         flags |= (share_mode & FILE_SHARE_DELETE) ?
1397                 SHARE_MODE_SHARE_DELETE : 0;
1398
1399         flags |= (lease_type & SMB2_LEASE_READ) ?
1400                 SHARE_MODE_LEASE_READ : 0;
1401         flags |= (lease_type & SMB2_LEASE_WRITE) ?
1402                 SHARE_MODE_LEASE_WRITE : 0;
1403         flags |= (lease_type & SMB2_LEASE_HANDLE) ?
1404                 SHARE_MODE_LEASE_HANDLE : 0;
1405
1406         if (d->flags == flags) {
1407                 return;
1408         }
1409
1410         if (modified != NULL) {
1411                 *modified = true;
1412         }
1413         d->flags = flags;
1414         d->modified = true;
1415 }
1416
1417 struct share_mode_watch_state {
1418         bool blockerdead;
1419         struct server_id blocker;
1420         bool within_cb;
1421 };
1422
1423 static void share_mode_watch_done(struct tevent_req *subreq);
1424
1425 struct tevent_req *share_mode_watch_send(
1426         TALLOC_CTX *mem_ctx,
1427         struct tevent_context *ev,
1428         struct share_mode_lock *lck,
1429         struct server_id blocker)
1430 {
1431         struct file_id id = share_mode_lock_file_id(lck);
1432         TDB_DATA key = locking_key(&id);
1433         struct tevent_req *req = NULL, *subreq = NULL;
1434         struct share_mode_watch_state *state = NULL;
1435
1436         req = tevent_req_create(
1437                 mem_ctx, &state, struct share_mode_watch_state);
1438         if (req == NULL) {
1439                 return NULL;
1440         }
1441
1442         if (share_mode_g_lock_within_cb(key)) {
1443                 state->within_cb = true;
1444                 subreq = g_lock_lock_cb_watch_data_send(state, ev,
1445                                                         current_share_mode_glck,
1446                                                         blocker);
1447                 if (tevent_req_nomem(subreq, req)) {
1448                         return tevent_req_post(req, ev);
1449                 }
1450         } else {
1451                 subreq = g_lock_watch_data_send(state, ev, lock_ctx, key, blocker);
1452                 if (tevent_req_nomem(subreq, req)) {
1453                         return tevent_req_post(req, ev);
1454                 }
1455         }
1456         tevent_req_set_callback(subreq, share_mode_watch_done, req);
1457         return req;
1458 }
1459
1460 static void share_mode_watch_done(struct tevent_req *subreq)
1461 {
1462         struct tevent_req *req = tevent_req_callback_data(
1463                 subreq, struct tevent_req);
1464         struct share_mode_watch_state *state = tevent_req_data(
1465                 req, struct share_mode_watch_state);
1466         NTSTATUS status;
1467
1468         if (state->within_cb) {
1469                 status = g_lock_lock_cb_watch_data_recv(
1470                         subreq, &state->blockerdead, &state->blocker);
1471                 if (tevent_req_nterror(req, status)) {
1472                         return;
1473                 }
1474         } else {
1475                 status = g_lock_watch_data_recv(
1476                         subreq, &state->blockerdead, &state->blocker);
1477                 if (tevent_req_nterror(req, status)) {
1478                         return;
1479                 }
1480         }
1481
1482         tevent_req_done(req);
1483 }
1484
1485 NTSTATUS share_mode_watch_recv(
1486         struct tevent_req *req, bool *blockerdead, struct server_id *blocker)
1487 {
1488         struct share_mode_watch_state *state = tevent_req_data(
1489                 req, struct share_mode_watch_state);
1490         NTSTATUS status;
1491
1492         if (tevent_req_is_nterror(req, &status)) {
1493                 return status;
1494         }
1495         if (blockerdead != NULL) {
1496                 *blockerdead = state->blockerdead;
1497         }
1498         if (blocker != NULL) {
1499                 *blocker = state->blocker;
1500         }
1501         return NT_STATUS_OK;
1502 }
1503
1504 struct fetch_share_mode_unlocked_state {
1505         TALLOC_CTX *mem_ctx;
1506         struct file_id id;
1507         struct share_mode_lock *lck;
1508 };
1509
1510 static void fetch_share_mode_unlocked_parser(
1511         struct server_id exclusive,
1512         size_t num_shared,
1513         const struct server_id *shared,
1514         const uint8_t *data,
1515         size_t datalen,
1516         void *private_data)
1517 {
1518         struct fetch_share_mode_unlocked_state *state = private_data;
1519         struct locking_tdb_data ltdb = { 0 };
1520
1521         if (datalen != 0) {
1522                 bool ok = locking_tdb_data_get(&ltdb, data, datalen);
1523                 if (!ok) {
1524                         DBG_DEBUG("locking_tdb_data_get failed\n");
1525                         return;
1526                 }
1527         }
1528
1529         if (ltdb.share_mode_data_len == 0) {
1530                 /* Likely a ctdb tombstone record, ignore it */
1531                 return;
1532         }
1533
1534         state->lck = talloc(state->mem_ctx, struct share_mode_lock);
1535         if (state->lck == NULL) {
1536                 DEBUG(0, ("talloc failed\n"));
1537                 return;
1538         }
1539         state->lck->id = state->id;
1540
1541         state->lck->cached_data = parse_share_modes(
1542                 state->lck,
1543                 state->id,
1544                 ltdb.share_mode_data_buf,
1545                 ltdb.share_mode_data_len);
1546         if (state->lck->cached_data == NULL) {
1547                 DBG_DEBUG("parse_share_modes failed\n");
1548                 TALLOC_FREE(state->lck);
1549         }
1550 }
1551
1552 /*******************************************************************
1553  Get a share_mode_lock without locking the database or reference
1554  counting. Used by smbstatus to display existing share modes.
1555 ********************************************************************/
1556
1557 struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx,
1558                                                   struct file_id id)
1559 {
1560         struct fetch_share_mode_unlocked_state state = {
1561                 .mem_ctx = mem_ctx,
1562                 .id = id,
1563         };
1564         TDB_DATA key = locking_key(&id);
1565         NTSTATUS status;
1566
1567         status = g_lock_dump(
1568                 lock_ctx, key, fetch_share_mode_unlocked_parser, &state);
1569         if (!NT_STATUS_IS_OK(status)) {
1570                 DBG_DEBUG("g_lock_dump failed: %s\n", nt_errstr(status));
1571                 return NULL;
1572         }
1573         return state.lck;
1574 }
1575
1576 struct fetch_share_mode_state {
1577         struct file_id id;
1578         struct share_mode_lock *lck;
1579         NTSTATUS status;
1580 };
1581
1582 static void fetch_share_mode_fn(
1583         struct server_id exclusive,
1584         size_t num_shared,
1585         const struct server_id *shared,
1586         const uint8_t *data,
1587         size_t datalen,
1588         void *private_data);
1589 static void fetch_share_mode_done(struct tevent_req *subreq);
1590
1591 /**
1592  * @brief Get a share_mode_lock without locking or refcounting
1593  *
1594  * This can be used in a clustered Samba environment where the async dbwrap
1595  * request is sent over a socket to the local ctdbd. If the send queue is full
1596  * and the caller was issuing multiple async dbwrap requests in a loop, the
1597  * caller knows it's probably time to stop sending requests for now and try
1598  * again later.
1599  *
1600  * @param[in]  mem_ctx The talloc memory context to use.
1601  *
1602  * @param[in]  ev      The event context to work on.
1603  *
1604  * @param[in]  id      The file id for the locking.tdb key
1605  *
1606  * @param[out] queued  This boolean out parameter tells the caller whether the
1607  *                     async request is blocked in a full send queue:
1608  *
1609  *                     false := request is dispatched
1610  *
1611  *                     true  := send queue is full, request waiting to be
1612  *                              dispatched
1613  *
1614  * @return             The new async request, NULL on error.
1615  **/
1616 struct tevent_req *fetch_share_mode_send(TALLOC_CTX *mem_ctx,
1617                                          struct tevent_context *ev,
1618                                          struct file_id id,
1619                                          bool *queued)
1620 {
1621         struct tevent_req *req = NULL, *subreq = NULL;
1622         struct fetch_share_mode_state *state = NULL;
1623
1624         *queued = false;
1625
1626         req = tevent_req_create(mem_ctx, &state,
1627                                 struct fetch_share_mode_state);
1628         if (req == NULL) {
1629                 return NULL;
1630         }
1631         state->id = id;
1632
1633         subreq = g_lock_dump_send(
1634                 state,
1635                 ev,
1636                 lock_ctx,
1637                 locking_key(&id),
1638                 fetch_share_mode_fn,
1639                 state);
1640         if (tevent_req_nomem(subreq, req)) {
1641                 return tevent_req_post(req, ev);
1642         }
1643         tevent_req_set_callback(subreq, fetch_share_mode_done, req);
1644         return req;
1645 }
1646
1647 static void fetch_share_mode_fn(
1648         struct server_id exclusive,
1649         size_t num_shared,
1650         const struct server_id *shared,
1651         const uint8_t *data,
1652         size_t datalen,
1653         void *private_data)
1654 {
1655         struct fetch_share_mode_state *state = talloc_get_type_abort(
1656                 private_data, struct fetch_share_mode_state);
1657         struct locking_tdb_data ltdb = { 0 };
1658
1659         if (datalen != 0) {
1660                 bool ok = locking_tdb_data_get(&ltdb, data, datalen);
1661                 if (!ok) {
1662                         DBG_DEBUG("locking_tdb_data_get failed\n");
1663                         return;
1664                 }
1665         }
1666
1667         if (ltdb.share_mode_data_len == 0) {
1668                 /* Likely a ctdb tombstone record, ignore it */
1669                 return;
1670         }
1671
1672         state->lck = talloc(state, struct share_mode_lock);
1673         if (state->lck == NULL) {
1674                 DBG_WARNING("talloc failed\n");
1675                 state->status = NT_STATUS_NO_MEMORY;
1676                 return;
1677         }
1678         state->lck->id = state->id,
1679
1680         state->lck->cached_data = parse_share_modes(
1681                 state->lck,
1682                 state->id,
1683                 ltdb.share_mode_data_buf,
1684                 ltdb.share_mode_data_len);
1685         if (state->lck->cached_data == NULL) {
1686                 DBG_DEBUG("parse_share_modes failed\n");
1687                 state->status = NT_STATUS_INTERNAL_DB_CORRUPTION;
1688                 TALLOC_FREE(state->lck);
1689                 return;
1690         }
1691 }
1692
1693 static void fetch_share_mode_done(struct tevent_req *subreq)
1694 {
1695         struct tevent_req *req = tevent_req_callback_data(
1696                 subreq, struct tevent_req);
1697         struct fetch_share_mode_state *state = tevent_req_data(
1698                 req, struct fetch_share_mode_state);
1699         NTSTATUS status;
1700
1701         status = g_lock_dump_recv(subreq);
1702         TALLOC_FREE(subreq);
1703         if (tevent_req_nterror(req, status)) {
1704                 return;
1705         }
1706         if (tevent_req_nterror(req, state->status)) {
1707                 return;
1708         }
1709         tevent_req_done(req);
1710 }
1711
1712 NTSTATUS fetch_share_mode_recv(struct tevent_req *req,
1713                                TALLOC_CTX *mem_ctx,
1714                                struct share_mode_lock **_lck)
1715 {
1716         struct fetch_share_mode_state *state = tevent_req_data(
1717                 req, struct fetch_share_mode_state);
1718         struct share_mode_lock *lck = NULL;
1719
1720         NTSTATUS status;
1721
1722         if (tevent_req_is_nterror(req, &status)) {
1723                 tevent_req_received(req);
1724                 return status;
1725         }
1726
1727         if (state->lck == NULL) {
1728                 tevent_req_received(req);
1729                 return NT_STATUS_NOT_FOUND;
1730         }
1731
1732         lck = talloc_move(mem_ctx, &state->lck);
1733
1734         if (DEBUGLEVEL >= 10) {
1735                 DBG_DEBUG("share_mode_data:\n");
1736                 NDR_PRINT_DEBUG(share_mode_data, lck->cached_data);
1737         }
1738
1739         *_lck = lck;
1740         tevent_req_received(req);
1741         return NT_STATUS_OK;
1742 }
1743
1744 struct share_mode_forall_state {
1745         TDB_DATA key;
1746         int (*fn)(struct file_id fid,
1747                   const struct share_mode_data *data,
1748                   void *private_data);
1749         void *private_data;
1750 };
1751
1752 static void share_mode_forall_dump_fn(
1753         struct server_id exclusive,
1754         size_t num_shared,
1755         const struct server_id *shared,
1756         const uint8_t *data,
1757         size_t datalen,
1758         void *private_data)
1759 {
1760         struct share_mode_forall_state *state = private_data;
1761         struct file_id fid;
1762         struct locking_tdb_data ltdb = { 0 };
1763         bool ok;
1764         struct share_mode_data *d;
1765
1766         if (state->key.dsize != sizeof(fid)) {
1767                 DBG_DEBUG("Got invalid key length %zu\n", state->key.dsize);
1768                 return;
1769         }
1770         memcpy(&fid, state->key.dptr, sizeof(fid));
1771
1772         ok = locking_tdb_data_get(&ltdb, data, datalen);
1773         if (!ok) {
1774                 DBG_DEBUG("locking_tdb_data_get() failed\n");
1775                 return;
1776         }
1777
1778         d = parse_share_modes(
1779                 talloc_tos(),
1780                 fid,
1781                 ltdb.share_mode_data_buf,
1782                 ltdb.share_mode_data_len);
1783         if (d == NULL) {
1784                 DBG_DEBUG("parse_share_modes() failed\n");
1785                 return;
1786         }
1787
1788         state->fn(fid, d, state->private_data);
1789         TALLOC_FREE(d);
1790 }
1791
1792 static int share_mode_forall_fn(TDB_DATA key, void *private_data)
1793 {
1794         struct share_mode_forall_state *state = private_data;
1795         NTSTATUS status;
1796
1797         state->key = key;
1798
1799         status = share_mode_g_lock_dump(
1800                 key, share_mode_forall_dump_fn, private_data);
1801         if (!NT_STATUS_IS_OK(status)) {
1802                 DBG_GET_SHARE_MODE_LOCK(status,
1803                         "g_lock_dump failed: %s\n",
1804                         nt_errstr(status));
1805         }
1806         return 0;
1807 }
1808
1809 int share_mode_forall(int (*fn)(struct file_id fid,
1810                                 const struct share_mode_data *data,
1811                                 void *private_data),
1812                       void *private_data)
1813 {
1814         struct share_mode_forall_state state = {
1815                 .fn = fn,
1816                 .private_data = private_data
1817         };
1818         int ret;
1819
1820         if (lock_ctx == NULL) {
1821                 return 0;
1822         }
1823
1824         ret = g_lock_locks(
1825                 lock_ctx, share_mode_forall_fn, &state);
1826         if (ret < 0) {
1827                 DBG_ERR("g_lock_locks failed\n");
1828         }
1829         return ret;
1830 }
1831
1832 struct share_entry_forall_state {
1833         struct file_id fid;
1834         const struct share_mode_data *data;
1835         int (*fn)(struct file_id fid,
1836                   const struct share_mode_data *data,
1837                   const struct share_mode_entry *entry,
1838                   void *private_data);
1839         void *private_data;
1840         int ret;
1841 };
1842
1843 static bool share_entry_traverse_walker(
1844         struct share_mode_entry *e,
1845         bool *modified,
1846         void *private_data)
1847 {
1848         struct share_entry_forall_state *state = private_data;
1849
1850         state->ret = state->fn(
1851                 state->fid, state->data, e, state->private_data);
1852         return (state->ret != 0);
1853 }
1854
1855 static int share_entry_traverse_fn(struct file_id fid,
1856                                    const struct share_mode_data *data,
1857                                    void *private_data)
1858 {
1859         struct share_entry_forall_state *state = private_data;
1860         struct share_mode_lock lck = {
1861                 .id = fid,
1862                 .cached_data = discard_const_p(struct share_mode_data, data)
1863         };
1864         bool ok;
1865
1866         state->fid = fid;
1867         state->data = data;
1868
1869         ok = share_mode_forall_entries(
1870                 &lck, share_entry_traverse_walker, state);
1871         if (!ok) {
1872                 DBG_ERR("share_mode_forall_entries failed\n");
1873                 return false;
1874         }
1875
1876         return state->ret;
1877 }
1878
1879 /*******************************************************************
1880  Call the specified function on each entry under management by the
1881  share mode system.
1882 ********************************************************************/
1883
1884 int share_entry_forall(int (*fn)(struct file_id fid,
1885                                  const struct share_mode_data *data,
1886                                  const struct share_mode_entry *entry,
1887                                  void *private_data),
1888                       void *private_data)
1889 {
1890         struct share_entry_forall_state state = {
1891                 .fn = fn, .private_data = private_data };
1892
1893         return share_mode_forall(share_entry_traverse_fn, &state);
1894 }
1895
1896 static int share_mode_entry_cmp(
1897         struct server_id pid1,
1898         uint64_t share_file_id1,
1899         struct server_id pid2,
1900         uint64_t share_file_id2)
1901 {
1902         int cmp;
1903
1904         cmp = server_id_cmp(&pid1, &pid2);
1905         if (cmp != 0) {
1906                 return cmp;
1907         }
1908         if (share_file_id1 != share_file_id2) {
1909                 return (share_file_id1 < share_file_id2) ? -1 : 1;
1910         }
1911         return 0;
1912 }
1913
1914 static size_t share_mode_entry_find(
1915         const uint8_t *data,
1916         size_t num_share_modes,
1917         struct server_id pid,
1918         uint64_t share_file_id,
1919         struct share_mode_entry *e,
1920         bool *match)
1921 {
1922         ssize_t left, right, middle;
1923
1924         *match = false;
1925
1926         if (num_share_modes == 0) {
1927                 return 0;
1928         }
1929
1930         left = 0;
1931         right = (num_share_modes-1);
1932
1933         while (left <= right) {
1934                 const uint8_t *middle_ptr = NULL;
1935                 int cmp;
1936                 bool ok;
1937
1938                 middle = left + ((right - left) / 2);
1939                 middle_ptr = data + middle * SHARE_MODE_ENTRY_SIZE;
1940
1941                 DBG_DEBUG("left=%zu, right=%zu, middle=%zu, middle_ptr=%p\n",
1942                           left,
1943                           right,
1944                           middle,
1945                           middle_ptr);
1946
1947                 ok = share_mode_entry_get(middle_ptr, e);
1948                 if (!ok) {
1949                         DBG_DEBUG("share_mode_entry_get failed\n");
1950                         return 0;
1951                 }
1952
1953                 cmp = share_mode_entry_cmp(
1954                         e->pid, e->share_file_id, pid, share_file_id);
1955                 if (cmp == 0) {
1956                         *match = true;
1957                         return middle;
1958                 }
1959
1960                 if (cmp < 0) {
1961                         right = middle-1;
1962                 } else {
1963                         left = middle+1;
1964                 }
1965         }
1966
1967         return left;
1968 }
1969
1970 bool set_share_mode(struct share_mode_lock *lck,
1971                     struct files_struct *fsp,
1972                     uid_t uid,
1973                     uint64_t mid,
1974                     uint16_t op_type,
1975                     const struct smb2_lease_key *lease_key,
1976                     uint32_t share_access,
1977                     uint32_t access_mask)
1978 {
1979         struct share_mode_data *d = share_mode_lock_assert_private_data(lck);
1980         TDB_DATA key = locking_key(&d->id);
1981         struct server_id my_pid = messaging_server_id(
1982                 fsp->conn->sconn->msg_ctx);
1983         struct locking_tdb_data *ltdb = NULL;
1984         size_t idx;
1985         struct share_mode_entry e = { .pid.pid = 0 };
1986         struct share_mode_entry_buf e_buf;
1987         NTSTATUS status;
1988         bool ok, found;
1989
1990         TDB_DATA dbufs[3];
1991         size_t num_dbufs = 0;
1992
1993         status = locking_tdb_data_fetch(key, talloc_tos(), &ltdb);
1994         if (!NT_STATUS_IS_OK(status)) {
1995                 DBG_ERR("locking_tdb_data_fetch failed: %s\n",
1996                         nt_errstr(status));
1997                 return false;
1998         }
1999         DBG_DEBUG("num_share_modes=%zu\n", ltdb->num_share_entries);
2000
2001         idx = share_mode_entry_find(
2002                 ltdb->share_entries,
2003                 ltdb->num_share_entries,
2004                 my_pid,
2005                 fh_get_gen_id(fsp->fh),
2006                 &e,
2007                 &found);
2008         if (found) {
2009                 DBG_WARNING("Found duplicate share mode\n");
2010                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2011                 goto done;
2012         }
2013
2014         e = (struct share_mode_entry) {
2015                 .pid = my_pid,
2016                 .share_access = share_access,
2017                 .private_options = fh_get_private_options(fsp->fh),
2018                 .access_mask = access_mask,
2019                 .op_mid = mid,
2020                 .op_type = op_type,
2021                 .time.tv_sec = fsp->open_time.tv_sec,
2022                 .time.tv_usec = fsp->open_time.tv_usec,
2023                 .share_file_id = fh_get_gen_id(fsp->fh),
2024                 .uid = (uint32_t)uid,
2025                 .flags = (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) ?
2026                         SHARE_MODE_FLAG_POSIX_OPEN : 0,
2027                 .name_hash = fsp->name_hash,
2028         };
2029
2030         if (op_type == LEASE_OPLOCK) {
2031                 const struct GUID *client_guid = fsp_client_guid(fsp);
2032                 e.client_guid = *client_guid;
2033                 e.lease_key = *lease_key;
2034         }
2035
2036         ok = share_mode_entry_put(&e, &e_buf);
2037         if (!ok) {
2038                 DBG_DEBUG("share_mode_entry_put failed\n");
2039                 status = NT_STATUS_INTERNAL_ERROR;
2040                 goto done;
2041         }
2042
2043         DBG_DEBUG("idx=%zu, found=%d\n", idx, (int)found);
2044
2045         if (idx > 0) {
2046                 dbufs[num_dbufs] = (TDB_DATA) {
2047                         .dptr = discard_const_p(uint8_t, ltdb->share_entries),
2048                         .dsize = idx * SHARE_MODE_ENTRY_SIZE,
2049                 };
2050                 num_dbufs += 1;
2051         }
2052
2053         dbufs[num_dbufs] = (TDB_DATA) {
2054                 .dptr = e_buf.buf, .dsize = SHARE_MODE_ENTRY_SIZE,
2055         };
2056         num_dbufs += 1;
2057
2058         if (idx < ltdb->num_share_entries) {
2059                 size_t num_after_idx = (ltdb->num_share_entries-idx);
2060                 dbufs[num_dbufs] = (TDB_DATA) {
2061                         .dptr = discard_const_p(uint8_t, ltdb->share_entries) +
2062                                 idx * SHARE_MODE_ENTRY_SIZE,
2063                         .dsize = num_after_idx * SHARE_MODE_ENTRY_SIZE,
2064                 };
2065                 num_dbufs += 1;
2066         }
2067
2068         {
2069                 size_t i;
2070                 for (i=0; i<num_dbufs; i++) {
2071                         DBG_DEBUG("dbufs[%zu]=(%p, %zu)\n",
2072                                   i,
2073                                   dbufs[i].dptr,
2074                                   dbufs[i].dsize);
2075                 }
2076         }
2077
2078         if (num_dbufs == 1) {
2079                 /*
2080                  * Storing a fresh record with just one share entry
2081                  */
2082                 d->modified = true;
2083         }
2084
2085         /*
2086          * If there was any existing data in
2087          * ltdb->share_entries, it's now been
2088          * moved and we've split it into:
2089          *
2090          * num_dbufs = 3
2091          * dbufs[0] -> old sorted data less than new_entry
2092          * dbufs[1] -> new_share_mode_entry
2093          * dbufs[2] -> old sorted_data greater than new entry.
2094          *
2095          * So the old data inside ltdb->share_entries is
2096          * no longer valid.
2097          *
2098          * If we're storing a brand new entry the
2099          * dbufs look like:
2100          *
2101          * num_dbufs = 1
2102          * dbufs[0] -> new_share_mode_entry
2103          *
2104          * Either way we must set ltdb->share_entries = NULL
2105          * and ltdb->num_share_entries = 0 so that
2106          * locking_tdb_data_store() doesn't use it to
2107          * store any data. It's no longer there.
2108          */
2109
2110         ltdb->share_entries = NULL;
2111         ltdb->num_share_entries = 0;
2112
2113         status = share_mode_data_ltdb_store(d, key, ltdb, dbufs, num_dbufs);
2114         if (!NT_STATUS_IS_OK(status)) {
2115                 DBG_ERR("share_mode_data_ltdb_store failed: %s\n",
2116                         nt_errstr(status));
2117         }
2118 done:
2119         TALLOC_FREE(ltdb);
2120         return NT_STATUS_IS_OK(status);
2121 }
2122
2123 static bool share_mode_for_one_entry(
2124         bool (*fn)(struct share_mode_entry *e,
2125                    bool *modified,
2126                    void *private_data),
2127         void *private_data,
2128         size_t *i,
2129         uint8_t *data,
2130         size_t *num_share_modes,
2131         bool *writeback)
2132 {
2133         DATA_BLOB blob = {
2134                 .data = data + (*i) * SHARE_MODE_ENTRY_SIZE,
2135                 .length = SHARE_MODE_ENTRY_SIZE,
2136         };
2137         struct share_mode_entry e = {.pid.pid=0};
2138         enum ndr_err_code ndr_err = NDR_ERR_SUCCESS;
2139         bool modified = false;
2140         bool stop = false;
2141         struct server_id e_pid;
2142         uint64_t e_share_file_id;
2143
2144         ndr_err = ndr_pull_struct_blob_all_noalloc(
2145                 &blob,
2146                 &e,
2147                 (ndr_pull_flags_fn_t)ndr_pull_share_mode_entry);
2148         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2149                 DBG_WARNING("ndr_pull_share_mode_entry failed\n");
2150                 *i += 1;
2151                 return false;
2152         }
2153         if (DEBUGLEVEL >= 10) {
2154                 DBG_DEBUG("entry[%zu]:\n", *i);
2155                 NDR_PRINT_DEBUG(share_mode_entry, &e);
2156         }
2157
2158         e_pid = e.pid;
2159         e_share_file_id = e.share_file_id;
2160
2161         stop = fn(&e, &modified, private_data);
2162
2163         DBG_DEBUG("entry[%zu]: modified=%d, e.stale=%d\n",
2164                   *i,
2165                   (int)modified,
2166                   (int)e.stale);
2167
2168         if (e.stale) {
2169                 if (DEBUGLEVEL>=10) {
2170                         DBG_DEBUG("share_mode_entry:\n");
2171                         NDR_PRINT_DEBUG(share_mode_entry, &e);
2172                 }
2173
2174                 if (*i < *num_share_modes) {
2175                         memmove(blob.data,
2176                                 blob.data + SHARE_MODE_ENTRY_SIZE,
2177                                 (*num_share_modes - *i - 1) *
2178                                 SHARE_MODE_ENTRY_SIZE);
2179                 }
2180                 *num_share_modes -= 1;
2181                 *writeback = true;
2182                 return stop;
2183         }
2184
2185         if (modified) {
2186                 if (DEBUGLEVEL>=10) {
2187                         DBG_DEBUG("share_mode_entry:\n");
2188                         NDR_PRINT_DEBUG(share_mode_entry, &e);
2189                 }
2190
2191                 /*
2192                  * Make sure sorting order is kept intact
2193                  */
2194                 SMB_ASSERT(server_id_equal(&e_pid, &e.pid));
2195                 SMB_ASSERT(e_share_file_id == e.share_file_id);
2196
2197                 ndr_err = ndr_push_struct_into_fixed_blob(
2198                         &blob,
2199                         &e,
2200                         (ndr_push_flags_fn_t)
2201                         ndr_push_share_mode_entry);
2202                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2203                         DBG_WARNING("ndr_push_share_mode_entry "
2204                                     "failed: %s\n",
2205                                     ndr_errstr(ndr_err));
2206                         /*
2207                          * Not much we can do, just ignore it
2208                          */
2209                 }
2210                 *i += 1;
2211                 *writeback = true;
2212                 return stop;
2213         }
2214
2215         if (stop) {
2216                 return true;
2217         }
2218
2219         *i += 1;
2220         return false;
2221 }
2222
2223 bool share_mode_forall_entries(
2224         struct share_mode_lock *lck,
2225         bool (*fn)(struct share_mode_entry *e,
2226                    bool *modified,
2227                    void *private_data),
2228         void *private_data)
2229 {
2230         struct file_id id = share_mode_lock_file_id(lck);
2231         struct share_mode_data *d = NULL;
2232         TDB_DATA key = locking_key(&id);
2233         struct locking_tdb_data *ltdb = NULL;
2234         uint8_t *share_entries = NULL;
2235         size_t num_share_entries;
2236         bool writeback = false;
2237         NTSTATUS status;
2238         bool stop = false;
2239         size_t i;
2240
2241         status = share_mode_lock_access_private_data(lck, &d);
2242         if (!NT_STATUS_IS_OK(status)) {
2243                 struct file_id_buf id_buf;
2244                 /* Any error recovery possible here ? */
2245                 DBG_ERR("share_mode_lock_access_private_data() failed for "
2246                         "%s - %s\n",
2247                         file_id_str_buf(id, &id_buf),
2248                         nt_errstr(status));
2249                 return false;
2250         }
2251
2252         status = locking_tdb_data_fetch(key, talloc_tos(), &ltdb);
2253         if (!NT_STATUS_IS_OK(status)) {
2254                 DBG_ERR("locking_tdb_data_fetch failed: %s\n",
2255                         nt_errstr(status));
2256                 return false;
2257         }
2258         DBG_DEBUG("num_share_modes=%zu\n", ltdb->num_share_entries);
2259
2260         num_share_entries = ltdb->num_share_entries;
2261         share_entries = discard_const_p(uint8_t, ltdb->share_entries);
2262
2263         i = 0;
2264         while (i<num_share_entries) {
2265                 stop = share_mode_for_one_entry(
2266                         fn,
2267                         private_data,
2268                         &i,
2269                         share_entries,
2270                         &num_share_entries,
2271                         &writeback);
2272                 if (stop) {
2273                         break;
2274                 }
2275         }
2276
2277         DBG_DEBUG("num_share_entries=%zu, writeback=%d\n",
2278                   num_share_entries,
2279                   (int)writeback);
2280
2281         if (!writeback) {
2282                 TALLOC_FREE(ltdb);
2283                 return true;
2284         }
2285
2286         if ((ltdb->num_share_entries != 0 ) && (num_share_entries == 0)) {
2287                 /*
2288                  * This routine wiped all share entries, let
2289                  * share_mode_data_store() delete the record
2290                  */
2291                 d->modified = true;
2292         }
2293
2294         ltdb->num_share_entries = num_share_entries;
2295         ltdb->share_entries = share_entries;
2296
2297         status = share_mode_data_ltdb_store(d, key, ltdb, NULL, 0);
2298         TALLOC_FREE(ltdb);
2299         if (!NT_STATUS_IS_OK(status)) {
2300                 DBG_ERR("share_mode_data_ltdb_store failed: %s\n",
2301                         nt_errstr(status));
2302                 return false;
2303         }
2304
2305         return true;
2306 }
2307
2308 struct share_mode_count_entries_state {
2309         size_t num_share_modes;
2310         NTSTATUS status;
2311 };
2312
2313 static void share_mode_count_entries_fn(
2314         struct server_id exclusive,
2315         size_t num_shared,
2316         const struct server_id *shared,
2317         const uint8_t *data,
2318         size_t datalen,
2319         void *private_data)
2320 {
2321         struct share_mode_count_entries_state *state = private_data;
2322         struct locking_tdb_data ltdb = { 0 };
2323         bool ok;
2324
2325         ok = locking_tdb_data_get(&ltdb, data, datalen);
2326         if (!ok) {
2327                 DBG_WARNING("locking_tdb_data_get failed for %zu\n", datalen);
2328                 state->status = NT_STATUS_INTERNAL_DB_CORRUPTION;
2329                 return;
2330         }
2331         state->num_share_modes = ltdb.num_share_entries;
2332         state->status = NT_STATUS_OK;
2333 }
2334
2335 NTSTATUS share_mode_count_entries(struct file_id fid, size_t *num_share_modes)
2336 {
2337         struct share_mode_count_entries_state state = {
2338                 .status = NT_STATUS_NOT_FOUND,
2339         };
2340         NTSTATUS status;
2341
2342         status = g_lock_dump(
2343                 lock_ctx,
2344                 locking_key(&fid),
2345                 share_mode_count_entries_fn,
2346                 &state);
2347         if (!NT_STATUS_IS_OK(status)) {
2348                 DBG_DEBUG("g_lock_dump failed: %s\n",
2349                           nt_errstr(status));
2350                 return status;
2351         }
2352         if (!NT_STATUS_IS_OK(state.status)) {
2353                 DBG_DEBUG("share_mode_count_entries_fn failed: %s\n",
2354                           nt_errstr(state.status));
2355                 return state.status;
2356         }
2357
2358         *num_share_modes = state.num_share_modes;
2359         return NT_STATUS_OK;
2360 }
2361
2362 static bool share_mode_entry_do(
2363         struct share_mode_data *d,
2364         struct server_id pid,
2365         uint64_t share_file_id,
2366         void (*fn)(struct share_mode_entry *e,
2367                    size_t num_share_modes,
2368                    bool *modified,
2369                    void *private_data),
2370         void *private_data)
2371 {
2372         TDB_DATA key = locking_key(&d->id);
2373         struct locking_tdb_data *ltdb = NULL;
2374         size_t idx;
2375         bool found = false;
2376         bool modified = false;
2377         struct share_mode_entry e;
2378         uint8_t *e_ptr = NULL;
2379         NTSTATUS status;
2380         bool ret = false;
2381
2382         status = locking_tdb_data_fetch(key, talloc_tos(), &ltdb);
2383         if (!NT_STATUS_IS_OK(status)) {
2384                 DBG_ERR("locking_tdb_data_fetch failed: %s\n",
2385                         nt_errstr(status));
2386                 return false;
2387         }
2388         DBG_DEBUG("num_share_modes=%zu\n", ltdb->num_share_entries);
2389
2390         idx = share_mode_entry_find(
2391                 ltdb->share_entries,
2392                 ltdb->num_share_entries,
2393                 pid,
2394                 share_file_id,
2395                 &e,
2396                 &found);
2397         if (!found) {
2398                 DBG_WARNING("Did not find share mode entry for %"PRIu64"\n",
2399                             share_file_id);
2400                 goto done;
2401         }
2402
2403         if (DEBUGLEVEL>=10) {
2404                 DBG_DEBUG("entry[%zu]:\n", idx);
2405                 NDR_PRINT_DEBUG(share_mode_entry, &e);
2406         }
2407
2408         fn(&e, ltdb->num_share_entries, &modified, private_data);
2409
2410         DBG_DEBUG("entry[%zu]: modified=%d, e.stale=%d\n",
2411                   idx,
2412                   (int)modified,
2413                   (int)e.stale);
2414
2415         if (!e.stale && !modified) {
2416                 ret = true;
2417                 goto done;
2418         }
2419
2420         e_ptr = discard_const_p(uint8_t, ltdb->share_entries) +
2421                 idx * SHARE_MODE_ENTRY_SIZE;
2422
2423         if (e.stale) {
2424                 /*
2425                  * Move the rest down one entry
2426                  */
2427                 size_t behind = ltdb->num_share_entries - idx - 1;
2428                 if (behind != 0) {
2429                         memmove(e_ptr,
2430                                 e_ptr + SHARE_MODE_ENTRY_SIZE,
2431                                 behind * SHARE_MODE_ENTRY_SIZE);
2432                 }
2433                 ltdb->num_share_entries -= 1;
2434
2435                 if (ltdb->num_share_entries == 0) {
2436                         /*
2437                          * Tell share_mode_lock_destructor() to delete
2438                          * the whole record
2439                          */
2440                         d->modified = true;
2441                 }
2442
2443                 if (DEBUGLEVEL>=10) {
2444                         DBG_DEBUG("share_mode_entry:\n");
2445                         NDR_PRINT_DEBUG(share_mode_entry, &e);
2446                 }
2447         } else {
2448                 struct share_mode_entry_buf buf;
2449                 bool ok;
2450
2451                 if (ltdb->num_share_entries != 1) {
2452                         /*
2453                          * Make sure the sorting order stays intact
2454                          */
2455                         SMB_ASSERT(server_id_equal(&e.pid, &pid));
2456                         SMB_ASSERT(e.share_file_id == share_file_id);
2457                 }
2458
2459                 ok = share_mode_entry_put(&e, &buf);
2460                 if (!ok) {
2461                         DBG_DEBUG("share_mode_entry_put failed\n");
2462                         goto done;
2463                 }
2464                 memcpy(e_ptr, buf.buf, SHARE_MODE_ENTRY_SIZE);
2465         }
2466
2467         status = share_mode_data_ltdb_store(d, key, ltdb, NULL, 0);
2468         if (!NT_STATUS_IS_OK(status)) {
2469                 DBG_ERR("share_mode_data_ltdb_store failed: %s\n",
2470                         nt_errstr(status));
2471                 goto done;
2472         }
2473
2474         ret = true;
2475 done:
2476         TALLOC_FREE(ltdb);
2477         return ret;
2478 }
2479
2480 struct del_share_mode_state {
2481         bool ok;
2482 };
2483
2484 static void del_share_mode_fn(
2485         struct share_mode_entry *e,
2486         size_t num_share_modes,
2487         bool *modified,
2488         void *private_data)
2489 {
2490         struct del_share_mode_state *state = private_data;
2491         e->stale = true;
2492         state->ok = true;
2493 }
2494
2495 bool del_share_mode_open_id(struct share_mode_lock *lck,
2496                             struct server_id open_pid,
2497                             uint64_t open_file_id)
2498 {
2499         struct del_share_mode_state state = { .ok = false };
2500         struct share_mode_data *d = NULL;
2501         NTSTATUS status;
2502         bool ok;
2503
2504         status = share_mode_lock_access_private_data(lck, &d);
2505         if (!NT_STATUS_IS_OK(status)) {
2506                 /* Any error recovery possible here ? */
2507                 return false;
2508         }
2509
2510         ok = share_mode_entry_do(
2511                 d,
2512                 open_pid,
2513                 open_file_id,
2514                 del_share_mode_fn,
2515                 &state);
2516         if (!ok) {
2517                 DBG_DEBUG("share_mode_entry_do failed\n");
2518                 return false;
2519         }
2520         if (!state.ok) {
2521                 DBG_DEBUG("del_share_mode_fn failed\n");
2522                 return false;
2523         }
2524         return true;
2525 }
2526
2527 bool del_share_mode(struct share_mode_lock *lck, files_struct *fsp)
2528 {
2529         struct server_id pid =
2530                 messaging_server_id(fsp->conn->sconn->msg_ctx);
2531         bool ok;
2532
2533         ok = del_share_mode_open_id(lck, pid, fh_get_gen_id(fsp->fh));
2534         if (!ok) {
2535                 struct file_id id = share_mode_lock_file_id(lck);
2536                 struct file_id_buf id_buf;
2537                 DBG_ERR("share_mode_lock_access_private_data() failed for "
2538                         "%s %s\n",
2539                         file_id_str_buf(id, &id_buf),
2540                         fsp_str_dbg(fsp));
2541                 return false;
2542         }
2543         return true;
2544 }
2545
2546 struct remove_share_oplock_state {
2547         bool ok;
2548 };
2549
2550 static void remove_share_oplock_fn(
2551         struct share_mode_entry *e,
2552         size_t num_share_modes,
2553         bool *modified,
2554         void *private_data)
2555 {
2556         struct remove_share_oplock_state *state = private_data;
2557
2558         e->op_type = NO_OPLOCK;
2559         *modified = true;
2560         state->ok = true;
2561 }
2562
2563 bool remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
2564 {
2565         struct remove_share_oplock_state state = { .ok = false };
2566         struct share_mode_data *d = NULL;
2567         NTSTATUS status;
2568         bool ok;
2569
2570         status = share_mode_lock_access_private_data(lck, &d);
2571         if (!NT_STATUS_IS_OK(status)) {
2572                 struct file_id id = share_mode_lock_file_id(lck);
2573                 struct file_id_buf id_buf;
2574                 /* Any error recovery possible here ? */
2575                 DBG_ERR("share_mode_lock_access_private_data() failed for "
2576                         "%s %s - %s\n",
2577                         file_id_str_buf(id, &id_buf),
2578                         fsp_str_dbg(fsp),
2579                         nt_errstr(status));
2580                 return false;
2581         }
2582
2583         ok = share_mode_entry_do(
2584                 d,
2585                 messaging_server_id(fsp->conn->sconn->msg_ctx),
2586                 fh_get_gen_id(fsp->fh),
2587                 remove_share_oplock_fn,
2588                 &state);
2589         if (!ok) {
2590                 DBG_DEBUG("share_mode_entry_do failed\n");
2591                 return false;
2592         }
2593         if (!state.ok) {
2594                 DBG_DEBUG("remove_share_oplock_fn failed\n");
2595                 return false;
2596         }
2597
2598         if (fsp->oplock_type == LEASE_OPLOCK) {
2599                 remove_lease_if_stale(
2600                         lck,
2601                         fsp_client_guid(fsp),
2602                         &fsp->lease->lease.lease_key);
2603         }
2604
2605         share_mode_wakeup_waiters(fsp->file_id);
2606
2607         return true;
2608 }
2609
2610 struct downgrade_share_oplock_state {
2611         bool ok;
2612 };
2613
2614 static void downgrade_share_oplock_fn(
2615         struct share_mode_entry *e,
2616         size_t num_share_modes,
2617         bool *modified,
2618         void *private_data)
2619 {
2620         struct downgrade_share_oplock_state *state = private_data;
2621
2622         e->op_type = LEVEL_II_OPLOCK;
2623         *modified = true;
2624         state->ok = true;
2625 }
2626
2627 bool downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
2628 {
2629         struct downgrade_share_oplock_state state = { .ok = false };
2630         struct share_mode_data *d = NULL;
2631         NTSTATUS status;
2632         bool ok;
2633
2634         status = share_mode_lock_access_private_data(lck, &d);
2635         if (!NT_STATUS_IS_OK(status)) {
2636                 struct file_id id = share_mode_lock_file_id(lck);
2637                 struct file_id_buf id_buf;
2638                 /* Any error recovery possible here ? */
2639                 DBG_ERR("share_mode_lock_access_private_data() failed for "
2640                         "%s %s - %s\n",
2641                         file_id_str_buf(id, &id_buf),
2642                         fsp_str_dbg(fsp),
2643                         nt_errstr(status));
2644                 return false;
2645         }
2646
2647         ok = share_mode_entry_do(
2648                 d,
2649                 messaging_server_id(fsp->conn->sconn->msg_ctx),
2650                 fh_get_gen_id(fsp->fh),
2651                 downgrade_share_oplock_fn,
2652                 &state);
2653         if (!ok) {
2654                 DBG_DEBUG("share_mode_entry_do failed\n");
2655                 return false;
2656         }
2657         if (!state.ok) {
2658                 DBG_DEBUG("downgrade_share_oplock_fn failed\n");
2659                 return false;
2660         }
2661
2662         d->flags |= SHARE_MODE_LEASE_READ;
2663         d->modified = true;
2664
2665         return true;
2666 }
2667
2668 bool mark_share_mode_disconnected(struct share_mode_lock *lck,
2669                                   struct files_struct *fsp)
2670 {
2671         struct server_id disconnected_pid = { .pid = 0 };
2672         bool ok;
2673
2674         if (fsp->op == NULL) {
2675                 return false;
2676         }
2677         if (!fsp->op->global->durable) {
2678                 return false;
2679         }
2680
2681         server_id_set_disconnected(&disconnected_pid);
2682
2683         ok = reset_share_mode_entry(
2684                 lck,
2685                 messaging_server_id(fsp->conn->sconn->msg_ctx),
2686                 fh_get_gen_id(fsp->fh),
2687                 disconnected_pid,
2688                 UINT64_MAX,
2689                 fsp->op->global->open_persistent_id);
2690
2691         return ok;
2692 }
2693
2694 bool reset_share_mode_entry(
2695         struct share_mode_lock *lck,
2696         struct server_id old_pid,
2697         uint64_t old_share_file_id,
2698         struct server_id new_pid,
2699         uint64_t new_mid,
2700         uint64_t new_share_file_id)
2701 {
2702         struct file_id id = share_mode_lock_file_id(lck);
2703         struct share_mode_data *d = NULL;
2704         TDB_DATA key = locking_key(&id);
2705         struct locking_tdb_data *ltdb = NULL;
2706         struct share_mode_entry e;
2707         struct share_mode_entry_buf e_buf;
2708         NTSTATUS status;
2709         int cmp;
2710         bool ret = false;
2711         bool ok;
2712
2713         status = share_mode_lock_access_private_data(lck, &d);
2714         if (!NT_STATUS_IS_OK(status)) {
2715                 struct file_id_buf id_buf;
2716                 /* Any error recovery possible here ? */
2717                 DBG_ERR("share_mode_lock_access_private_data() failed for "
2718                         "%s - %s\n",
2719                         file_id_str_buf(id, &id_buf),
2720                         nt_errstr(status));
2721                 return false;
2722         }
2723
2724         status = locking_tdb_data_fetch(key, talloc_tos(), &ltdb);
2725         if (!NT_STATUS_IS_OK(status)) {
2726                 DBG_ERR("locking_tdb_data_fetch failed: %s\n",
2727                         nt_errstr(status));
2728                 return false;
2729         }
2730
2731         if (ltdb->num_share_entries != 1) {
2732                 DBG_DEBUG("num_share_modes=%zu\n", ltdb->num_share_entries);
2733                 goto done;
2734         }
2735
2736         ok = share_mode_entry_get(ltdb->share_entries, &e);
2737         if (!ok) {
2738                 DBG_WARNING("share_mode_entry_get failed\n");
2739                 goto done;
2740         }
2741
2742         cmp = share_mode_entry_cmp(
2743                 old_pid, old_share_file_id, e.pid, e.share_file_id);
2744         if (cmp != 0) {
2745                 struct server_id_buf tmp1, tmp2;
2746                 DBG_WARNING("Expected pid=%s, file_id=%"PRIu64", "
2747                             "got pid=%s, file_id=%"PRIu64"\n",
2748                             server_id_str_buf(old_pid, &tmp1),
2749                             old_share_file_id,
2750                             server_id_str_buf(e.pid, &tmp2),
2751                             e.share_file_id);
2752                 goto done;
2753         }
2754
2755         e.pid = new_pid;
2756         if (new_mid != UINT64_MAX) {
2757                 e.op_mid = new_mid;
2758         }
2759         e.share_file_id = new_share_file_id;
2760
2761         ok = share_mode_entry_put(&e, &e_buf);
2762         if (!ok) {
2763                 DBG_WARNING("share_mode_entry_put failed\n");
2764                 goto done;
2765         }
2766
2767         ltdb->share_entries = e_buf.buf;
2768
2769         d->modified = true;
2770
2771         status = share_mode_data_ltdb_store(d, key, ltdb, NULL, 0);
2772         if (!NT_STATUS_IS_OK(status)) {
2773                 DBG_ERR("share_mode_data_ltdb_store failed: %s\n",
2774                         nt_errstr(status));
2775                 goto done;
2776         }
2777
2778         ret = true;
2779 done:
2780         TALLOC_FREE(ltdb);
2781         return ret;
2782 }
2783
2784 struct share_mode_do_locked_vfs_denied_state {
2785         struct file_id id;
2786         share_mode_do_locked_vfs_fn_t fn;
2787         void *private_data;
2788         const char *location;
2789         NTSTATUS status;
2790 };
2791
2792 static void share_mode_do_locked_vfs_denied_fn(struct g_lock_lock_cb_state *glck,
2793                                                void *cb_private)
2794 {
2795         struct share_mode_do_locked_vfs_denied_state *state =
2796                 (struct share_mode_do_locked_vfs_denied_state *)cb_private;
2797         struct smb_vfs_deny_state vfs_deny = {};
2798         struct share_mode_lock lck;
2799
2800         if (glck != NULL) {
2801                 current_share_mode_glck = glck;
2802         }
2803
2804         state->status = get_share_mode_lock_internal(state->id,
2805                                                      NULL,  /* servicepath */
2806                                                      NULL,  /* smb_fname */
2807                                                      NULL,  /* old_write_time */
2808                                                      &lck);
2809         if (!NT_STATUS_IS_OK(state->status)) {
2810                 DBG_GET_SHARE_MODE_LOCK(state->status,
2811                         "get_share_mode_lock_internal failed: %s\n",
2812                         nt_errstr(state->status));
2813                 if (glck != NULL) {
2814                         g_lock_lock_cb_unlock(glck);
2815                         current_share_mode_glck = NULL;
2816                 }
2817                 return;
2818         }
2819
2820         _smb_vfs_deny_push(&vfs_deny, state->location);
2821         state->fn(&lck, state->private_data);
2822         _smb_vfs_deny_pop(&vfs_deny, state->location);
2823
2824         state->status = put_share_mode_lock_internal(&lck);
2825         if (!NT_STATUS_IS_OK(state->status)) {
2826                 DBG_ERR("put_share_mode_lock_internal failed: %s\n",
2827                         nt_errstr(state->status));
2828                 smb_panic("put_share_mode_lock_internal failed\n");
2829                 return;
2830         }
2831
2832         if (glck != NULL) {
2833                 g_lock_lock_cb_unlock(glck);
2834                 current_share_mode_glck = NULL;
2835         }
2836         return;
2837 }
2838
2839 /**
2840  * @brief Run @fn protected with G_LOCK_WRITE in the given file_id
2841  *
2842  * @fn is NOT allowed to call SMB_VFS_* or similar functions,
2843  * which may block for some time in the kernel.
2844  *
2845  * There must be at least one share_mode_entry, otherwise
2846  * NT_STATUS_NOT_FOUND is returned.
2847  *
2848  * @param[in]  id           The key for the share_mode record.
2849  * @param[in]  fn           The function to run under the g_lock.
2850  * @param[in]  private_date A private pointer passed to @fn.
2851  */
2852 NTSTATUS _share_mode_do_locked_vfs_denied(
2853         struct file_id id,
2854         share_mode_do_locked_vfs_fn_t fn,
2855         void *private_data,
2856         const char *location)
2857 {
2858         struct share_mode_do_locked_vfs_denied_state state = {
2859                 .id = id,
2860                 .fn = fn,
2861                 .private_data = private_data,
2862                 .location = location,
2863         };
2864
2865         if (share_mode_lock_key_refcount == 0) {
2866                 TDB_DATA key = locking_key(&id);
2867                 NTSTATUS status;
2868
2869                 share_mode_lock_skip_g_lock = true;
2870                 status = g_lock_lock(
2871                         lock_ctx,
2872                         key,
2873                         G_LOCK_WRITE,
2874                         (struct timeval) { .tv_sec = 3600 },
2875                         share_mode_do_locked_vfs_denied_fn,
2876                         &state);
2877                 share_mode_lock_skip_g_lock = false;
2878                 if (!NT_STATUS_IS_OK(status)) {
2879                         DBG_DEBUG("g_lock_lock failed: %s\n",
2880                                   nt_errstr(status));
2881                         return status;
2882                 }
2883                 return state.status;
2884         }
2885
2886         share_mode_do_locked_vfs_denied_fn(NULL, &state);
2887
2888         return state.status;
2889 }
2890
2891 /**
2892  * @brief Run @fn protected with G_LOCK_WRITE in the given file_id
2893  *
2894  * @fn is allowed to call SMB_VFS_* or similar functions,
2895  * which may block for some time in the kernel.
2896  *
2897  * There must be at least one share_mode_entry, otherwise
2898  * NT_STATUS_NOT_FOUND is returned.
2899  *
2900  * @param[in]  id           The key for the share_mode record.
2901  * @param[in]  fn           The function to run under the g_lock.
2902  * @param[in]  private_date A private pointer passed to @fn.
2903  */
2904 NTSTATUS _share_mode_do_locked_vfs_allowed(
2905         struct file_id id,
2906         share_mode_do_locked_vfs_fn_t fn,
2907         void *private_data,
2908         const char *location)
2909 {
2910         struct share_mode_lock lck;
2911         NTSTATUS status;
2912
2913         smb_vfs_assert_allowed();
2914
2915         status = get_share_mode_lock_internal(id,
2916                                               NULL,  /* servicepath */
2917                                               NULL,  /* smb_fname */
2918                                               NULL,  /* old_write_time */
2919                                               &lck);
2920         if (!NT_STATUS_IS_OK(status)) {
2921                 DBG_GET_SHARE_MODE_LOCK(status,
2922                         "get_share_mode_lock_internal failed: %s\n",
2923                         nt_errstr(status));
2924                 return status;
2925         }
2926
2927         fn(&lck, private_data);
2928
2929         status = put_share_mode_lock_internal(&lck);
2930         if (!NT_STATUS_IS_OK(status)) {
2931                 DBG_ERR("put_share_mode_lock_internal failed: %s\n",
2932                         nt_errstr(status));
2933                 smb_panic("put_share_mode_lock_internal failed\n");
2934                 return status;
2935         }
2936
2937         return NT_STATUS_OK;
2938 }
2939
2940 struct share_mode_entry_prepare_lock_state {
2941         struct file_id id;
2942         const char *servicepath;
2943         const struct smb_filename *smb_fname;
2944         const struct timespec *old_write_time;
2945         share_mode_entry_prepare_lock_fn_t fn;
2946         void *private_data;
2947         const char *location;
2948         bool keep_locked;
2949         struct share_mode_lock *lck;
2950         NTSTATUS status;
2951 };
2952
2953 static void share_mode_entry_prepare_lock_fn(struct g_lock_lock_cb_state *glck,
2954                                              void *cb_private)
2955 {
2956         struct share_mode_entry_prepare_lock_state *state =
2957                 (struct share_mode_entry_prepare_lock_state *)cb_private;
2958         struct smb_vfs_deny_state vfs_deny = {};
2959
2960         SMB_ASSERT(glck != NULL);
2961         current_share_mode_glck = glck;
2962
2963         state->status = get_share_mode_lock_internal(state->id,
2964                                                      state->servicepath,
2965                                                      state->smb_fname,
2966                                                      state->old_write_time,
2967                                                      state->lck);
2968         if (!NT_STATUS_IS_OK(state->status)) {
2969                 /* no DBG_GET_SHARE_MODE_LOCK here! */
2970                 DBG_ERR("get_share_mode_lock_internal failed: %s\n",
2971                         nt_errstr(state->status));
2972                 g_lock_lock_cb_unlock(glck);
2973                 current_share_mode_glck = NULL;
2974                 return;
2975         }
2976
2977         _smb_vfs_deny_push(&vfs_deny, state->location);
2978         state->fn(state->lck, &state->keep_locked, state->private_data);
2979         _smb_vfs_deny_pop(&vfs_deny, state->location);
2980
2981         if (state->keep_locked) {
2982                 current_share_mode_glck = NULL;
2983                 return;
2984         }
2985
2986         state->status = put_share_mode_lock_internal(state->lck);
2987         if (!NT_STATUS_IS_OK(state->status)) {
2988                 DBG_ERR("put_share_mode_lock_internal failed: %s\n",
2989                         nt_errstr(state->status));
2990                 smb_panic("put_share_mode_lock_internal failed\n");
2991                 return;
2992         }
2993
2994         g_lock_lock_cb_unlock(glck);
2995         current_share_mode_glck = NULL;
2996         return;
2997 }
2998
2999 NTSTATUS _share_mode_entry_prepare_lock(
3000         struct share_mode_entry_prepare_state *prepare_state,
3001         struct file_id id,
3002         const char *servicepath,
3003         const struct smb_filename *smb_fname,
3004         const struct timespec *old_write_time,
3005         share_mode_entry_prepare_lock_fn_t fn,
3006         void *private_data,
3007         const char *location)
3008 {
3009         struct share_mode_entry_prepare_lock_state state = {
3010                 .id = id,
3011                 .servicepath = servicepath,
3012                 .smb_fname = smb_fname,
3013                 .old_write_time = old_write_time,
3014                 .fn = fn,
3015                 .private_data = private_data,
3016                 .location = location,
3017         };
3018         TDB_DATA key = locking_key(&id);
3019         NTSTATUS status;
3020
3021         SMB_ASSERT(share_mode_lock_key_refcount == 0);
3022
3023         SMB_ASSERT(__SHARE_MODE_LOCK_SPACE >= sizeof(struct share_mode_lock));
3024
3025         *prepare_state = (struct share_mode_entry_prepare_state) {
3026                 .__fid = id,
3027                 .__lck_ptr = &prepare_state->__lck_space,
3028         };
3029
3030         state.lck = prepare_state->__lck_ptr;
3031
3032         share_mode_lock_skip_g_lock = true;
3033         status = g_lock_lock(
3034                 lock_ctx,
3035                 key,
3036                 G_LOCK_WRITE,
3037                 (struct timeval) { .tv_sec = 3600 },
3038                 share_mode_entry_prepare_lock_fn,
3039                 &state);
3040         share_mode_lock_skip_g_lock = false;
3041         if (!state.keep_locked) {
3042                 prepare_state->__lck_ptr = NULL;
3043         }
3044         if (!NT_STATUS_IS_OK(status)) {
3045                 DBG_DEBUG("g_lock_lock failed: %s\n",
3046                           nt_errstr(status));
3047                 return status;
3048         }
3049
3050         return state.status;
3051 }
3052
3053 struct share_mode_entry_prepare_unlock_state {
3054         struct file_id id;
3055         share_mode_entry_prepare_unlock_fn_t fn;
3056         void *private_data;
3057         const char *location;
3058         struct share_mode_lock *lck;
3059         NTSTATUS status;
3060 };
3061
3062 static void share_mode_entry_prepare_unlock_existing_fn(
3063         struct share_mode_entry_prepare_unlock_state *state)
3064 {
3065         if (state->fn != NULL) {
3066                 struct smb_vfs_deny_state vfs_deny = {};
3067
3068                 _smb_vfs_deny_push(&vfs_deny, state->location);
3069                 state->fn(state->lck, state->private_data);
3070                 _smb_vfs_deny_pop(&vfs_deny, state->location);
3071         }
3072
3073         state->status = put_share_mode_lock_internal(state->lck);
3074         if (!NT_STATUS_IS_OK(state->status)) {
3075                 DBG_ERR("put_share_mode_lock_internal failed: %s\n",
3076                         nt_errstr(state->status));
3077                 smb_panic("put_share_mode_lock_internal failed\n");
3078                 return;
3079         }
3080
3081         return;
3082 }
3083
3084 static void share_mode_entry_prepare_unlock_relock_fn(struct g_lock_lock_cb_state *glck,
3085                                                       void *cb_private)
3086 {
3087         struct share_mode_entry_prepare_unlock_state *state =
3088                 (struct share_mode_entry_prepare_unlock_state *)cb_private;
3089         struct smb_vfs_deny_state vfs_deny = {};
3090
3091         SMB_ASSERT(glck != NULL);
3092         current_share_mode_glck = glck;
3093
3094         state->status = get_share_mode_lock_internal(state->id,
3095                                                      NULL,  /* servicepath */
3096                                                      NULL,  /* smb_fname */
3097                                                      NULL,  /* old_write_time */
3098                                                      state->lck);
3099         if (!NT_STATUS_IS_OK(state->status)) {
3100                 /* no DBG_GET_SHARE_MODE_LOCK here! */
3101                 DBG_ERR("get_share_mode_lock_internal failed: %s\n",
3102                         nt_errstr(state->status));
3103                 g_lock_lock_cb_unlock(glck);
3104                 current_share_mode_glck = NULL;
3105                 return;
3106         }
3107
3108         _smb_vfs_deny_push(&vfs_deny, state->location);
3109         state->fn(state->lck, state->private_data);
3110         _smb_vfs_deny_pop(&vfs_deny, state->location);
3111
3112         state->status = put_share_mode_lock_internal(state->lck);
3113         if (!NT_STATUS_IS_OK(state->status)) {
3114                 DBG_ERR("put_share_mode_lock_internal failed: %s\n",
3115                         nt_errstr(state->status));
3116                 smb_panic("put_share_mode_lock_internal failed\n");
3117                 return;
3118         }
3119
3120         g_lock_lock_cb_unlock(glck);
3121         current_share_mode_glck = NULL;
3122         return;
3123 }
3124
3125 NTSTATUS _share_mode_entry_prepare_unlock(
3126         struct share_mode_entry_prepare_state *prepare_state,
3127         share_mode_entry_prepare_unlock_fn_t fn,
3128         void *private_data,
3129         const char *location)
3130 {
3131         struct share_mode_entry_prepare_unlock_state state = {
3132                 .id = prepare_state->__fid,
3133                 .fn = fn,
3134                 .private_data = private_data,
3135                 .location = location,
3136         };
3137         TDB_DATA key = locking_key(&prepare_state->__fid);
3138         NTSTATUS status;
3139
3140         if (prepare_state->__lck_ptr != NULL) {
3141                 /*
3142                  * With an existing lock, we just run the unlock prepare
3143                  * function following by the unlock.
3144                  */
3145
3146                 SMB_ASSERT(share_mode_lock_key_refcount == 1);
3147
3148                 state.lck = prepare_state->__lck_ptr;
3149                 prepare_state->__lck_ptr = NULL;
3150
3151                 share_mode_entry_prepare_unlock_existing_fn(&state);
3152                 return state.status;
3153         }
3154
3155         /*
3156          * No existing lock, which means
3157          * _share_mode_entry_prepare_lock() didn't steal
3158          * the lock...
3159          */
3160         SMB_ASSERT(share_mode_lock_key_refcount == 0);
3161
3162         if (fn == NULL) {
3163                 /*
3164                  * Without an existing lock and without
3165                  * a prepare function there's nothing to
3166                  * do...
3167                  */
3168                 return NT_STATUS_OK;
3169         }
3170
3171         /*
3172          * In order to run the unlock prepare function
3173          * we need to relock the entry.
3174          */
3175         state.lck = &prepare_state->__lck_space;
3176
3177         share_mode_lock_skip_g_lock = true;
3178         status = g_lock_lock(
3179                 lock_ctx,
3180                 key,
3181                 G_LOCK_WRITE,
3182                 (struct timeval) { .tv_sec = 3600 },
3183                 share_mode_entry_prepare_unlock_relock_fn,
3184                 &state);
3185         share_mode_lock_skip_g_lock = false;
3186         if (!NT_STATUS_IS_OK(status)) {
3187                 DBG_ERR("g_lock_lock failed: %s\n",
3188                         nt_errstr(status));
3189                 return status;
3190         }
3191
3192         return state.status;
3193 }