35ae7584a268b02670a61dc6ce9feeffe5121525
[mat/samba.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 = sconn_server_id(fsp->conn->sconn);
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                         sconn_server_id(fsp->conn->sconn),
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                         sconn_server_id(fsp->conn->sconn),
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                         sconn_server_id(fsp->conn->sconn),
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                         sconn_server_id(fsp->conn->sconn),
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 = %lu, "
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, 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 bool parse_share_modes(const TDB_DATA dbuf, struct share_mode_lock *lck)
517 {
518         int i;
519         struct server_id *pids;
520         bool *pid_exists;
521         enum ndr_err_code ndr_err;
522         DATA_BLOB blob;
523
524         blob.data = dbuf.dptr;
525         blob.length = dbuf.dsize;
526
527         ndr_err = ndr_pull_struct_blob(
528                 &blob, lck, lck,
529                 (ndr_pull_flags_fn_t)ndr_pull_share_mode_lock);
530         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
531                 DEBUG(1, ("ndr_pull_share_mode_lock failed\n"));
532                 return false;
533         }
534
535         lck->modified = false;
536
537         if (DEBUGLEVEL >= 10) {
538                 DEBUG(10, ("parse_share_modes:\n"));
539                 NDR_PRINT_DEBUG(share_mode_lock, lck);
540         }
541
542         /*
543          * Ensure that each entry has a real process attached.
544          */
545
546         pids = talloc_array(talloc_tos(), struct server_id,
547                             lck->num_share_modes);
548         if (pids == NULL) {
549                 smb_panic("parse_share_modes: talloc_array failed");
550         }
551         pid_exists = talloc_array(talloc_tos(), bool, lck->num_share_modes);
552         if (pid_exists == NULL) {
553                 smb_panic("parse_share_modes: talloc_array failed");
554         }
555
556         for (i=0; i<lck->num_share_modes; i++) {
557                 pids[i] = lck->share_modes[i].pid;
558         }
559
560         if (!serverids_exist(pids, lck->num_share_modes, pid_exists)) {
561                 smb_panic("parse_share_modes: serverids_exist failed");
562         }
563
564         i = 0;
565         while (i < lck->num_share_modes) {
566                 struct share_mode_entry *e = &lck->share_modes[i];
567                 if (!pid_exists[i]) {
568                         *e = lck->share_modes[lck->num_share_modes-1];
569                         lck->num_share_modes -= 1;
570                         lck->modified = True;
571                         continue;
572                 }
573                 i += 1;
574         }
575         TALLOC_FREE(pid_exists);
576         TALLOC_FREE(pids);
577
578         return True;
579 }
580
581 static TDB_DATA unparse_share_modes(struct share_mode_lock *lck)
582 {
583         DATA_BLOB blob;
584         enum ndr_err_code ndr_err;
585
586         if (DEBUGLEVEL >= 10) {
587                 DEBUG(10, ("unparse_share_modes:\n"));
588                 NDR_PRINT_DEBUG(share_mode_lock, lck);
589         }
590
591         if (lck->num_share_modes == 0) {
592                 DEBUG(10, ("No used share mode found\n"));
593                 return make_tdb_data(NULL, 0);
594         }
595
596         ndr_err = ndr_push_struct_blob(
597                 &blob, lck, lck,
598                 (ndr_push_flags_fn_t)ndr_push_share_mode_lock);
599         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
600                 smb_panic("ndr_push_share_mode_lock failed");
601         }
602
603         return make_tdb_data(blob.data, blob.length);
604 }
605
606 static int share_mode_lock_destructor(struct share_mode_lock *lck)
607 {
608         NTSTATUS status;
609         TDB_DATA data;
610
611         if (!lck->modified) {
612                 return 0;
613         }
614
615         data = unparse_share_modes(lck);
616
617         if (data.dptr == NULL) {
618                 if (!lck->fresh) {
619                         /* There has been an entry before, delete it */
620
621                         status = dbwrap_record_delete(lck->record);
622                         if (!NT_STATUS_IS_OK(status)) {
623                                 char *errmsg;
624
625                                 DEBUG(0, ("delete_rec returned %s\n",
626                                           nt_errstr(status)));
627
628                                 if (asprintf(&errmsg, "could not delete share "
629                                              "entry: %s\n",
630                                              nt_errstr(status)) == -1) {
631                                         smb_panic("could not delete share"
632                                                   "entry");
633                                 }
634                                 smb_panic(errmsg);
635                         }
636                 }
637                 goto done;
638         }
639
640         status = dbwrap_record_store(lck->record, data, TDB_REPLACE);
641         if (!NT_STATUS_IS_OK(status)) {
642                 char *errmsg;
643
644                 DEBUG(0, ("store returned %s\n", nt_errstr(status)));
645
646                 if (asprintf(&errmsg, "could not store share mode entry: %s",
647                              nt_errstr(status)) == -1) {
648                         smb_panic("could not store share mode entry");
649                 }
650                 smb_panic(errmsg);
651         }
652
653  done:
654
655         return 0;
656 }
657
658 static bool fill_share_mode_lock(struct share_mode_lock *lck,
659                                  struct file_id id,
660                                  const char *servicepath,
661                                  const struct smb_filename *smb_fname,
662                                  TDB_DATA share_mode_data,
663                                  const struct timespec *old_write_time)
664 {
665         bool fresh;
666
667         /* Ensure we set every field here as the destructor must be
668            valid even if parse_share_modes fails. */
669
670         lck->servicepath = NULL;
671         lck->base_name = NULL;
672         lck->stream_name = NULL;
673         lck->id = id;
674         lck->num_share_modes = 0;
675         lck->share_modes = NULL;
676         lck->num_delete_tokens = 0;
677         lck->delete_tokens = NULL;
678         ZERO_STRUCT(lck->old_write_time);
679         ZERO_STRUCT(lck->changed_write_time);
680
681         fresh = (share_mode_data.dptr == NULL);
682
683         if (fresh) {
684                 bool has_stream;
685                 if (smb_fname == NULL || servicepath == NULL
686                     || old_write_time == NULL) {
687                         return False;
688                 }
689
690                 has_stream = smb_fname->stream_name != NULL;
691
692                 lck->base_name = talloc_strdup(lck, smb_fname->base_name);
693                 lck->stream_name = talloc_strdup(lck, smb_fname->stream_name);
694                 lck->servicepath = talloc_strdup(lck, servicepath);
695                 if (lck->base_name == NULL ||
696                     (has_stream && lck->stream_name == NULL) ||
697                     lck->servicepath == NULL) {
698                         DEBUG(0, ("talloc failed\n"));
699                         return False;
700                 }
701                 lck->old_write_time = *old_write_time;
702                 lck->modified = false;
703         } else {
704                 if (!parse_share_modes(share_mode_data, lck)) {
705                         DEBUG(0, ("Could not parse share modes\n"));
706                         return False;
707                 }
708         }
709         lck->fresh = fresh;
710
711         return True;
712 }
713
714 struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
715                                             const struct file_id id,
716                                             const char *servicepath,
717                                             const struct smb_filename *smb_fname,
718                                             const struct timespec *old_write_time)
719 {
720         struct share_mode_lock *lck;
721         struct file_id tmp;
722         struct db_record *rec;
723         TDB_DATA key = locking_key(&id, &tmp);
724         TDB_DATA value;
725
726         if (!(lck = talloc(mem_ctx, struct share_mode_lock))) {
727                 DEBUG(0, ("talloc failed\n"));
728                 return NULL;
729         }
730
731         rec = dbwrap_fetch_locked(lock_db, lck, key);
732         if (rec == NULL) {
733                 DEBUG(3, ("Could not lock share entry\n"));
734                 TALLOC_FREE(lck);
735                 return NULL;
736         }
737
738         value = dbwrap_record_get_value(rec);
739
740         if (!fill_share_mode_lock(lck, id, servicepath, smb_fname,
741                                   value, old_write_time)) {
742                 DEBUG(3, ("fill_share_mode_lock failed\n"));
743                 TALLOC_FREE(lck);
744                 return NULL;
745         }
746
747         lck->record = rec;
748         talloc_set_destructor(lck, share_mode_lock_destructor);
749
750         return lck;
751 }
752
753 struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx,
754                                                   const struct file_id id)
755 {
756         struct share_mode_lock *lck;
757         struct file_id tmp;
758         TDB_DATA key = locking_key(&id, &tmp);
759         TDB_DATA data;
760         NTSTATUS status;
761
762         if (!(lck = talloc(mem_ctx, struct share_mode_lock))) {
763                 DEBUG(0, ("talloc failed\n"));
764                 return NULL;
765         }
766
767         status = dbwrap_fetch(lock_db, lck, key, &data);
768         if (!NT_STATUS_IS_OK(status)) {
769                 DEBUG(3, ("Could not fetch share entry\n"));
770                 TALLOC_FREE(lck);
771                 return NULL;
772         }
773         if (data.dptr == NULL) {
774                 TALLOC_FREE(lck);
775                 return NULL;
776         }
777
778         if (!fill_share_mode_lock(lck, id, NULL, NULL, data, NULL)) {
779                 DEBUG(10, ("fetch_share_mode_unlocked: no share_mode record "
780                            "around (file not open)\n"));
781                 TALLOC_FREE(lck);
782                 return NULL;
783         }
784
785         return lck;
786 }
787
788 /*******************************************************************
789  Sets the service name and filename for rename.
790  At this point we emit "file renamed" messages to all
791  process id's that have this file open.
792  Based on an initial code idea from SATOH Fumiyasu <fumiya@samba.gr.jp>
793 ********************************************************************/
794
795 bool rename_share_filename(struct messaging_context *msg_ctx,
796                         struct share_mode_lock *lck,
797                         const char *servicepath,
798                         uint32_t orig_name_hash,
799                         uint32_t new_name_hash,
800                         const struct smb_filename *smb_fname_dst)
801 {
802         size_t sp_len;
803         size_t bn_len;
804         size_t sn_len;
805         size_t msg_len;
806         char *frm = NULL;
807         int i;
808         bool strip_two_chars = false;
809         bool has_stream = smb_fname_dst->stream_name != NULL;
810
811         DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n",
812                    servicepath, smb_fname_dst->base_name));
813
814         /*
815          * rename_internal_fsp() and rename_internals() add './' to
816          * head of newname if newname does not contain a '/'.
817          */
818         if (smb_fname_dst->base_name[0] &&
819             smb_fname_dst->base_name[1] &&
820             smb_fname_dst->base_name[0] == '.' &&
821             smb_fname_dst->base_name[1] == '/') {
822                 strip_two_chars = true;
823         }
824
825         lck->servicepath = talloc_strdup(lck, servicepath);
826         lck->base_name = talloc_strdup(lck, smb_fname_dst->base_name +
827                                        (strip_two_chars ? 2 : 0));
828         lck->stream_name = talloc_strdup(lck, smb_fname_dst->stream_name);
829         if (lck->base_name == NULL ||
830             (has_stream && lck->stream_name == NULL) ||
831             lck->servicepath == NULL) {
832                 DEBUG(0, ("rename_share_filename: talloc failed\n"));
833                 return False;
834         }
835         lck->modified = True;
836
837         sp_len = strlen(lck->servicepath);
838         bn_len = strlen(lck->base_name);
839         sn_len = has_stream ? strlen(lck->stream_name) : 0;
840
841         msg_len = MSG_FILE_RENAMED_MIN_SIZE + sp_len + 1 + bn_len + 1 +
842             sn_len + 1;
843
844         /* Set up the name changed message. */
845         frm = talloc_array(lck, char, msg_len);
846         if (!frm) {
847                 return False;
848         }
849
850         push_file_id_24(frm, &lck->id);
851
852         DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len ));
853
854         strlcpy(&frm[24],
855                 lck->servicepath ? lck->servicepath : "",
856                 sp_len+1);
857         strlcpy(&frm[24 + sp_len + 1],
858                 lck->base_name ? lck->base_name : "",
859                 bn_len+1);
860         strlcpy(&frm[24 + sp_len + 1 + bn_len + 1],
861                 lck->stream_name ? lck->stream_name : "",
862                 sn_len+1);
863
864         /* Send the messages. */
865         for (i=0; i<lck->num_share_modes; i++) {
866                 struct share_mode_entry *se = &lck->share_modes[i];
867                 if (!is_valid_share_mode_entry(se)) {
868                         continue;
869                 }
870
871                 /* If this is a hardlink to the inode
872                    with a different name, skip this. */
873                 if (se->name_hash != orig_name_hash) {
874                         continue;
875                 }
876
877                 se->name_hash = new_name_hash;
878
879                 /* But not to ourselves... */
880                 if (procid_is_me(&se->pid)) {
881                         continue;
882                 }
883
884                 DEBUG(10,("rename_share_filename: sending rename message to "
885                           "pid %s file_id %s sharepath %s base_name %s "
886                           "stream_name %s\n",
887                           procid_str_static(&se->pid),
888                           file_id_string_tos(&lck->id),
889                           lck->servicepath, lck->base_name,
890                         has_stream ? lck->stream_name : ""));
891
892                 messaging_send_buf(msg_ctx, se->pid, MSG_SMB_FILE_RENAME,
893                                    (uint8 *)frm, msg_len);
894         }
895
896         return True;
897 }
898
899 void get_file_infos(struct file_id id,
900                     uint32_t name_hash,
901                     bool *delete_on_close,
902                     struct timespec *write_time)
903 {
904         struct share_mode_lock *lck;
905
906         if (delete_on_close) {
907                 *delete_on_close = false;
908         }
909
910         if (write_time) {
911                 ZERO_STRUCTP(write_time);
912         }
913
914         if (!(lck = fetch_share_mode_unlocked(talloc_tos(), id))) {
915                 return;
916         }
917
918         if (delete_on_close) {
919                 *delete_on_close = is_delete_on_close_set(lck, name_hash);
920         }
921
922         if (write_time) {
923                 struct timespec wt;
924
925                 wt = lck->changed_write_time;
926                 if (null_timespec(wt)) {
927                         wt = lck->old_write_time;
928                 }
929
930                 *write_time = wt;
931         }
932
933         TALLOC_FREE(lck);
934 }
935
936 bool is_valid_share_mode_entry(const struct share_mode_entry *e)
937 {
938         int num_props = 0;
939
940         num_props += ((e->op_type == NO_OPLOCK) ? 1 : 0);
941         num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0);
942         num_props += (LEVEL_II_OPLOCK_TYPE(e->op_type) ? 1 : 0);
943
944         SMB_ASSERT(num_props <= 1);
945         return (num_props != 0);
946 }
947
948 bool is_deferred_open_entry(const struct share_mode_entry *e)
949 {
950         return (e->op_type == DEFERRED_OPEN_ENTRY);
951 }
952
953 /*******************************************************************
954  Fill a share mode entry.
955 ********************************************************************/
956
957 static void fill_share_mode_entry(struct share_mode_entry *e,
958                                   files_struct *fsp,
959                                   uid_t uid, uint64_t mid, uint16 op_type)
960 {
961         ZERO_STRUCTP(e);
962         e->pid = sconn_server_id(fsp->conn->sconn);
963         e->share_access = fsp->share_access;
964         e->private_options = fsp->fh->private_options;
965         e->access_mask = fsp->access_mask;
966         e->op_mid = mid;
967         e->op_type = op_type;
968         e->time.tv_sec = fsp->open_time.tv_sec;
969         e->time.tv_usec = fsp->open_time.tv_usec;
970         e->id = fsp->file_id;
971         e->share_file_id = fsp->fh->gen_id;
972         e->uid = (uint32)uid;
973         e->flags = fsp->posix_open ? SHARE_MODE_FLAG_POSIX_OPEN : 0;
974         e->name_hash = fsp->name_hash;
975 }
976
977 static void fill_deferred_open_entry(struct share_mode_entry *e,
978                                      const struct timeval request_time,
979                                      struct file_id id,
980                                      struct server_id pid,
981                                      uint64_t mid)
982 {
983         ZERO_STRUCTP(e);
984         e->pid = pid;
985         e->op_mid = mid;
986         e->op_type = DEFERRED_OPEN_ENTRY;
987         e->time.tv_sec = request_time.tv_sec;
988         e->time.tv_usec = request_time.tv_usec;
989         e->id = id;
990         e->uid = (uint32)-1;
991         e->flags = 0;
992 }
993
994 static void add_share_mode_entry(struct share_mode_lock *lck,
995                                  const struct share_mode_entry *entry)
996 {
997         ADD_TO_ARRAY(lck, struct share_mode_entry, *entry,
998                      &lck->share_modes, &lck->num_share_modes);
999         lck->modified = True;
1000 }
1001
1002 void set_share_mode(struct share_mode_lock *lck, files_struct *fsp,
1003                     uid_t uid, uint64_t mid, uint16 op_type)
1004 {
1005         struct share_mode_entry entry;
1006         fill_share_mode_entry(&entry, fsp, uid, mid, op_type);
1007         add_share_mode_entry(lck, &entry);
1008 }
1009
1010 void add_deferred_open(struct share_mode_lock *lck, uint64_t mid,
1011                        struct timeval request_time,
1012                        struct server_id pid, struct file_id id)
1013 {
1014         struct share_mode_entry entry;
1015         fill_deferred_open_entry(&entry, request_time, id, pid, mid);
1016         add_share_mode_entry(lck, &entry);
1017 }
1018
1019 /*******************************************************************
1020  Check if two share mode entries are identical, ignoring oplock 
1021  and mid info and desired_access. (Removed paranoia test - it's
1022  not automatically a logic error if they are identical. JRA.)
1023 ********************************************************************/
1024
1025 static bool share_modes_identical(struct share_mode_entry *e1,
1026                                   struct share_mode_entry *e2)
1027 {
1028         /* We used to check for e1->share_access == e2->share_access here
1029            as well as the other fields but 2 different DOS or FCB opens
1030            sharing the same share mode entry may validly differ in
1031            fsp->share_access field. */
1032
1033         return (procid_equal(&e1->pid, &e2->pid) &&
1034                 file_id_equal(&e1->id, &e2->id) &&
1035                 e1->share_file_id == e2->share_file_id );
1036 }
1037
1038 static bool deferred_open_identical(struct share_mode_entry *e1,
1039                                     struct share_mode_entry *e2)
1040 {
1041         return (procid_equal(&e1->pid, &e2->pid) &&
1042                 (e1->op_mid == e2->op_mid) &&
1043                 file_id_equal(&e1->id, &e2->id));
1044 }
1045
1046 static struct share_mode_entry *find_share_mode_entry(struct share_mode_lock *lck,
1047                                                       struct share_mode_entry *entry)
1048 {
1049         int i;
1050
1051         for (i=0; i<lck->num_share_modes; i++) {
1052                 struct share_mode_entry *e = &lck->share_modes[i];
1053                 if (is_valid_share_mode_entry(entry) &&
1054                     is_valid_share_mode_entry(e) &&
1055                     share_modes_identical(e, entry)) {
1056                         return e;
1057                 }
1058                 if (is_deferred_open_entry(entry) &&
1059                     is_deferred_open_entry(e) &&
1060                     deferred_open_identical(e, entry)) {
1061                         return e;
1062                 }
1063         }
1064         return NULL;
1065 }
1066
1067 /*******************************************************************
1068  Del the share mode of a file for this process. Return the number of
1069  entries left.
1070 ********************************************************************/
1071
1072 bool del_share_mode(struct share_mode_lock *lck, files_struct *fsp)
1073 {
1074         struct share_mode_entry entry, *e;
1075
1076         /* Don't care about the pid owner being correct here - just a search. */
1077         fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1078
1079         e = find_share_mode_entry(lck, &entry);
1080         if (e == NULL) {
1081                 return False;
1082         }
1083         *e = lck->share_modes[lck->num_share_modes-1];
1084         lck->num_share_modes -= 1;
1085         lck->modified = True;
1086         return True;
1087 }
1088
1089 void del_deferred_open_entry(struct share_mode_lock *lck, uint64_t mid,
1090                              struct server_id pid)
1091 {
1092         struct share_mode_entry entry, *e;
1093
1094         fill_deferred_open_entry(&entry, timeval_zero(),
1095                                  lck->id, pid, mid);
1096
1097         e = find_share_mode_entry(lck, &entry);
1098         if (e == NULL) {
1099                 return;
1100         }
1101         *e = lck->share_modes[lck->num_share_modes-1];
1102         lck->num_share_modes -= 1;
1103         lck->modified = True;
1104 }
1105
1106 /*******************************************************************
1107  Remove an oplock mid and mode entry from a share mode.
1108 ********************************************************************/
1109
1110 bool remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
1111 {
1112         struct share_mode_entry entry, *e;
1113
1114         /* Don't care about the pid owner being correct here - just a search. */
1115         fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1116
1117         e = find_share_mode_entry(lck, &entry);
1118         if (e == NULL) {
1119                 return False;
1120         }
1121
1122         if (EXCLUSIVE_OPLOCK_TYPE(e->op_type)) {
1123                 /*
1124                  * Going from exclusive or batch,
1125                  * we always go through FAKE_LEVEL_II
1126                  * first.
1127                  */
1128                 if (!EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1129                         smb_panic("remove_share_oplock: logic error");
1130                 }
1131                 e->op_type = FAKE_LEVEL_II_OPLOCK;
1132         } else {
1133                 e->op_type = NO_OPLOCK;
1134         }
1135         lck->modified = True;
1136         return True;
1137 }
1138
1139 /*******************************************************************
1140  Downgrade a oplock type from exclusive to level II.
1141 ********************************************************************/
1142
1143 bool downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
1144 {
1145         struct share_mode_entry entry, *e;
1146
1147         /* Don't care about the pid owner being correct here - just a search. */
1148         fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1149
1150         e = find_share_mode_entry(lck, &entry);
1151         if (e == NULL) {
1152                 return False;
1153         }
1154
1155         e->op_type = LEVEL_II_OPLOCK;
1156         lck->modified = True;
1157         return True;
1158 }
1159
1160 /*************************************************************************
1161  Return a talloced copy of a struct security_unix_token. NULL on fail.
1162  (Should this be in locking.c.... ?).
1163 *************************************************************************/
1164
1165 static struct security_unix_token *copy_unix_token(TALLOC_CTX *ctx, const struct security_unix_token *tok)
1166 {
1167         struct security_unix_token *cpy;
1168
1169         cpy = talloc(ctx, struct security_unix_token);
1170         if (!cpy) {
1171                 return NULL;
1172         }
1173
1174         cpy->uid = tok->uid;
1175         cpy->gid = tok->gid;
1176         cpy->ngroups = tok->ngroups;
1177         if (tok->ngroups) {
1178                 /* Make this a talloc child of cpy. */
1179                 cpy->groups = (gid_t *)talloc_memdup(
1180                         cpy, tok->groups, tok->ngroups * sizeof(gid_t));
1181                 if (!cpy->groups) {
1182                         TALLOC_FREE(cpy);
1183                         return NULL;
1184                 }
1185         }
1186         return cpy;
1187 }
1188
1189 /****************************************************************************
1190  Adds a delete on close token.
1191 ****************************************************************************/
1192
1193 static bool add_delete_on_close_token(struct share_mode_lock *lck,
1194                         uint32_t name_hash,
1195                         const struct security_unix_token *tok)
1196 {
1197         struct delete_token *tmp, *dtl;
1198
1199         tmp = talloc_realloc(lck, lck->delete_tokens, struct delete_token,
1200                              lck->num_delete_tokens+1);
1201         if (tmp == NULL) {
1202                 return false;
1203         }
1204         lck->delete_tokens = tmp;
1205         dtl = &lck->delete_tokens[lck->num_delete_tokens];
1206
1207         dtl->name_hash = name_hash;
1208         dtl->delete_token = copy_unix_token(lck->delete_tokens, tok);
1209         if (dtl->delete_token == NULL) {
1210                 return false;
1211         }
1212         lck->num_delete_tokens += 1;
1213         lck->modified = true;
1214         return true;
1215 }
1216
1217 /****************************************************************************
1218  Sets the delete on close flag over all share modes on this file.
1219  Modify the share mode entry for all files open
1220  on this device and inode to tell other smbds we have
1221  changed the delete on close flag. This will be noticed
1222  in the close code, the last closer will delete the file
1223  if flag is set.
1224  This makes a copy of any struct security_unix_token into the
1225  lck entry. This function is used when the lock is already granted.
1226 ****************************************************************************/
1227
1228 void set_delete_on_close_lck(files_struct *fsp,
1229                         struct share_mode_lock *lck,
1230                         bool delete_on_close,
1231                         const struct security_unix_token *tok)
1232 {
1233         int i;
1234         bool ret;
1235
1236         if (delete_on_close) {
1237                 SMB_ASSERT(tok != NULL);
1238         } else {
1239                 SMB_ASSERT(tok == NULL);
1240         }
1241
1242         for (i=0; i<lck->num_delete_tokens; i++) {
1243                 struct delete_token *dt = &lck->delete_tokens[i];
1244                 if (dt->name_hash == fsp->name_hash) {
1245                         lck->modified = true;
1246                         if (delete_on_close == false) {
1247                                 /* Delete this entry. */
1248                                 TALLOC_FREE(dt->delete_token);
1249                                 *dt = lck->delete_tokens[
1250                                         lck->num_delete_tokens-1];
1251                                 lck->num_delete_tokens -= 1;
1252                                 return;
1253                         }
1254                         /* Replace this token with the
1255                            given tok. */
1256                         TALLOC_FREE(dt->delete_token);
1257                         dt->delete_token = copy_unix_token(dt, tok);
1258                         SMB_ASSERT(dt->delete_token != NULL);
1259                 }
1260         }
1261
1262         if (!delete_on_close) {
1263                 /* Nothing to delete - not found. */
1264                 return;
1265         }
1266
1267         ret = add_delete_on_close_token(lck, fsp->name_hash, tok);
1268         SMB_ASSERT(ret);
1269 }
1270
1271 bool set_delete_on_close(files_struct *fsp, bool delete_on_close, const struct security_unix_token *tok)
1272 {
1273         struct share_mode_lock *lck;
1274
1275         DEBUG(10,("set_delete_on_close: %s delete on close flag for "
1276                   "fnum = %d, file %s\n",
1277                   delete_on_close ? "Adding" : "Removing", fsp->fnum,
1278                   fsp_str_dbg(fsp)));
1279
1280         lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
1281                                   NULL);
1282         if (lck == NULL) {
1283                 return False;
1284         }
1285
1286         set_delete_on_close_lck(fsp, lck, delete_on_close,
1287                         delete_on_close ? tok : NULL);
1288
1289         if (fsp->is_directory) {
1290                 SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name));
1291                 send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
1292                                                fsp->fsp_name->base_name);
1293         }
1294
1295         TALLOC_FREE(lck);
1296
1297         fsp->delete_on_close = delete_on_close;
1298
1299         return True;
1300 }
1301
1302 const struct security_unix_token *get_delete_on_close_token(struct share_mode_lock *lck, uint32_t name_hash)
1303 {
1304         int i;
1305
1306         DEBUG(10,("get_delete_on_close_token: name_hash = 0x%x\n",
1307                         (unsigned int)name_hash ));
1308
1309         for (i=0; i<lck->num_delete_tokens; i++) {
1310                 struct delete_token *dt = &lck->delete_tokens[i];
1311                 DEBUG(10,("get_delete_on_close_token: dtl->name_hash = 0x%x\n",
1312                                 (unsigned int)dt->name_hash ));
1313                 if (dt->name_hash == name_hash) {
1314                         return dt->delete_token;
1315                 }
1316         }
1317         return NULL;
1318 }
1319
1320 bool is_delete_on_close_set(struct share_mode_lock *lck, uint32_t name_hash)
1321 {
1322         return (get_delete_on_close_token(lck, name_hash) != NULL);
1323 }
1324
1325 bool set_sticky_write_time(struct file_id fileid, struct timespec write_time)
1326 {
1327         struct share_mode_lock *lck;
1328
1329         DEBUG(5,("set_sticky_write_time: %s id=%s\n",
1330                  timestring(talloc_tos(),
1331                             convert_timespec_to_time_t(write_time)),
1332                  file_id_string_tos(&fileid)));
1333
1334         lck = get_share_mode_lock(talloc_tos(), fileid, NULL, NULL, NULL);
1335         if (lck == NULL) {
1336                 return False;
1337         }
1338
1339         if (timespec_compare(&lck->changed_write_time, &write_time) != 0) {
1340                 lck->modified = True;
1341                 lck->changed_write_time = write_time;
1342         }
1343
1344         TALLOC_FREE(lck);
1345         return True;
1346 }
1347
1348 bool set_write_time(struct file_id fileid, struct timespec write_time)
1349 {
1350         struct share_mode_lock *lck;
1351
1352         DEBUG(5,("set_write_time: %s id=%s\n",
1353                  timestring(talloc_tos(),
1354                             convert_timespec_to_time_t(write_time)),
1355                  file_id_string_tos(&fileid)));
1356
1357         lck = get_share_mode_lock(talloc_tos(), fileid, NULL, NULL, NULL);
1358         if (lck == NULL) {
1359                 return False;
1360         }
1361
1362         if (timespec_compare(&lck->old_write_time, &write_time) != 0) {
1363                 lck->modified = True;
1364                 lck->old_write_time = write_time;
1365         }
1366
1367         TALLOC_FREE(lck);
1368         return True;
1369 }
1370
1371
1372 struct forall_state {
1373         void (*fn)(const struct share_mode_entry *entry,
1374                    const char *sharepath,
1375                    const char *fname,
1376                    void *private_data);
1377         void *private_data;
1378 };
1379
1380 static int traverse_fn(struct db_record *rec, void *_state)
1381 {
1382         struct forall_state *state = (struct forall_state *)_state;
1383         uint32_t i;
1384         TDB_DATA key;
1385         TDB_DATA value;
1386         DATA_BLOB blob;
1387         enum ndr_err_code ndr_err;
1388         struct share_mode_lock *lck;
1389
1390         key = dbwrap_record_get_key(rec);
1391         value = dbwrap_record_get_value(rec);
1392
1393         /* Ensure this is a locking_key record. */
1394         if (key.dsize != sizeof(struct file_id))
1395                 return 0;
1396
1397         lck = talloc(talloc_tos(), struct share_mode_lock);
1398         if (lck == NULL) {
1399                 return 0;
1400         }
1401
1402         blob.data = value.dptr;
1403         blob.length = value.dsize;
1404
1405         ndr_err = ndr_pull_struct_blob(
1406                 &blob, lck, lck,
1407                 (ndr_pull_flags_fn_t)ndr_pull_share_mode_lock);
1408         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1409                 DEBUG(1, ("ndr_pull_share_mode_lock failed\n"));
1410                 return 0;
1411         }
1412         for (i=0; i<lck->num_share_modes; i++) {
1413                 state->fn(&lck->share_modes[i],
1414                           lck->servicepath, lck->base_name,
1415                           state->private_data);
1416         }
1417         TALLOC_FREE(lck);
1418
1419         return 0;
1420 }
1421
1422 /*******************************************************************
1423  Call the specified function on each entry under management by the
1424  share mode system.
1425 ********************************************************************/
1426
1427 int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *,
1428                                  const char *, void *),
1429                       void *private_data)
1430 {
1431         struct forall_state state;
1432         NTSTATUS status;
1433         int count;
1434
1435         if (lock_db == NULL)
1436                 return 0;
1437
1438         state.fn = fn;
1439         state.private_data = private_data;
1440
1441         status = dbwrap_traverse_read(lock_db, traverse_fn, (void *)&state,
1442                                       &count);
1443
1444         if (!NT_STATUS_IS_OK(status)) {
1445                 return -1;
1446         } else {
1447                 return count;
1448         }
1449 }