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