2e400ac8ef0e7b6468f553173018deee9cd9ca45
[ira/wip.git] / source3 / locking / locking.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Locking functions
4    Copyright (C) Andrew Tridgell 1992-2000
5    Copyright (C) Jeremy Allison 1992-2006
6    Copyright (C) Volker Lendecke 2005
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
21    Revision History:
22
23    12 aug 96: Erik.Devriendt@te6.siemens.be
24    added support for shared memory implementation of share mode locking
25
26    May 1997. Jeremy Allison (jallison@whistle.com). Modified share mode
27    locking to deal with multiple share modes per open file.
28
29    September 1997. Jeremy Allison (jallison@whistle.com). Added oplock
30    support.
31
32    rewritten completely to use new tdb code. Tridge, Dec '99
33
34    Added POSIX locking support. Jeremy Allison (jeremy@valinux.com), Apr. 2000.
35    Added Unix Extensions POSIX locking support. Jeremy Allison Mar 2006.
36 */
37
38 #include "includes.h"
39 #include "system/filesys.h"
40 #include "locking/proto.h"
41 #include "smbd/globals.h"
42 #include "dbwrap/dbwrap.h"
43 #include "dbwrap/dbwrap_open.h"
44 #include "../libcli/security/security.h"
45 #include "serverid.h"
46 #include "messages.h"
47 #include "util_tdb.h"
48 #include "../librpc/gen_ndr/ndr_open_files.h"
49
50 #undef DBGC_CLASS
51 #define DBGC_CLASS DBGC_LOCKING
52
53 #define NO_LOCKING_COUNT (-1)
54
55 /* the locking database handle */
56 static struct db_context *lock_db;
57
58 /****************************************************************************
59  Debugging aids :-).
60 ****************************************************************************/
61
62 const char *lock_type_name(enum brl_type lock_type)
63 {
64         switch (lock_type) {
65                 case READ_LOCK:
66                         return "READ";
67                 case WRITE_LOCK:
68                         return "WRITE";
69                 case PENDING_READ_LOCK:
70                         return "PENDING_READ";
71                 case PENDING_WRITE_LOCK:
72                         return "PENDING_WRITE";
73                 default:
74                         return "other";
75         }
76 }
77
78 const char *lock_flav_name(enum brl_flavour lock_flav)
79 {
80         return (lock_flav == WINDOWS_LOCK) ? "WINDOWS_LOCK" : "POSIX_LOCK";
81 }
82
83 /****************************************************************************
84  Utility function called to see if a file region is locked.
85  Called in the read/write codepath.
86 ****************************************************************************/
87
88 void init_strict_lock_struct(files_struct *fsp,
89                                 uint64_t smblctx,
90                                 br_off start,
91                                 br_off size,
92                                 enum brl_type lock_type,
93                                 struct lock_struct *plock)
94 {
95         SMB_ASSERT(lock_type == READ_LOCK || lock_type == WRITE_LOCK);
96
97         plock->context.smblctx = smblctx;
98         plock->context.tid = fsp->conn->cnum;
99         plock->context.pid = messaging_server_id(fsp->conn->sconn->msg_ctx);
100         plock->start = start;
101         plock->size = size;
102         plock->fnum = fsp->fnum;
103         plock->lock_type = lock_type;
104         plock->lock_flav = lp_posix_cifsu_locktype(fsp);
105 }
106
107 bool strict_lock_default(files_struct *fsp, struct lock_struct *plock)
108 {
109         int strict_locking = lp_strict_locking(fsp->conn->params);
110         bool ret = False;
111
112         if (plock->size == 0) {
113                 return True;
114         }
115
116         if (!lp_locking(fsp->conn->params) || !strict_locking) {
117                 return True;
118         }
119
120         if (strict_locking == Auto) {
121                 if  (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (plock->lock_type == READ_LOCK || plock->lock_type == WRITE_LOCK)) {
122                         DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp_str_dbg(fsp)));
123                         ret = True;
124                 } else if ((fsp->oplock_type == LEVEL_II_OPLOCK) &&
125                            (plock->lock_type == READ_LOCK)) {
126                         DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp_str_dbg(fsp)));
127                         ret = True;
128                 } else {
129                         struct byte_range_lock *br_lck;
130
131                         br_lck = brl_get_locks_readonly(fsp);
132                         if (!br_lck) {
133                                 return True;
134                         }
135                         ret = brl_locktest(br_lck,
136                                         plock->context.smblctx,
137                                         plock->context.pid,
138                                         plock->start,
139                                         plock->size,
140                                         plock->lock_type,
141                                         plock->lock_flav);
142                 }
143         } else {
144                 struct byte_range_lock *br_lck;
145
146                 br_lck = brl_get_locks_readonly(fsp);
147                 if (!br_lck) {
148                         return True;
149                 }
150                 ret = brl_locktest(br_lck,
151                                 plock->context.smblctx,
152                                 plock->context.pid,
153                                 plock->start,
154                                 plock->size,
155                                 plock->lock_type,
156                                 plock->lock_flav);
157         }
158
159         DEBUG(10,("strict_lock_default: flavour = %s brl start=%.0f "
160                         "len=%.0f %s for fnum %d file %s\n",
161                         lock_flav_name(plock->lock_flav),
162                         (double)plock->start, (double)plock->size,
163                         ret ? "unlocked" : "locked",
164                         plock->fnum, fsp_str_dbg(fsp)));
165
166         return ret;
167 }
168
169 void strict_unlock_default(files_struct *fsp, struct lock_struct *plock)
170 {
171 }
172
173 /****************************************************************************
174  Find out if a lock could be granted - return who is blocking us if we can't.
175 ****************************************************************************/
176
177 NTSTATUS query_lock(files_struct *fsp,
178                         uint64_t *psmblctx,
179                         uint64_t *pcount,
180                         uint64_t *poffset,
181                         enum brl_type *plock_type,
182                         enum brl_flavour lock_flav)
183 {
184         struct byte_range_lock *br_lck = NULL;
185
186         if (!fsp->can_lock) {
187                 return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
188         }
189
190         if (!lp_locking(fsp->conn->params)) {
191                 return NT_STATUS_OK;
192         }
193
194         br_lck = brl_get_locks_readonly(fsp);
195         if (!br_lck) {
196                 return NT_STATUS_NO_MEMORY;
197         }
198
199         return brl_lockquery(br_lck,
200                         psmblctx,
201                         messaging_server_id(fsp->conn->sconn->msg_ctx),
202                         poffset,
203                         pcount,
204                         plock_type,
205                         lock_flav);
206 }
207
208 static void increment_current_lock_count(files_struct *fsp,
209     enum brl_flavour lock_flav)
210 {
211         if (lock_flav == WINDOWS_LOCK &&
212             fsp->current_lock_count != NO_LOCKING_COUNT) {
213                 /* blocking ie. pending, locks also count here,
214                  * as this is an efficiency counter to avoid checking
215                  * the lock db. on close. JRA. */
216
217                 fsp->current_lock_count++;
218         } else {
219                 /* Notice that this has had a POSIX lock request.
220                  * We can't count locks after this so forget them.
221                  */
222                 fsp->current_lock_count = NO_LOCKING_COUNT;
223         }
224 }
225
226 static void decrement_current_lock_count(files_struct *fsp,
227     enum brl_flavour lock_flav)
228 {
229         if (lock_flav == WINDOWS_LOCK &&
230             fsp->current_lock_count != NO_LOCKING_COUNT) {
231                 SMB_ASSERT(fsp->current_lock_count > 0);
232                 fsp->current_lock_count--;
233         }
234 }
235
236 /****************************************************************************
237  Utility function called by locking requests.
238 ****************************************************************************/
239
240 struct byte_range_lock *do_lock(struct messaging_context *msg_ctx,
241                         files_struct *fsp,
242                         uint64_t smblctx,
243                         uint64_t count,
244                         uint64_t offset,
245                         enum brl_type lock_type,
246                         enum brl_flavour lock_flav,
247                         bool blocking_lock,
248                         NTSTATUS *perr,
249                         uint64_t *psmblctx,
250                         struct blocking_lock_record *blr)
251 {
252         struct byte_range_lock *br_lck = NULL;
253
254         /* silently return ok on print files as we don't do locking there */
255         if (fsp->print_file) {
256                 *perr = NT_STATUS_OK;
257                 return NULL;
258         }
259
260         if (!fsp->can_lock) {
261                 *perr = fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
262                 return NULL;
263         }
264
265         if (!lp_locking(fsp->conn->params)) {
266                 *perr = NT_STATUS_OK;
267                 return NULL;
268         }
269
270         /* NOTE! 0 byte long ranges ARE allowed and should be stored  */
271
272         DEBUG(10,("do_lock: lock flavour %s lock type %s start=%.0f len=%.0f "
273                 "blocking_lock=%s requested for fnum %d file %s\n",
274                 lock_flav_name(lock_flav), lock_type_name(lock_type),
275                 (double)offset, (double)count, blocking_lock ? "true" :
276                 "false", fsp->fnum, fsp_str_dbg(fsp)));
277
278         br_lck = brl_get_locks(talloc_tos(), fsp);
279         if (!br_lck) {
280                 *perr = NT_STATUS_NO_MEMORY;
281                 return NULL;
282         }
283
284         *perr = brl_lock(msg_ctx,
285                         br_lck,
286                         smblctx,
287                         messaging_server_id(fsp->conn->sconn->msg_ctx),
288                         offset,
289                         count,
290                         lock_type,
291                         lock_flav,
292                         blocking_lock,
293                         psmblctx,
294                         blr);
295
296         DEBUG(10, ("do_lock: returning status=%s\n", nt_errstr(*perr)));
297
298         increment_current_lock_count(fsp, lock_flav);
299         return br_lck;
300 }
301
302 /****************************************************************************
303  Utility function called by unlocking requests.
304 ****************************************************************************/
305
306 NTSTATUS do_unlock(struct messaging_context *msg_ctx,
307                         files_struct *fsp,
308                         uint64_t smblctx,
309                         uint64_t count,
310                         uint64_t offset,
311                         enum brl_flavour lock_flav)
312 {
313         bool ok = False;
314         struct byte_range_lock *br_lck = NULL;
315
316         if (!fsp->can_lock) {
317                 return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
318         }
319
320         if (!lp_locking(fsp->conn->params)) {
321                 return NT_STATUS_OK;
322         }
323
324         DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for fnum %d file %s\n",
325                   (double)offset, (double)count, fsp->fnum,
326                   fsp_str_dbg(fsp)));
327
328         br_lck = brl_get_locks(talloc_tos(), fsp);
329         if (!br_lck) {
330                 return NT_STATUS_NO_MEMORY;
331         }
332
333         ok = brl_unlock(msg_ctx,
334                         br_lck,
335                         smblctx,
336                         messaging_server_id(fsp->conn->sconn->msg_ctx),
337                         offset,
338                         count,
339                         lock_flav);
340
341         TALLOC_FREE(br_lck);
342
343         if (!ok) {
344                 DEBUG(10,("do_unlock: returning ERRlock.\n" ));
345                 return NT_STATUS_RANGE_NOT_LOCKED;
346         }
347
348         decrement_current_lock_count(fsp, lock_flav);
349         return NT_STATUS_OK;
350 }
351
352 /****************************************************************************
353  Cancel any pending blocked locks.
354 ****************************************************************************/
355
356 NTSTATUS do_lock_cancel(files_struct *fsp,
357                         uint64 smblctx,
358                         uint64_t count,
359                         uint64_t offset,
360                         enum brl_flavour lock_flav,
361                         struct blocking_lock_record *blr)
362 {
363         bool ok = False;
364         struct byte_range_lock *br_lck = NULL;
365
366         if (!fsp->can_lock) {
367                 return fsp->is_directory ?
368                         NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
369         }
370
371         if (!lp_locking(fsp->conn->params)) {
372                 return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
373         }
374
375         DEBUG(10,("do_lock_cancel: cancel start=%.0f len=%.0f requested for fnum %d file %s\n",
376                   (double)offset, (double)count, fsp->fnum,
377                   fsp_str_dbg(fsp)));
378
379         br_lck = brl_get_locks(talloc_tos(), fsp);
380         if (!br_lck) {
381                 return NT_STATUS_NO_MEMORY;
382         }
383
384         ok = brl_lock_cancel(br_lck,
385                         smblctx,
386                         messaging_server_id(fsp->conn->sconn->msg_ctx),
387                         offset,
388                         count,
389                         lock_flav,
390                         blr);
391
392         TALLOC_FREE(br_lck);
393
394         if (!ok) {
395                 DEBUG(10,("do_lock_cancel: returning ERRcancelviolation.\n" ));
396                 return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
397         }
398
399         decrement_current_lock_count(fsp, lock_flav);
400         return NT_STATUS_OK;
401 }
402
403 /****************************************************************************
404  Remove any locks on this fd. Called from file_close().
405 ****************************************************************************/
406
407 void locking_close_file(struct messaging_context *msg_ctx,
408                         files_struct *fsp,
409                         enum file_close_type close_type)
410 {
411         struct byte_range_lock *br_lck;
412
413         if (!lp_locking(fsp->conn->params)) {
414                 return;
415         }
416
417         /* If we have not outstanding locks or pending
418          * locks then we don't need to look in the lock db.
419          */
420
421         if (fsp->current_lock_count == 0) {
422                 return;
423         }
424
425         br_lck = brl_get_locks(talloc_tos(),fsp);
426
427         if (br_lck) {
428                 cancel_pending_lock_requests_by_fid(fsp, br_lck, close_type);
429                 brl_close_fnum(msg_ctx, br_lck);
430                 TALLOC_FREE(br_lck);
431         }
432 }
433
434 /****************************************************************************
435  Initialise the locking functions.
436 ****************************************************************************/
437
438 static bool locking_init_internal(bool read_only)
439 {
440         brl_init(read_only);
441
442         if (lock_db)
443                 return True;
444
445         lock_db = db_open(NULL, lock_path("locking.tdb"),
446                           lp_open_files_db_hash_size(),
447                           TDB_DEFAULT|TDB_VOLATILE|TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH,
448                           read_only?O_RDONLY:O_RDWR|O_CREAT, 0644);
449
450         if (!lock_db) {
451                 DEBUG(0,("ERROR: Failed to initialise locking database\n"));
452                 return False;
453         }
454
455         if (!posix_locking_init(read_only))
456                 return False;
457
458         return True;
459 }
460
461 bool locking_init(void)
462 {
463         return locking_init_internal(false);
464 }
465
466 bool locking_init_readonly(void)
467 {
468         return locking_init_internal(true);
469 }
470
471 /*******************************************************************
472  Deinitialize the share_mode management.
473 ******************************************************************/
474
475 bool locking_end(void)
476 {
477         brl_shutdown();
478         TALLOC_FREE(lock_db);
479         return true;
480 }
481
482 /*******************************************************************
483  Form a static locking key for a dev/inode pair.
484 ******************************************************************/
485
486 static TDB_DATA locking_key(const struct file_id *id, struct file_id *tmp)
487 {
488         *tmp = *id;
489         return make_tdb_data((const uint8_t *)tmp, sizeof(*tmp));
490 }
491
492 /*******************************************************************
493  Print out a share mode.
494 ********************************************************************/
495
496 char *share_mode_str(TALLOC_CTX *ctx, int num, const struct share_mode_entry *e)
497 {
498         return talloc_asprintf(ctx, "share_mode_entry[%d]: "
499                  "pid = %s, share_access = 0x%x, private_options = 0x%x, "
500                  "access_mask = 0x%x, mid = 0x%llx, type= 0x%x, gen_id = %llu, "
501                  "uid = %u, flags = %u, file_id %s, name_hash = 0x%x",
502                  num,
503                  procid_str_static(&e->pid),
504                  e->share_access, e->private_options,
505                  e->access_mask, (unsigned long long)e->op_mid,
506                  e->op_type, (unsigned long long)e->share_file_id,
507                  (unsigned int)e->uid, (unsigned int)e->flags,
508                  file_id_string_tos(&e->id),
509                  (unsigned int)e->name_hash);
510 }
511
512 /*******************************************************************
513  Get all share mode entries for a dev/inode pair.
514 ********************************************************************/
515
516 static struct share_mode_lock *parse_share_modes(TALLOC_CTX *mem_ctx,
517                                                  const TDB_DATA dbuf)
518 {
519         struct share_mode_lock *lck;
520         int i;
521         struct server_id *pids;
522         bool *pid_exists;
523         enum ndr_err_code ndr_err;
524         DATA_BLOB blob;
525
526         lck = talloc_zero(mem_ctx, struct share_mode_lock);
527         if (lck == NULL) {
528                 DEBUG(0, ("talloc failed\n"));
529                 goto fail;
530         }
531
532         blob.data = dbuf.dptr;
533         blob.length = dbuf.dsize;
534
535         ndr_err = ndr_pull_struct_blob(
536                 &blob, lck, lck,
537                 (ndr_pull_flags_fn_t)ndr_pull_share_mode_lock);
538         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
539                 DEBUG(1, ("ndr_pull_share_mode_lock failed\n"));
540                 goto fail;
541         }
542
543         lck->modified = false;
544         lck->fresh = false;
545
546         if (DEBUGLEVEL >= 10) {
547                 DEBUG(10, ("parse_share_modes:\n"));
548                 NDR_PRINT_DEBUG(share_mode_lock, lck);
549         }
550
551         /*
552          * Ensure that each entry has a real process attached.
553          */
554
555         pids = talloc_array(talloc_tos(), struct server_id,
556                             lck->num_share_modes);
557         if (pids == NULL) {
558                 DEBUG(0, ("talloc failed\n"));
559                 goto fail;
560         }
561         pid_exists = talloc_array(talloc_tos(), bool, lck->num_share_modes);
562         if (pid_exists == NULL) {
563                 DEBUG(0, ("talloc failed\n"));
564                 goto fail;
565         }
566
567         for (i=0; i<lck->num_share_modes; i++) {
568                 pids[i] = lck->share_modes[i].pid;
569         }
570         if (!serverids_exist(pids, lck->num_share_modes, pid_exists)) {
571                 DEBUG(0, ("serverid_exists failed\n"));
572                 goto fail;
573         }
574
575         i = 0;
576         while (i < lck->num_share_modes) {
577                 struct share_mode_entry *e = &lck->share_modes[i];
578                 if (!pid_exists[i]) {
579                         *e = lck->share_modes[lck->num_share_modes-1];
580                         lck->num_share_modes -= 1;
581                         lck->modified = True;
582                         continue;
583                 }
584                 i += 1;
585         }
586         TALLOC_FREE(pid_exists);
587         TALLOC_FREE(pids);
588         return lck;
589 fail:
590         TALLOC_FREE(lck);
591         return NULL;
592 }
593
594 static TDB_DATA unparse_share_modes(struct share_mode_lock *lck)
595 {
596         DATA_BLOB blob;
597         enum ndr_err_code ndr_err;
598
599         if (DEBUGLEVEL >= 10) {
600                 DEBUG(10, ("unparse_share_modes:\n"));
601                 NDR_PRINT_DEBUG(share_mode_lock, lck);
602         }
603
604         if (lck->num_share_modes == 0) {
605                 DEBUG(10, ("No used share mode found\n"));
606                 return make_tdb_data(NULL, 0);
607         }
608
609         ndr_err = ndr_push_struct_blob(
610                 &blob, lck, lck,
611                 (ndr_push_flags_fn_t)ndr_push_share_mode_lock);
612         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
613                 smb_panic("ndr_push_share_mode_lock failed");
614         }
615
616         return make_tdb_data(blob.data, blob.length);
617 }
618
619 static int share_mode_lock_destructor(struct share_mode_lock *lck)
620 {
621         NTSTATUS status;
622         TDB_DATA data;
623
624         if (!lck->modified) {
625                 return 0;
626         }
627
628         data = unparse_share_modes(lck);
629
630         if (data.dptr == NULL) {
631                 if (!lck->fresh) {
632                         /* There has been an entry before, delete it */
633
634                         status = dbwrap_record_delete(lck->record);
635                         if (!NT_STATUS_IS_OK(status)) {
636                                 char *errmsg;
637
638                                 DEBUG(0, ("delete_rec returned %s\n",
639                                           nt_errstr(status)));
640
641                                 if (asprintf(&errmsg, "could not delete share "
642                                              "entry: %s\n",
643                                              nt_errstr(status)) == -1) {
644                                         smb_panic("could not delete share"
645                                                   "entry");
646                                 }
647                                 smb_panic(errmsg);
648                         }
649                 }
650                 goto done;
651         }
652
653         status = dbwrap_record_store(lck->record, data, TDB_REPLACE);
654         if (!NT_STATUS_IS_OK(status)) {
655                 char *errmsg;
656
657                 DEBUG(0, ("store returned %s\n", nt_errstr(status)));
658
659                 if (asprintf(&errmsg, "could not store share mode entry: %s",
660                              nt_errstr(status)) == -1) {
661                         smb_panic("could not store share mode entry");
662                 }
663                 smb_panic(errmsg);
664         }
665
666  done:
667
668         return 0;
669 }
670
671 static struct share_mode_lock *fresh_share_mode_lock(
672         TALLOC_CTX *mem_ctx, const char *servicepath,
673         const struct smb_filename *smb_fname,
674         const struct timespec *old_write_time)
675 {
676         struct share_mode_lock *lck;
677
678         if ((servicepath == NULL) || (smb_fname == NULL) ||
679             (old_write_time == NULL)) {
680                 return NULL;
681         }
682
683         lck = talloc_zero(mem_ctx, struct share_mode_lock);
684         if (lck == NULL) {
685                 goto fail;
686         }
687         lck->base_name = talloc_strdup(lck, smb_fname->base_name);
688         if (lck->base_name == NULL) {
689                 goto fail;
690         }
691         if (smb_fname->stream_name != NULL) {
692                 lck->stream_name = talloc_strdup(lck, smb_fname->stream_name);
693                 if (lck->stream_name == NULL) {
694                         goto fail;
695                 }
696         }
697         lck->servicepath = talloc_strdup(lck, servicepath);
698         if (lck->servicepath == NULL) {
699                 goto fail;
700         }
701         lck->old_write_time = *old_write_time;
702         lck->modified = false;
703         lck->fresh = true;
704         return lck;
705 fail:
706         DEBUG(0, ("talloc failed\n"));
707         TALLOC_FREE(lck);
708         return NULL;
709 }
710
711 struct share_mode_lock *get_share_mode_lock_fresh(TALLOC_CTX *mem_ctx,
712                                                   const struct file_id id,
713                                                   const char *servicepath,
714                                                   const struct smb_filename *smb_fname,
715                                                   const struct timespec *old_write_time)
716 {
717         struct share_mode_lock *lck;
718         struct file_id tmp;
719         struct db_record *rec;
720         TDB_DATA key = locking_key(&id, &tmp);
721         TDB_DATA value;
722
723         rec = dbwrap_fetch_locked(lock_db, mem_ctx, key);
724         if (rec == NULL) {
725                 DEBUG(3, ("Could not lock share entry\n"));
726                 return NULL;
727         }
728
729         value = dbwrap_record_get_value(rec);
730
731         if (value.dptr == NULL) {
732                 lck = fresh_share_mode_lock(mem_ctx, servicepath, smb_fname,
733                                             old_write_time);
734         } else {
735                 lck = parse_share_modes(mem_ctx, value);
736         }
737
738         if (lck == NULL) {
739                 DEBUG(1, ("Could not get share mode lock\n"));
740                 TALLOC_FREE(rec);
741                 return NULL;
742         }
743         lck->id = id;
744         lck->record = talloc_move(lck, &rec);
745         talloc_set_destructor(lck, share_mode_lock_destructor);
746         return lck;
747 }
748
749 struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
750                                             const struct file_id id)
751 {
752         return get_share_mode_lock_fresh(mem_ctx, id, NULL, NULL, NULL);
753 }
754
755 struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx,
756                                                   const struct file_id id)
757 {
758         struct share_mode_lock *lck;
759         struct file_id tmp;
760         TDB_DATA key = locking_key(&id, &tmp);
761         TDB_DATA data;
762         NTSTATUS status;
763
764         status = dbwrap_fetch(lock_db, talloc_tos(), key, &data);
765         if (!NT_STATUS_IS_OK(status)) {
766                 DEBUG(3, ("Could not fetch share entry\n"));
767                 return NULL;
768         }
769         if (data.dptr == NULL) {
770                 return NULL;
771         }
772         lck = parse_share_modes(mem_ctx, data);
773         if (lck != NULL) {
774                 lck->id = id;
775         }
776         TALLOC_FREE(data.dptr);
777         return lck;
778 }
779
780 /*******************************************************************
781  Sets the service name and filename for rename.
782  At this point we emit "file renamed" messages to all
783  process id's that have this file open.
784  Based on an initial code idea from SATOH Fumiyasu <fumiya@samba.gr.jp>
785 ********************************************************************/
786
787 bool rename_share_filename(struct messaging_context *msg_ctx,
788                         struct share_mode_lock *lck,
789                         const char *servicepath,
790                         uint32_t orig_name_hash,
791                         uint32_t new_name_hash,
792                         const struct smb_filename *smb_fname_dst)
793 {
794         size_t sp_len;
795         size_t bn_len;
796         size_t sn_len;
797         size_t msg_len;
798         char *frm = NULL;
799         int i;
800         bool strip_two_chars = false;
801         bool has_stream = smb_fname_dst->stream_name != NULL;
802
803         DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n",
804                    servicepath, smb_fname_dst->base_name));
805
806         /*
807          * rename_internal_fsp() and rename_internals() add './' to
808          * head of newname if newname does not contain a '/'.
809          */
810         if (smb_fname_dst->base_name[0] &&
811             smb_fname_dst->base_name[1] &&
812             smb_fname_dst->base_name[0] == '.' &&
813             smb_fname_dst->base_name[1] == '/') {
814                 strip_two_chars = true;
815         }
816
817         lck->servicepath = talloc_strdup(lck, servicepath);
818         lck->base_name = talloc_strdup(lck, smb_fname_dst->base_name +
819                                        (strip_two_chars ? 2 : 0));
820         lck->stream_name = talloc_strdup(lck, smb_fname_dst->stream_name);
821         if (lck->base_name == NULL ||
822             (has_stream && lck->stream_name == NULL) ||
823             lck->servicepath == NULL) {
824                 DEBUG(0, ("rename_share_filename: talloc failed\n"));
825                 return False;
826         }
827         lck->modified = True;
828
829         sp_len = strlen(lck->servicepath);
830         bn_len = strlen(lck->base_name);
831         sn_len = has_stream ? strlen(lck->stream_name) : 0;
832
833         msg_len = MSG_FILE_RENAMED_MIN_SIZE + sp_len + 1 + bn_len + 1 +
834             sn_len + 1;
835
836         /* Set up the name changed message. */
837         frm = talloc_array(lck, char, msg_len);
838         if (!frm) {
839                 return False;
840         }
841
842         push_file_id_24(frm, &lck->id);
843
844         DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len ));
845
846         strlcpy(&frm[24],
847                 lck->servicepath ? lck->servicepath : "",
848                 sp_len+1);
849         strlcpy(&frm[24 + sp_len + 1],
850                 lck->base_name ? lck->base_name : "",
851                 bn_len+1);
852         strlcpy(&frm[24 + sp_len + 1 + bn_len + 1],
853                 lck->stream_name ? lck->stream_name : "",
854                 sn_len+1);
855
856         /* Send the messages. */
857         for (i=0; i<lck->num_share_modes; i++) {
858                 struct share_mode_entry *se = &lck->share_modes[i];
859                 if (!is_valid_share_mode_entry(se)) {
860                         continue;
861                 }
862
863                 /* If this is a hardlink to the inode
864                    with a different name, skip this. */
865                 if (se->name_hash != orig_name_hash) {
866                         continue;
867                 }
868
869                 se->name_hash = new_name_hash;
870
871                 /* But not to ourselves... */
872                 if (procid_is_me(&se->pid)) {
873                         continue;
874                 }
875
876                 DEBUG(10,("rename_share_filename: sending rename message to "
877                           "pid %s file_id %s sharepath %s base_name %s "
878                           "stream_name %s\n",
879                           procid_str_static(&se->pid),
880                           file_id_string_tos(&lck->id),
881                           lck->servicepath, lck->base_name,
882                         has_stream ? lck->stream_name : ""));
883
884                 messaging_send_buf(msg_ctx, se->pid, MSG_SMB_FILE_RENAME,
885                                    (uint8 *)frm, msg_len);
886         }
887
888         return True;
889 }
890
891 void get_file_infos(struct file_id id,
892                     uint32_t name_hash,
893                     bool *delete_on_close,
894                     struct timespec *write_time)
895 {
896         struct share_mode_lock *lck;
897
898         if (delete_on_close) {
899                 *delete_on_close = false;
900         }
901
902         if (write_time) {
903                 ZERO_STRUCTP(write_time);
904         }
905
906         if (!(lck = fetch_share_mode_unlocked(talloc_tos(), id))) {
907                 return;
908         }
909
910         if (delete_on_close) {
911                 *delete_on_close = is_delete_on_close_set(lck, name_hash);
912         }
913
914         if (write_time) {
915                 struct timespec wt;
916
917                 wt = lck->changed_write_time;
918                 if (null_timespec(wt)) {
919                         wt = lck->old_write_time;
920                 }
921
922                 *write_time = wt;
923         }
924
925         TALLOC_FREE(lck);
926 }
927
928 bool is_valid_share_mode_entry(const struct share_mode_entry *e)
929 {
930         int num_props = 0;
931
932         num_props += ((e->op_type == NO_OPLOCK) ? 1 : 0);
933         num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0);
934         num_props += (LEVEL_II_OPLOCK_TYPE(e->op_type) ? 1 : 0);
935
936         SMB_ASSERT(num_props <= 1);
937         return (num_props != 0);
938 }
939
940 bool is_deferred_open_entry(const struct share_mode_entry *e)
941 {
942         return (e->op_type == DEFERRED_OPEN_ENTRY);
943 }
944
945 /*******************************************************************
946  Fill a share mode entry.
947 ********************************************************************/
948
949 static void fill_share_mode_entry(struct share_mode_entry *e,
950                                   files_struct *fsp,
951                                   uid_t uid, uint64_t mid, uint16 op_type)
952 {
953         ZERO_STRUCTP(e);
954         e->pid = messaging_server_id(fsp->conn->sconn->msg_ctx);
955         e->share_access = fsp->share_access;
956         e->private_options = fsp->fh->private_options;
957         e->access_mask = fsp->access_mask;
958         e->op_mid = mid;
959         e->op_type = op_type;
960         e->time.tv_sec = fsp->open_time.tv_sec;
961         e->time.tv_usec = fsp->open_time.tv_usec;
962         e->id = fsp->file_id;
963         e->share_file_id = fsp->fh->gen_id;
964         e->uid = (uint32)uid;
965         e->flags = fsp->posix_open ? SHARE_MODE_FLAG_POSIX_OPEN : 0;
966         e->name_hash = fsp->name_hash;
967 }
968
969 static void fill_deferred_open_entry(struct share_mode_entry *e,
970                                      const struct timeval request_time,
971                                      struct file_id id,
972                                      struct server_id pid,
973                                      uint64_t mid)
974 {
975         ZERO_STRUCTP(e);
976         e->pid = pid;
977         e->op_mid = mid;
978         e->op_type = DEFERRED_OPEN_ENTRY;
979         e->time.tv_sec = request_time.tv_sec;
980         e->time.tv_usec = request_time.tv_usec;
981         e->id = id;
982         e->uid = (uint32)-1;
983         e->flags = 0;
984 }
985
986 static void add_share_mode_entry(struct share_mode_lock *lck,
987                                  const struct share_mode_entry *entry)
988 {
989         ADD_TO_ARRAY(lck, struct share_mode_entry, *entry,
990                      &lck->share_modes, &lck->num_share_modes);
991         lck->modified = True;
992 }
993
994 void set_share_mode(struct share_mode_lock *lck, files_struct *fsp,
995                     uid_t uid, uint64_t mid, uint16 op_type)
996 {
997         struct share_mode_entry entry;
998         fill_share_mode_entry(&entry, fsp, uid, mid, op_type);
999         add_share_mode_entry(lck, &entry);
1000 }
1001
1002 void add_deferred_open(struct share_mode_lock *lck, uint64_t mid,
1003                        struct timeval request_time,
1004                        struct server_id pid, struct file_id id)
1005 {
1006         struct share_mode_entry entry;
1007         fill_deferred_open_entry(&entry, request_time, id, pid, mid);
1008         add_share_mode_entry(lck, &entry);
1009 }
1010
1011 /*******************************************************************
1012  Check if two share mode entries are identical, ignoring oplock 
1013  and mid info and desired_access. (Removed paranoia test - it's
1014  not automatically a logic error if they are identical. JRA.)
1015 ********************************************************************/
1016
1017 static bool share_modes_identical(struct share_mode_entry *e1,
1018                                   struct share_mode_entry *e2)
1019 {
1020         /* We used to check for e1->share_access == e2->share_access here
1021            as well as the other fields but 2 different DOS or FCB opens
1022            sharing the same share mode entry may validly differ in
1023            fsp->share_access field. */
1024
1025         return (procid_equal(&e1->pid, &e2->pid) &&
1026                 file_id_equal(&e1->id, &e2->id) &&
1027                 e1->share_file_id == e2->share_file_id );
1028 }
1029
1030 static bool deferred_open_identical(struct share_mode_entry *e1,
1031                                     struct share_mode_entry *e2)
1032 {
1033         return (procid_equal(&e1->pid, &e2->pid) &&
1034                 (e1->op_mid == e2->op_mid) &&
1035                 file_id_equal(&e1->id, &e2->id));
1036 }
1037
1038 static struct share_mode_entry *find_share_mode_entry(struct share_mode_lock *lck,
1039                                                       struct share_mode_entry *entry)
1040 {
1041         int i;
1042
1043         for (i=0; i<lck->num_share_modes; i++) {
1044                 struct share_mode_entry *e = &lck->share_modes[i];
1045                 if (is_valid_share_mode_entry(entry) &&
1046                     is_valid_share_mode_entry(e) &&
1047                     share_modes_identical(e, entry)) {
1048                         return e;
1049                 }
1050                 if (is_deferred_open_entry(entry) &&
1051                     is_deferred_open_entry(e) &&
1052                     deferred_open_identical(e, entry)) {
1053                         return e;
1054                 }
1055         }
1056         return NULL;
1057 }
1058
1059 /*******************************************************************
1060  Del the share mode of a file for this process. Return the number of
1061  entries left.
1062 ********************************************************************/
1063
1064 bool del_share_mode(struct share_mode_lock *lck, files_struct *fsp)
1065 {
1066         struct share_mode_entry entry, *e;
1067
1068         /* Don't care about the pid owner being correct here - just a search. */
1069         fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1070
1071         e = find_share_mode_entry(lck, &entry);
1072         if (e == NULL) {
1073                 return False;
1074         }
1075         *e = lck->share_modes[lck->num_share_modes-1];
1076         lck->num_share_modes -= 1;
1077         lck->modified = True;
1078         return True;
1079 }
1080
1081 void del_deferred_open_entry(struct share_mode_lock *lck, uint64_t mid,
1082                              struct server_id pid)
1083 {
1084         struct share_mode_entry entry, *e;
1085
1086         fill_deferred_open_entry(&entry, timeval_zero(),
1087                                  lck->id, pid, mid);
1088
1089         e = find_share_mode_entry(lck, &entry);
1090         if (e == NULL) {
1091                 return;
1092         }
1093         *e = lck->share_modes[lck->num_share_modes-1];
1094         lck->num_share_modes -= 1;
1095         lck->modified = True;
1096 }
1097
1098 /*******************************************************************
1099  Remove an oplock mid and mode entry from a share mode.
1100 ********************************************************************/
1101
1102 bool remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
1103 {
1104         struct share_mode_entry entry, *e;
1105
1106         /* Don't care about the pid owner being correct here - just a search. */
1107         fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1108
1109         e = find_share_mode_entry(lck, &entry);
1110         if (e == NULL) {
1111                 return False;
1112         }
1113
1114         if (EXCLUSIVE_OPLOCK_TYPE(e->op_type)) {
1115                 /*
1116                  * Going from exclusive or batch,
1117                  * we always go through FAKE_LEVEL_II
1118                  * first.
1119                  */
1120                 if (!EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1121                         smb_panic("remove_share_oplock: logic error");
1122                 }
1123                 e->op_type = FAKE_LEVEL_II_OPLOCK;
1124         } else {
1125                 e->op_type = NO_OPLOCK;
1126         }
1127         lck->modified = True;
1128         return True;
1129 }
1130
1131 /*******************************************************************
1132  Downgrade a oplock type from exclusive to level II.
1133 ********************************************************************/
1134
1135 bool downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
1136 {
1137         struct share_mode_entry entry, *e;
1138
1139         /* Don't care about the pid owner being correct here - just a search. */
1140         fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1141
1142         e = find_share_mode_entry(lck, &entry);
1143         if (e == NULL) {
1144                 return False;
1145         }
1146
1147         e->op_type = LEVEL_II_OPLOCK;
1148         lck->modified = True;
1149         return True;
1150 }
1151
1152 /*************************************************************************
1153  Return a talloced copy of a struct security_unix_token. NULL on fail.
1154  (Should this be in locking.c.... ?).
1155 *************************************************************************/
1156
1157 static struct security_unix_token *copy_unix_token(TALLOC_CTX *ctx, const struct security_unix_token *tok)
1158 {
1159         struct security_unix_token *cpy;
1160
1161         cpy = talloc(ctx, struct security_unix_token);
1162         if (!cpy) {
1163                 return NULL;
1164         }
1165
1166         cpy->uid = tok->uid;
1167         cpy->gid = tok->gid;
1168         cpy->ngroups = tok->ngroups;
1169         if (tok->ngroups) {
1170                 /* Make this a talloc child of cpy. */
1171                 cpy->groups = (gid_t *)talloc_memdup(
1172                         cpy, tok->groups, tok->ngroups * sizeof(gid_t));
1173                 if (!cpy->groups) {
1174                         TALLOC_FREE(cpy);
1175                         return NULL;
1176                 }
1177         }
1178         return cpy;
1179 }
1180
1181 /****************************************************************************
1182  Adds a delete on close token.
1183 ****************************************************************************/
1184
1185 static bool add_delete_on_close_token(struct share_mode_lock *lck,
1186                         uint32_t name_hash,
1187                         const struct security_unix_token *tok)
1188 {
1189         struct delete_token *tmp, *dtl;
1190
1191         tmp = talloc_realloc(lck, lck->delete_tokens, struct delete_token,
1192                              lck->num_delete_tokens+1);
1193         if (tmp == NULL) {
1194                 return false;
1195         }
1196         lck->delete_tokens = tmp;
1197         dtl = &lck->delete_tokens[lck->num_delete_tokens];
1198
1199         dtl->name_hash = name_hash;
1200         dtl->delete_token = copy_unix_token(lck->delete_tokens, tok);
1201         if (dtl->delete_token == NULL) {
1202                 return false;
1203         }
1204         lck->num_delete_tokens += 1;
1205         lck->modified = true;
1206         return true;
1207 }
1208
1209 /****************************************************************************
1210  Sets the delete on close flag over all share modes on this file.
1211  Modify the share mode entry for all files open
1212  on this device and inode to tell other smbds we have
1213  changed the delete on close flag. This will be noticed
1214  in the close code, the last closer will delete the file
1215  if flag is set.
1216  This makes a copy of any struct security_unix_token into the
1217  lck entry. This function is used when the lock is already granted.
1218 ****************************************************************************/
1219
1220 void set_delete_on_close_lck(files_struct *fsp,
1221                         struct share_mode_lock *lck,
1222                         bool delete_on_close,
1223                         const struct security_unix_token *tok)
1224 {
1225         int i;
1226         bool ret;
1227
1228         if (delete_on_close) {
1229                 SMB_ASSERT(tok != NULL);
1230         } else {
1231                 SMB_ASSERT(tok == NULL);
1232         }
1233
1234         for (i=0; i<lck->num_delete_tokens; i++) {
1235                 struct delete_token *dt = &lck->delete_tokens[i];
1236                 if (dt->name_hash == fsp->name_hash) {
1237                         lck->modified = true;
1238                         if (delete_on_close == false) {
1239                                 /* Delete this entry. */
1240                                 TALLOC_FREE(dt->delete_token);
1241                                 *dt = lck->delete_tokens[
1242                                         lck->num_delete_tokens-1];
1243                                 lck->num_delete_tokens -= 1;
1244                                 return;
1245                         }
1246                         /* Replace this token with the
1247                            given tok. */
1248                         TALLOC_FREE(dt->delete_token);
1249                         dt->delete_token = copy_unix_token(dt, tok);
1250                         SMB_ASSERT(dt->delete_token != NULL);
1251                 }
1252         }
1253
1254         if (!delete_on_close) {
1255                 /* Nothing to delete - not found. */
1256                 return;
1257         }
1258
1259         ret = add_delete_on_close_token(lck, fsp->name_hash, tok);
1260         SMB_ASSERT(ret);
1261 }
1262
1263 bool set_delete_on_close(files_struct *fsp, bool delete_on_close, const struct security_unix_token *tok)
1264 {
1265         struct share_mode_lock *lck;
1266
1267         DEBUG(10,("set_delete_on_close: %s delete on close flag for "
1268                   "fnum = %d, file %s\n",
1269                   delete_on_close ? "Adding" : "Removing", fsp->fnum,
1270                   fsp_str_dbg(fsp)));
1271
1272         lck = get_share_mode_lock(talloc_tos(), fsp->file_id);
1273         if (lck == NULL) {
1274                 return False;
1275         }
1276
1277         set_delete_on_close_lck(fsp, lck, delete_on_close,
1278                         delete_on_close ? tok : NULL);
1279
1280         if (fsp->is_directory) {
1281                 SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name));
1282                 send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
1283                                                fsp->fsp_name->base_name);
1284         }
1285
1286         TALLOC_FREE(lck);
1287
1288         fsp->delete_on_close = delete_on_close;
1289
1290         return True;
1291 }
1292
1293 const struct security_unix_token *get_delete_on_close_token(struct share_mode_lock *lck, uint32_t name_hash)
1294 {
1295         int i;
1296
1297         DEBUG(10,("get_delete_on_close_token: name_hash = 0x%x\n",
1298                         (unsigned int)name_hash ));
1299
1300         for (i=0; i<lck->num_delete_tokens; i++) {
1301                 struct delete_token *dt = &lck->delete_tokens[i];
1302                 DEBUG(10,("get_delete_on_close_token: dtl->name_hash = 0x%x\n",
1303                                 (unsigned int)dt->name_hash ));
1304                 if (dt->name_hash == name_hash) {
1305                         return dt->delete_token;
1306                 }
1307         }
1308         return NULL;
1309 }
1310
1311 bool is_delete_on_close_set(struct share_mode_lock *lck, uint32_t name_hash)
1312 {
1313         return (get_delete_on_close_token(lck, name_hash) != NULL);
1314 }
1315
1316 bool set_sticky_write_time(struct file_id fileid, struct timespec write_time)
1317 {
1318         struct share_mode_lock *lck;
1319
1320         DEBUG(5,("set_sticky_write_time: %s id=%s\n",
1321                  timestring(talloc_tos(),
1322                             convert_timespec_to_time_t(write_time)),
1323                  file_id_string_tos(&fileid)));
1324
1325         lck = get_share_mode_lock(talloc_tos(), fileid);
1326         if (lck == NULL) {
1327                 return False;
1328         }
1329
1330         if (timespec_compare(&lck->changed_write_time, &write_time) != 0) {
1331                 lck->modified = True;
1332                 lck->changed_write_time = write_time;
1333         }
1334
1335         TALLOC_FREE(lck);
1336         return True;
1337 }
1338
1339 bool set_write_time(struct file_id fileid, struct timespec write_time)
1340 {
1341         struct share_mode_lock *lck;
1342
1343         DEBUG(5,("set_write_time: %s id=%s\n",
1344                  timestring(talloc_tos(),
1345                             convert_timespec_to_time_t(write_time)),
1346                  file_id_string_tos(&fileid)));
1347
1348         lck = get_share_mode_lock(talloc_tos(), fileid);
1349         if (lck == NULL) {
1350                 return False;
1351         }
1352
1353         if (timespec_compare(&lck->old_write_time, &write_time) != 0) {
1354                 lck->modified = True;
1355                 lck->old_write_time = write_time;
1356         }
1357
1358         TALLOC_FREE(lck);
1359         return True;
1360 }
1361
1362
1363 struct forall_state {
1364         void (*fn)(const struct share_mode_entry *entry,
1365                    const char *sharepath,
1366                    const char *fname,
1367                    void *private_data);
1368         void *private_data;
1369 };
1370
1371 static int traverse_fn(struct db_record *rec, void *_state)
1372 {
1373         struct forall_state *state = (struct forall_state *)_state;
1374         uint32_t i;
1375         TDB_DATA key;
1376         TDB_DATA value;
1377         DATA_BLOB blob;
1378         enum ndr_err_code ndr_err;
1379         struct share_mode_lock *lck;
1380
1381         key = dbwrap_record_get_key(rec);
1382         value = dbwrap_record_get_value(rec);
1383
1384         /* Ensure this is a locking_key record. */
1385         if (key.dsize != sizeof(struct file_id))
1386                 return 0;
1387
1388         lck = talloc(talloc_tos(), struct share_mode_lock);
1389         if (lck == NULL) {
1390                 return 0;
1391         }
1392
1393         blob.data = value.dptr;
1394         blob.length = value.dsize;
1395
1396         ndr_err = ndr_pull_struct_blob(
1397                 &blob, lck, lck,
1398                 (ndr_pull_flags_fn_t)ndr_pull_share_mode_lock);
1399         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1400                 DEBUG(1, ("ndr_pull_share_mode_lock failed\n"));
1401                 return 0;
1402         }
1403         for (i=0; i<lck->num_share_modes; i++) {
1404                 state->fn(&lck->share_modes[i],
1405                           lck->servicepath, lck->base_name,
1406                           state->private_data);
1407         }
1408         TALLOC_FREE(lck);
1409
1410         return 0;
1411 }
1412
1413 /*******************************************************************
1414  Call the specified function on each entry under management by the
1415  share mode system.
1416 ********************************************************************/
1417
1418 int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *,
1419                                  const char *, void *),
1420                       void *private_data)
1421 {
1422         struct forall_state state;
1423         NTSTATUS status;
1424         int count;
1425
1426         if (lock_db == NULL)
1427                 return 0;
1428
1429         state.fn = fn;
1430         state.private_data = private_data;
1431
1432         status = dbwrap_traverse_read(lock_db, traverse_fn, (void *)&state,
1433                                       &count);
1434
1435         if (!NT_STATUS_IS_OK(status)) {
1436                 return -1;
1437         } else {
1438                 return count;
1439         }
1440 }