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