smbd: Remove share_mode_lease and the leases array from share_mode_entry
[aaptel/samba-autobuild/.git] / source3 / locking / share_mode_lock.c
1 /*
2    Unix SMB/CIFS implementation.
3    Locking functions
4    Copyright (C) Andrew Tridgell 1992-2000
5    Copyright (C) Jeremy Allison 1992-2006
6    Copyright (C) Volker Lendecke 2005
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
21    Revision History:
22
23    12 aug 96: Erik.Devriendt@te6.siemens.be
24    added support for shared memory implementation of share mode locking
25
26    May 1997. Jeremy Allison (jallison@whistle.com). Modified share mode
27    locking to deal with multiple share modes per open file.
28
29    September 1997. Jeremy Allison (jallison@whistle.com). Added oplock
30    support.
31
32    rewritten completely to use new tdb code. Tridge, Dec '99
33
34    Added POSIX locking support. Jeremy Allison (jeremy@valinux.com), Apr. 2000.
35    Added Unix Extensions POSIX locking support. Jeremy Allison Mar 2006.
36 */
37
38 #include "includes.h"
39 #include "system/filesys.h"
40 #include "lib/util/server_id.h"
41 #include "locking/proto.h"
42 #include "smbd/globals.h"
43 #include "dbwrap/dbwrap.h"
44 #include "dbwrap/dbwrap_open.h"
45 #include "../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
63 static bool locking_init_internal(bool read_only)
64 {
65         struct db_context *backend;
66         char *db_path;
67
68         brl_init(read_only);
69
70         if (lock_db)
71                 return True;
72
73         db_path = lock_path(talloc_tos(), "locking.tdb");
74         if (db_path == NULL) {
75                 return false;
76         }
77
78         backend = db_open(NULL, db_path,
79                           SMB_OPEN_DATABASE_TDB_HASH_SIZE,
80                           TDB_DEFAULT|TDB_VOLATILE|TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH,
81                           read_only?O_RDONLY:O_RDWR|O_CREAT, 0644,
82                           DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE);
83         TALLOC_FREE(db_path);
84         if (!backend) {
85                 DEBUG(0,("ERROR: Failed to initialise locking database\n"));
86                 return False;
87         }
88
89         lock_db = db_open_watched(NULL, &backend, global_messaging_context());
90         if (lock_db == NULL) {
91                 DBG_ERR("db_open_watched failed\n");
92                 TALLOC_FREE(backend);
93                 return false;
94         }
95
96         if (!posix_locking_init(read_only)) {
97                 TALLOC_FREE(lock_db);
98                 return False;
99         }
100
101         return True;
102 }
103
104 bool locking_init(void)
105 {
106         return locking_init_internal(false);
107 }
108
109 bool locking_init_readonly(void)
110 {
111         return locking_init_internal(true);
112 }
113
114 /*******************************************************************
115  Deinitialize the share_mode management.
116 ******************************************************************/
117
118 bool locking_end(void)
119 {
120         brl_shutdown();
121         TALLOC_FREE(lock_db);
122         return true;
123 }
124
125 /*******************************************************************
126  Form a static locking key for a dev/inode pair.
127 ******************************************************************/
128
129 static TDB_DATA locking_key(const struct file_id *id)
130 {
131         return make_tdb_data((const uint8_t *)id, sizeof(*id));
132 }
133
134 /*******************************************************************
135  Share mode cache utility functions that store/delete/retrieve
136  entries from memcache.
137
138  For now share the statcache (global cache) memory space. If
139  a lock record gets orphaned (which shouldn't happen as we're
140  using the same locking_key data as lookup) it will eventually
141  fall out of the cache via the normal LRU trim mechanism. If
142  necessary we can always make this a separate (smaller) cache.
143 ******************************************************************/
144
145 static DATA_BLOB memcache_key(const struct file_id *id)
146 {
147         return data_blob_const((const void *)id, sizeof(*id));
148 }
149
150 static void share_mode_memcache_delete(struct share_mode_data *d)
151 {
152         const DATA_BLOB key = memcache_key(&d->id);
153
154         DBG_DEBUG("deleting entry for file %s seq %"PRIx64" key %s\n",
155                   d->base_name,
156                   d->sequence_number,
157                   file_id_string(talloc_tos(), &d->id));
158
159         memcache_delete(NULL,
160                         SHARE_MODE_LOCK_CACHE,
161                         key);
162 }
163
164 static void share_mode_memcache_store(struct share_mode_data *d)
165 {
166         const DATA_BLOB key = memcache_key(&d->id);
167
168         DBG_DEBUG("stored entry for file %s seq %"PRIx64" key %s\n",
169                   d->base_name,
170                   d->sequence_number,
171                   file_id_string(talloc_tos(), &d->id));
172
173         /* Ensure everything stored in the cache is pristine. */
174         d->modified = false;
175         d->fresh = false;
176
177         /*
178          * Ensure the memory going into the cache
179          * doesn't have a destructor so it can be
180          * cleanly freed by share_mode_memcache_delete().
181          */
182         talloc_set_destructor(d, NULL);
183
184         /* Cache will own d after this call. */
185         memcache_add_talloc(NULL,
186                         SHARE_MODE_LOCK_CACHE,
187                         key,
188                         &d);
189 }
190
191 /*
192  * NB. We use ndr_pull_hyper on a stack-created
193  * struct ndr_pull with no talloc allowed, as we
194  * need this to be really fast as an ndr-peek into
195  * the first 8 bytes of the blob.
196  */
197
198 static enum ndr_err_code get_blob_sequence_number(DATA_BLOB *blob,
199                                                 uint64_t *pseq)
200 {
201         struct ndr_pull ndr = {.data = blob->data, .data_size = blob->length};
202         NDR_CHECK(ndr_pull_hyper(&ndr, NDR_SCALARS, pseq));
203         return NDR_ERR_SUCCESS;
204 }
205
206 static int share_mode_data_nofree_destructor(struct share_mode_data *d)
207 {
208         return -1;
209 }
210
211 static struct share_mode_data *share_mode_memcache_fetch(TALLOC_CTX *mem_ctx,
212                                         const TDB_DATA id_key,
213                                         DATA_BLOB *blob)
214 {
215         enum ndr_err_code ndr_err;
216         struct share_mode_data *d;
217         uint64_t sequence_number;
218         void *ptr;
219         struct file_id id;
220         DATA_BLOB key;
221
222         /* Ensure this is a locking_key record. */
223         if (id_key.dsize != sizeof(id)) {
224                 return NULL;
225         }
226
227         memcpy(&id, id_key.dptr, id_key.dsize);
228         key = memcache_key(&id);
229
230         ptr = memcache_lookup_talloc(NULL,
231                         SHARE_MODE_LOCK_CACHE,
232                         key);
233         if (ptr == NULL) {
234                 DEBUG(10,("failed to find entry for key %s\n",
235                         file_id_string(mem_ctx, &id)));
236                 return NULL;
237         }
238         /* sequence number key is at start of blob. */
239         ndr_err = get_blob_sequence_number(blob, &sequence_number);
240         if (ndr_err != NDR_ERR_SUCCESS) {
241                 /* Bad blob. Remove entry. */
242                 DEBUG(10,("bad blob %u key %s\n",
243                         (unsigned int)ndr_err,
244                         file_id_string(mem_ctx, &id)));
245                 memcache_delete(NULL,
246                         SHARE_MODE_LOCK_CACHE,
247                         key);
248                 return NULL;
249         }
250
251         d = (struct share_mode_data *)ptr;
252         if (d->sequence_number != sequence_number) {
253                 DBG_DEBUG("seq changed (cached %"PRIx64") (new %"PRIx64") "
254                           "for key %s\n",
255                           d->sequence_number,
256                           sequence_number,
257                           file_id_string(mem_ctx, &id));
258                 /* Cache out of date. Remove entry. */
259                 memcache_delete(NULL,
260                         SHARE_MODE_LOCK_CACHE,
261                         key);
262                 return NULL;
263         }
264
265         /* Move onto mem_ctx. */
266         d = talloc_move(mem_ctx, &ptr);
267
268         /*
269          * Now we own d, prevent the cache from freeing it
270          * when we delete the entry.
271          */
272         talloc_set_destructor(d, share_mode_data_nofree_destructor);
273
274         /* Remove from the cache. We own it now. */
275         memcache_delete(NULL,
276                         SHARE_MODE_LOCK_CACHE,
277                         key);
278
279         /* And reset the destructor to none. */
280         talloc_set_destructor(d, NULL);
281
282         DBG_DEBUG("fetched entry for file %s seq %"PRIx64" key %s\n",
283                   d->base_name,
284                   d->sequence_number,
285                   file_id_string(mem_ctx, &id));
286
287         return d;
288 }
289
290 /*******************************************************************
291  Get all share mode entries for a dev/inode pair.
292 ********************************************************************/
293
294 static struct share_mode_data *parse_share_modes(TALLOC_CTX *mem_ctx,
295                                                 const TDB_DATA key,
296                                                 const TDB_DATA dbuf)
297 {
298         struct share_mode_data *d;
299         enum ndr_err_code ndr_err;
300         DATA_BLOB blob;
301
302         blob.data = dbuf.dptr;
303         blob.length = dbuf.dsize;
304
305         /* See if we already have a cached copy of this key. */
306         d = share_mode_memcache_fetch(mem_ctx, key, &blob);
307         if (d != NULL) {
308                 return d;
309         }
310
311         d = talloc(mem_ctx, struct share_mode_data);
312         if (d == NULL) {
313                 DEBUG(0, ("talloc failed\n"));
314                 goto fail;
315         }
316
317         ndr_err = ndr_pull_struct_blob_all(
318                 &blob, d, d, (ndr_pull_flags_fn_t)ndr_pull_share_mode_data);
319         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
320                 DEBUG(1, ("ndr_pull_share_mode_lock failed: %s\n",
321                           ndr_errstr(ndr_err)));
322                 goto fail;
323         }
324
325         if (DEBUGLEVEL >= 10) {
326                 DEBUG(10, ("parse_share_modes:\n"));
327                 NDR_PRINT_DEBUG(share_mode_data, d);
328         }
329
330         return d;
331 fail:
332         TALLOC_FREE(d);
333         return NULL;
334 }
335
336 /*******************************************************************
337  Create a storable data blob from a modified share_mode_data struct.
338 ********************************************************************/
339
340 static TDB_DATA unparse_share_modes(struct share_mode_data *d)
341 {
342         DATA_BLOB blob;
343         enum ndr_err_code ndr_err;
344
345         if (DEBUGLEVEL >= 10) {
346                 DEBUG(10, ("unparse_share_modes:\n"));
347                 NDR_PRINT_DEBUG(share_mode_data, d);
348         }
349
350         share_mode_memcache_delete(d);
351
352         /* Update the sequence number. */
353         d->sequence_number += 1;
354
355         remove_stale_share_mode_entries(d);
356
357         if (d->num_share_modes == 0) {
358                 DEBUG(10, ("No used share mode found\n"));
359                 return make_tdb_data(NULL, 0);
360         }
361
362         ndr_err = ndr_push_struct_blob(
363                 &blob, d, d, (ndr_push_flags_fn_t)ndr_push_share_mode_data);
364         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
365                 smb_panic("ndr_push_share_mode_lock failed");
366         }
367
368         return make_tdb_data(blob.data, blob.length);
369 }
370
371 /*******************************************************************
372  If modified, store the share_mode_data back into the database.
373 ********************************************************************/
374
375 static int share_mode_data_destructor(struct share_mode_data *d)
376 {
377         NTSTATUS status;
378         TDB_DATA data;
379
380         if (!d->modified) {
381                 return 0;
382         }
383
384         data = unparse_share_modes(d);
385
386         if (data.dptr == NULL) {
387                 if (!d->fresh) {
388                         /* There has been an entry before, delete it */
389
390                         status = dbwrap_record_delete(d->record);
391                         if (!NT_STATUS_IS_OK(status)) {
392                                 char *errmsg;
393
394                                 DEBUG(0, ("delete_rec returned %s\n",
395                                           nt_errstr(status)));
396
397                                 if (asprintf(&errmsg, "could not delete share "
398                                              "entry: %s\n",
399                                              nt_errstr(status)) == -1) {
400                                         smb_panic("could not delete share"
401                                                   "entry");
402                                 }
403                                 smb_panic(errmsg);
404                         }
405                 }
406                 /*
407                  * Nothing to store in cache - allow the normal
408                  * release of record lock and memory free.
409                  */
410                 return 0;
411         }
412
413         status = dbwrap_record_store(d->record, data, TDB_REPLACE);
414         if (!NT_STATUS_IS_OK(status)) {
415                 char *errmsg;
416
417                 DEBUG(0, ("store returned %s\n", nt_errstr(status)));
418
419                 if (asprintf(&errmsg, "could not store share mode entry: %s",
420                              nt_errstr(status)) == -1) {
421                         smb_panic("could not store share mode entry");
422                 }
423                 smb_panic(errmsg);
424         }
425
426         /*
427          * Release the record lock before putting in the cache.
428          */
429         TALLOC_FREE(d->record);
430
431         /*
432          * Release the dptr as well before reparenting to NULL
433          * (in-memory cache) context.
434          */
435         TALLOC_FREE(data.dptr);
436         /*
437          * Reparent d into the in-memory cache so it can be reused if the
438          * sequence number matches. See parse_share_modes()
439          * for details.
440          */
441
442         share_mode_memcache_store(d);
443         return -1;
444 }
445
446 /*******************************************************************
447  Allocate a new share_mode_data struct, mark it unmodified.
448  fresh is set to note that currently there is no database entry.
449 ********************************************************************/
450
451 static struct share_mode_data *fresh_share_mode_lock(
452         TALLOC_CTX *mem_ctx, const char *servicepath,
453         const struct smb_filename *smb_fname,
454         const struct timespec *old_write_time)
455 {
456         struct share_mode_data *d;
457
458         if ((servicepath == NULL) || (smb_fname == NULL) ||
459             (old_write_time == NULL)) {
460                 return NULL;
461         }
462
463         d = talloc_zero(mem_ctx, struct share_mode_data);
464         if (d == NULL) {
465                 goto fail;
466         }
467         /* New record - new sequence number. */
468         generate_random_buffer((uint8_t *)&d->sequence_number, 8);
469
470         d->base_name = talloc_strdup(d, smb_fname->base_name);
471         if (d->base_name == NULL) {
472                 goto fail;
473         }
474         if (smb_fname->stream_name != NULL) {
475                 d->stream_name = talloc_strdup(d, smb_fname->stream_name);
476                 if (d->stream_name == NULL) {
477                         goto fail;
478                 }
479         }
480         d->servicepath = talloc_strdup(d, servicepath);
481         if (d->servicepath == NULL) {
482                 goto fail;
483         }
484         d->old_write_time = *old_write_time;
485         d->modified = false;
486         d->fresh = true;
487         return d;
488 fail:
489         DEBUG(0, ("talloc failed\n"));
490         TALLOC_FREE(d);
491         return NULL;
492 }
493
494 /*******************************************************************
495  Either fetch a share mode from the database, or allocate a fresh
496  one if the record doesn't exist.
497 ********************************************************************/
498
499 static struct share_mode_lock *get_share_mode_lock_internal(
500         TALLOC_CTX *mem_ctx, struct file_id id,
501         const char *servicepath, const struct smb_filename *smb_fname,
502         const struct timespec *old_write_time)
503 {
504         struct share_mode_lock *lck;
505         struct share_mode_data *d;
506         struct db_record *rec;
507         TDB_DATA key = locking_key(&id);
508         TDB_DATA value;
509
510         rec = dbwrap_fetch_locked(lock_db, mem_ctx, key);
511         if (rec == NULL) {
512                 DEBUG(3, ("Could not lock share entry\n"));
513                 return NULL;
514         }
515
516         value = dbwrap_record_get_value(rec);
517
518         if (value.dptr == NULL) {
519                 d = fresh_share_mode_lock(mem_ctx, servicepath, smb_fname,
520                                           old_write_time);
521         } else {
522                 d = parse_share_modes(mem_ctx, key, value);
523         }
524
525         if (d == NULL) {
526                 DEBUG(5, ("get_share_mode_lock_internal: "
527                         "Could not get share mode lock\n"));
528                 TALLOC_FREE(rec);
529                 return NULL;
530         }
531         d->id = id;
532         d->record = talloc_move(d, &rec);
533         talloc_set_destructor(d, share_mode_data_destructor);
534
535         lck = talloc(mem_ctx, struct share_mode_lock);
536         if (lck == NULL) {
537                 DEBUG(1, ("talloc failed\n"));
538                 TALLOC_FREE(d);
539                 return NULL;
540         }
541         lck->data = talloc_move(lck, &d);
542         return lck;
543 }
544
545 /*
546  * We can only ever have one share mode locked. Users of
547  * get_share_mode_lock never see this, it will be refcounted by
548  * talloc_reference.
549  */
550 static struct share_mode_lock *the_lock;
551
552 static int the_lock_destructor(struct share_mode_lock *l)
553 {
554         the_lock = NULL;
555         return 0;
556 }
557
558 /*******************************************************************
559  Get a share_mode_lock, Reference counted to allow nested calls.
560 ********************************************************************/
561
562 struct share_mode_lock *get_share_mode_lock(
563         TALLOC_CTX *mem_ctx,
564         struct file_id id,
565         const char *servicepath,
566         const struct smb_filename *smb_fname,
567         const struct timespec *old_write_time)
568 {
569         struct share_mode_lock *lck;
570
571         lck = talloc(mem_ctx, struct share_mode_lock);
572         if (lck == NULL) {
573                 DEBUG(1, ("talloc failed\n"));
574                 return NULL;
575         }
576
577         if (the_lock == NULL) {
578                 the_lock = get_share_mode_lock_internal(
579                         lck, id, servicepath, smb_fname, old_write_time);
580                 if (the_lock == NULL) {
581                         goto fail;
582                 }
583                 talloc_set_destructor(the_lock, the_lock_destructor);
584         } else {
585                 if (!file_id_equal(&the_lock->data->id, &id)) {
586                         DEBUG(1, ("Can not lock two share modes "
587                                   "simultaneously\n"));
588                         goto fail;
589                 }
590                 if (talloc_reference(lck, the_lock) == NULL) {
591                         DEBUG(1, ("talloc_reference failed\n"));
592                         goto fail;
593                 }
594         }
595         lck->data = the_lock->data;
596         return lck;
597 fail:
598         TALLOC_FREE(lck);
599         return NULL;
600 }
601
602 struct fetch_share_mode_unlocked_state {
603         TALLOC_CTX *mem_ctx;
604         struct share_mode_lock *lck;
605 };
606
607 static void fetch_share_mode_unlocked_parser(
608         TDB_DATA key, TDB_DATA data, void *private_data)
609 {
610         struct fetch_share_mode_unlocked_state *state = private_data;
611
612         if (data.dsize == 0) {
613                 /* Likely a ctdb tombstone record, ignore it */
614                 return;
615         }
616
617         state->lck = talloc(state->mem_ctx, struct share_mode_lock);
618         if (state->lck == NULL) {
619                 DEBUG(0, ("talloc failed\n"));
620                 return;
621         }
622
623         state->lck->data = parse_share_modes(state->lck, key, data);
624 }
625
626 /*******************************************************************
627  Get a share_mode_lock without locking the database or reference
628  counting. Used by smbstatus to display existing share modes.
629 ********************************************************************/
630
631 struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx,
632                                                   struct file_id id)
633 {
634         struct fetch_share_mode_unlocked_state state = { .mem_ctx = mem_ctx };
635         TDB_DATA key = locking_key(&id);
636         NTSTATUS status;
637
638         status = dbwrap_parse_record(
639                 lock_db, key, fetch_share_mode_unlocked_parser, &state);
640         if (!NT_STATUS_IS_OK(status)) {
641                 return NULL;
642         }
643         return state.lck;
644 }
645
646 static void fetch_share_mode_done(struct tevent_req *subreq);
647
648 struct fetch_share_mode_state {
649         struct file_id id;
650         TDB_DATA key;
651         struct fetch_share_mode_unlocked_state parser_state;
652         enum dbwrap_req_state req_state;
653 };
654
655 /**
656  * @brief Get a share_mode_lock without locking or refcounting
657  *
658  * This can be used in a clustered Samba environment where the async dbwrap
659  * request is sent over a socket to the local ctdbd. If the send queue is full
660  * and the caller was issuing multiple async dbwrap requests in a loop, the
661  * caller knows it's probably time to stop sending requests for now and try
662  * again later.
663  *
664  * @param[in]  mem_ctx The talloc memory context to use.
665  *
666  * @param[in]  ev      The event context to work on.
667  *
668  * @param[in]  id      The file id for the locking.tdb key
669  *
670  * @param[out] queued  This boolean out parameter tells the caller whether the
671  *                     async request is blocked in a full send queue:
672  *
673  *                     false := request is dispatched
674  *
675  *                     true  := send queue is full, request waiting to be
676  *                              dispatched
677  *
678  * @return             The new async request, NULL on error.
679  **/
680 struct tevent_req *fetch_share_mode_send(TALLOC_CTX *mem_ctx,
681                                          struct tevent_context *ev,
682                                          struct file_id id,
683                                          bool *queued)
684 {
685         struct tevent_req *req = NULL;
686         struct fetch_share_mode_state *state = NULL;
687         struct tevent_req *subreq = NULL;
688
689         *queued = false;
690
691         req = tevent_req_create(mem_ctx, &state,
692                                 struct fetch_share_mode_state);
693         if (req == NULL) {
694                 return NULL;
695         }
696
697         state->id = id;
698         state->key = locking_key(&state->id);
699         state->parser_state.mem_ctx = state;
700
701         subreq = dbwrap_parse_record_send(state,
702                                           ev,
703                                           lock_db,
704                                           state->key,
705                                           fetch_share_mode_unlocked_parser,
706                                           &state->parser_state,
707                                           &state->req_state);
708         if (tevent_req_nomem(subreq, req)) {
709                 return tevent_req_post(req, ev);
710         }
711         tevent_req_set_callback(subreq, fetch_share_mode_done, req);
712
713         if (state->req_state < DBWRAP_REQ_DISPATCHED) {
714                 *queued = true;
715         }
716         return req;
717 }
718
719 static void fetch_share_mode_done(struct tevent_req *subreq)
720 {
721         struct tevent_req *req = tevent_req_callback_data(
722                 subreq, struct tevent_req);
723         NTSTATUS status;
724
725         status = dbwrap_parse_record_recv(subreq);
726         TALLOC_FREE(subreq);
727         if (tevent_req_nterror(req, status)) {
728                 return;
729         }
730
731         tevent_req_done(req);
732         return;
733 }
734
735 NTSTATUS fetch_share_mode_recv(struct tevent_req *req,
736                                TALLOC_CTX *mem_ctx,
737                                struct share_mode_lock **_lck)
738 {
739         struct fetch_share_mode_state *state = tevent_req_data(
740                 req, struct fetch_share_mode_state);
741         struct share_mode_lock *lck = NULL;
742
743         NTSTATUS status;
744
745         if (tevent_req_is_nterror(req, &status)) {
746                 tevent_req_received(req);
747                 return status;
748         }
749
750         if (state->parser_state.lck->data == NULL) {
751                 tevent_req_received(req);
752                 return NT_STATUS_NOT_FOUND;
753         }
754
755         lck = talloc_move(mem_ctx, &state->parser_state.lck);
756
757         if (DEBUGLEVEL >= 10) {
758                 DBG_DEBUG("share_mode_data:\n");
759                 NDR_PRINT_DEBUG(share_mode_data, lck->data);
760         }
761
762         *_lck = lck;
763         tevent_req_received(req);
764         return NT_STATUS_OK;
765 }
766
767 struct share_mode_forall_state {
768         int (*fn)(struct file_id fid, const struct share_mode_data *data,
769                   void *private_data);
770         void *private_data;
771 };
772
773 static int share_mode_traverse_fn(struct db_record *rec, void *_state)
774 {
775         struct share_mode_forall_state *state =
776                 (struct share_mode_forall_state *)_state;
777         TDB_DATA key;
778         TDB_DATA value;
779         DATA_BLOB blob;
780         enum ndr_err_code ndr_err;
781         struct share_mode_data *d;
782         struct file_id fid;
783         int ret;
784
785         key = dbwrap_record_get_key(rec);
786         value = dbwrap_record_get_value(rec);
787
788         /* Ensure this is a locking_key record. */
789         if (key.dsize != sizeof(fid)) {
790                 return 0;
791         }
792         memcpy(&fid, key.dptr, sizeof(fid));
793
794         d = talloc(talloc_tos(), struct share_mode_data);
795         if (d == NULL) {
796                 return 0;
797         }
798
799         blob.data = value.dptr;
800         blob.length = value.dsize;
801
802         ndr_err = ndr_pull_struct_blob_all(
803                 &blob, d, d, (ndr_pull_flags_fn_t)ndr_pull_share_mode_data);
804         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
805                 DEBUG(1, ("ndr_pull_share_mode_lock failed\n"));
806                 return 0;
807         }
808
809         if (DEBUGLEVEL > 10) {
810                 DEBUG(11, ("parse_share_modes:\n"));
811                 NDR_PRINT_DEBUG(share_mode_data, d);
812         }
813
814         ret = state->fn(fid, d, state->private_data);
815
816         TALLOC_FREE(d);
817         return ret;
818 }
819
820 int share_mode_forall(int (*fn)(struct file_id fid,
821                                 const struct share_mode_data *data,
822                                 void *private_data),
823                       void *private_data)
824 {
825         struct share_mode_forall_state state = {
826                 .fn = fn,
827                 .private_data = private_data
828         };
829         NTSTATUS status;
830         int count;
831
832         if (lock_db == NULL) {
833                 return 0;
834         }
835
836         status = dbwrap_traverse_read(lock_db, share_mode_traverse_fn,
837                                       &state, &count);
838         if (!NT_STATUS_IS_OK(status)) {
839                 return -1;
840         }
841
842         return count;
843 }
844
845 struct share_entry_forall_state {
846         int (*fn)(struct file_id fid,
847                   const struct share_mode_data *data,
848                   const struct share_mode_entry *entry,
849                   void *private_data);
850         void *private_data;
851 };
852
853 static int share_entry_traverse_fn(struct file_id fid,
854                                    const struct share_mode_data *data,
855                                    void *private_data)
856 {
857         struct share_entry_forall_state *state = private_data;
858         uint32_t i;
859
860         for (i=0; i<data->num_share_modes; i++) {
861                 int ret;
862
863                 ret = state->fn(fid,
864                                 data,
865                                 &data->share_modes[i],
866                                 state->private_data);
867                 if (ret != 0) {
868                         return ret;
869                 }
870         }
871
872         return 0;
873 }
874
875 /*******************************************************************
876  Call the specified function on each entry under management by the
877  share mode system.
878 ********************************************************************/
879
880 int share_entry_forall(int (*fn)(struct file_id fid,
881                                  const struct share_mode_data *data,
882                                  const struct share_mode_entry *entry,
883                                  void *private_data),
884                       void *private_data)
885 {
886         struct share_entry_forall_state state = {
887                 .fn = fn, .private_data = private_data };
888
889         return share_mode_forall(share_entry_traverse_fn, &state);
890 }
891
892 static bool cleanup_disconnected_lease(struct share_mode_lock *lck,
893                                        struct share_mode_entry *e,
894                                        void *private_data)
895 {
896         struct share_mode_data *d = lck->data;
897         NTSTATUS status;
898
899         status = leases_db_del(&e->client_guid, &e->lease_key, &d->id);
900
901         if (!NT_STATUS_IS_OK(status)) {
902                 DBG_DEBUG("leases_db_del failed: %s\n",
903                           nt_errstr(status));
904         }
905
906         return false;
907 }
908
909 bool share_mode_cleanup_disconnected(struct file_id fid,
910                                      uint64_t open_persistent_id)
911 {
912         bool ret = false;
913         TALLOC_CTX *frame = talloc_stackframe();
914         unsigned n;
915         struct share_mode_data *data;
916         struct share_mode_lock *lck;
917         bool ok;
918
919         lck = get_existing_share_mode_lock(frame, fid);
920         if (lck == NULL) {
921                 DEBUG(5, ("share_mode_cleanup_disconnected: "
922                           "Could not fetch share mode entry for %s\n",
923                           file_id_string(frame, &fid)));
924                 goto done;
925         }
926         data = lck->data;
927
928         for (n=0; n < data->num_share_modes; n++) {
929                 struct share_mode_entry *entry = &data->share_modes[n];
930
931                 if (!server_id_is_disconnected(&entry->pid)) {
932                         struct server_id_buf tmp;
933                         DEBUG(5, ("share_mode_cleanup_disconnected: "
934                                   "file (file-id='%s', servicepath='%s', "
935                                   "base_name='%s%s%s') "
936                                   "is used by server %s ==> do not cleanup\n",
937                                   file_id_string(frame, &fid),
938                                   data->servicepath,
939                                   data->base_name,
940                                   (data->stream_name == NULL)
941                                   ? "" : "', stream_name='",
942                                   (data->stream_name == NULL)
943                                   ? "" : data->stream_name,
944                                   server_id_str_buf(entry->pid, &tmp)));
945                         goto done;
946                 }
947                 if (open_persistent_id != entry->share_file_id) {
948                         DBG_INFO("entry for file "
949                                  "(file-id='%s', servicepath='%s', "
950                                  "base_name='%s%s%s') "
951                                  "has share_file_id %"PRIu64" but expected "
952                                  "%"PRIu64"==> do not cleanup\n",
953                                  file_id_string(frame, &fid),
954                                  data->servicepath,
955                                  data->base_name,
956                                  (data->stream_name == NULL)
957                                  ? "" : "', stream_name='",
958                                  (data->stream_name == NULL)
959                                  ? "" : data->stream_name,
960                                  entry->share_file_id,
961                                  open_persistent_id);
962                         goto done;
963                 }
964         }
965
966         ok = share_mode_forall_leases(lck, cleanup_disconnected_lease, NULL);
967         if (!ok) {
968                 DBG_DEBUG("failed to clean up leases associated "
969                           "with file (file-id='%s', servicepath='%s', "
970                           "base_name='%s%s%s') and open_persistent_id %"PRIu64" "
971                           "==> do not cleanup\n",
972                           file_id_string(frame, &fid),
973                           data->servicepath,
974                           data->base_name,
975                           (data->stream_name == NULL)
976                           ? "" : "', stream_name='",
977                           (data->stream_name == NULL)
978                           ? "" : data->stream_name,
979                           open_persistent_id);
980         }
981
982         ok = brl_cleanup_disconnected(fid, open_persistent_id);
983         if (!ok) {
984                 DBG_DEBUG("failed to clean up byte range locks associated "
985                           "with file (file-id='%s', servicepath='%s', "
986                           "base_name='%s%s%s') and open_persistent_id %"PRIu64" "
987                           "==> do not cleanup\n",
988                           file_id_string(frame, &fid),
989                           data->servicepath,
990                           data->base_name,
991                           (data->stream_name == NULL)
992                           ? "" : "', stream_name='",
993                           (data->stream_name == NULL)
994                           ? "" : data->stream_name,
995                           open_persistent_id);
996                 goto done;
997         }
998
999         DBG_DEBUG("cleaning up %u entries for file "
1000                   "(file-id='%s', servicepath='%s', "
1001                   "base_name='%s%s%s') "
1002                   "from open_persistent_id %"PRIu64"\n",
1003                   data->num_share_modes,
1004                   file_id_string(frame, &fid),
1005                   data->servicepath,
1006                   data->base_name,
1007                   (data->stream_name == NULL)
1008                   ? "" : "', stream_name='",
1009                   (data->stream_name == NULL)
1010                   ? "" : data->stream_name,
1011                   open_persistent_id);
1012
1013         data->num_share_modes = 0;
1014         data->modified = true;
1015
1016         ret = true;
1017 done:
1018         talloc_free(frame);
1019         return ret;
1020 }