Fix the build breakage by #including modules/vfs_acl_common.c
[Samba/gbeck.git] / source3 / locking / locking.c
blobfba871c704e0cb5417e82bdd462524fed165e754
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
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.
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.
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/>.
21 Revision History:
23 12 aug 96: Erik.Devriendt@te6.siemens.be
24 added support for shared memory implementation of share mode locking
26 May 1997. Jeremy Allison (jallison@whistle.com). Modified share mode
27 locking to deal with multiple share modes per open file.
29 September 1997. Jeremy Allison (jallison@whistle.com). Added oplock
30 support.
32 rewrtten completely to use new tdb code. Tridge, Dec '99
34 Added POSIX locking support. Jeremy Allison (jeremy@valinux.com), Apr. 2000.
35 Added Unix Extensions POSIX locking support. Jeremy Allison Mar 2006.
38 #include "includes.h"
40 #undef DBGC_CLASS
41 #define DBGC_CLASS DBGC_LOCKING
43 #define NO_LOCKING_COUNT (-1)
45 /* the locking database handle */
46 static struct db_context *lock_db;
48 /****************************************************************************
49 Debugging aids :-).
50 ****************************************************************************/
52 const char *lock_type_name(enum brl_type lock_type)
54 switch (lock_type) {
55 case READ_LOCK:
56 return "READ";
57 case WRITE_LOCK:
58 return "WRITE";
59 case PENDING_READ_LOCK:
60 return "PENDING_READ";
61 case PENDING_WRITE_LOCK:
62 return "PENDING_WRITE";
63 default:
64 return "other";
68 const char *lock_flav_name(enum brl_flavour lock_flav)
70 return (lock_flav == WINDOWS_LOCK) ? "WINDOWS_LOCK" : "POSIX_LOCK";
73 /****************************************************************************
74 Utility function called to see if a file region is locked.
75 Called in the read/write codepath.
76 ****************************************************************************/
78 void init_strict_lock_struct(files_struct *fsp,
79 uint32 smbpid,
80 br_off start,
81 br_off size,
82 enum brl_type lock_type,
83 struct lock_struct *plock)
85 SMB_ASSERT(lock_type == READ_LOCK || lock_type == WRITE_LOCK);
87 plock->context.smbpid = smbpid;
88 plock->context.tid = fsp->conn->cnum;
89 plock->context.pid = procid_self();
90 plock->start = start;
91 plock->size = size;
92 plock->fnum = fsp->fnum;
93 plock->lock_type = lock_type;
94 plock->lock_flav = lp_posix_cifsu_locktype(fsp);
97 bool strict_lock_default(files_struct *fsp, struct lock_struct *plock)
99 int strict_locking = lp_strict_locking(fsp->conn->params);
100 bool ret = False;
102 if (plock->size == 0) {
103 return True;
106 if (!lp_locking(fsp->conn->params) || !strict_locking) {
107 return True;
110 if (strict_locking == Auto) {
111 if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (plock->lock_type == READ_LOCK || plock->lock_type == WRITE_LOCK)) {
112 DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp_str_dbg(fsp)));
113 ret = True;
114 } else if ((fsp->oplock_type == LEVEL_II_OPLOCK) &&
115 (plock->lock_type == READ_LOCK)) {
116 DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp_str_dbg(fsp)));
117 ret = True;
118 } else {
119 struct byte_range_lock *br_lck = brl_get_locks_readonly(talloc_tos(), fsp);
120 if (!br_lck) {
121 return True;
123 ret = brl_locktest(br_lck,
124 plock->context.smbpid,
125 plock->context.pid,
126 plock->start,
127 plock->size,
128 plock->lock_type,
129 plock->lock_flav);
130 TALLOC_FREE(br_lck);
132 } else {
133 struct byte_range_lock *br_lck = brl_get_locks_readonly(talloc_tos(), fsp);
134 if (!br_lck) {
135 return True;
137 ret = brl_locktest(br_lck,
138 plock->context.smbpid,
139 plock->context.pid,
140 plock->start,
141 plock->size,
142 plock->lock_type,
143 plock->lock_flav);
144 TALLOC_FREE(br_lck);
147 DEBUG(10,("strict_lock_default: flavour = %s brl start=%.0f "
148 "len=%.0f %s for fnum %d file %s\n",
149 lock_flav_name(plock->lock_flav),
150 (double)plock->start, (double)plock->size,
151 ret ? "unlocked" : "locked",
152 plock->fnum, fsp_str_dbg(fsp)));
154 return ret;
157 void strict_unlock_default(files_struct *fsp, struct lock_struct *plock)
161 /****************************************************************************
162 Find out if a lock could be granted - return who is blocking us if we can't.
163 ****************************************************************************/
165 NTSTATUS query_lock(files_struct *fsp,
166 uint32 *psmbpid,
167 uint64_t *pcount,
168 uint64_t *poffset,
169 enum brl_type *plock_type,
170 enum brl_flavour lock_flav)
172 struct byte_range_lock *br_lck = NULL;
173 NTSTATUS status = NT_STATUS_LOCK_NOT_GRANTED;
175 if (!fsp->can_lock) {
176 return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
179 if (!lp_locking(fsp->conn->params)) {
180 return NT_STATUS_OK;
183 br_lck = brl_get_locks_readonly(talloc_tos(), fsp);
184 if (!br_lck) {
185 return NT_STATUS_NO_MEMORY;
188 status = brl_lockquery(br_lck,
189 psmbpid,
190 procid_self(),
191 poffset,
192 pcount,
193 plock_type,
194 lock_flav);
196 TALLOC_FREE(br_lck);
197 return status;
200 static void increment_current_lock_count(files_struct *fsp,
201 enum brl_flavour lock_flav)
203 if (lock_flav == WINDOWS_LOCK &&
204 fsp->current_lock_count != NO_LOCKING_COUNT) {
205 /* blocking ie. pending, locks also count here,
206 * as this is an efficiency counter to avoid checking
207 * the lock db. on close. JRA. */
209 fsp->current_lock_count++;
210 } else {
211 /* Notice that this has had a POSIX lock request.
212 * We can't count locks after this so forget them.
214 fsp->current_lock_count = NO_LOCKING_COUNT;
218 static void decrement_current_lock_count(files_struct *fsp,
219 enum brl_flavour lock_flav)
221 if (lock_flav == WINDOWS_LOCK &&
222 fsp->current_lock_count != NO_LOCKING_COUNT) {
223 SMB_ASSERT(fsp->current_lock_count > 0);
224 fsp->current_lock_count--;
228 /****************************************************************************
229 Utility function called by locking requests.
230 ****************************************************************************/
232 struct byte_range_lock *do_lock(struct messaging_context *msg_ctx,
233 files_struct *fsp,
234 uint32 lock_pid,
235 uint64_t count,
236 uint64_t offset,
237 enum brl_type lock_type,
238 enum brl_flavour lock_flav,
239 bool blocking_lock,
240 NTSTATUS *perr,
241 uint32 *plock_pid,
242 struct blocking_lock_record *blr)
244 struct byte_range_lock *br_lck = NULL;
246 if (!fsp->can_lock) {
247 *perr = fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
248 return NULL;
251 if (!lp_locking(fsp->conn->params)) {
252 *perr = NT_STATUS_OK;
253 return NULL;
256 /* NOTE! 0 byte long ranges ARE allowed and should be stored */
258 DEBUG(10,("do_lock: lock flavour %s lock type %s start=%.0f len=%.0f "
259 "blocking_lock=%s requested for fnum %d file %s\n",
260 lock_flav_name(lock_flav), lock_type_name(lock_type),
261 (double)offset, (double)count, blocking_lock ? "true" :
262 "false", fsp->fnum, fsp_str_dbg(fsp)));
264 br_lck = brl_get_locks(talloc_tos(), fsp);
265 if (!br_lck) {
266 *perr = NT_STATUS_NO_MEMORY;
267 return NULL;
270 *perr = brl_lock(msg_ctx,
271 br_lck,
272 lock_pid,
273 procid_self(),
274 offset,
275 count,
276 lock_type,
277 lock_flav,
278 blocking_lock,
279 plock_pid,
280 blr);
282 DEBUG(10, ("do_lock: returning status=%s\n", nt_errstr(*perr)));
284 increment_current_lock_count(fsp, lock_flav);
285 return br_lck;
288 /****************************************************************************
289 Utility function called by unlocking requests.
290 ****************************************************************************/
292 NTSTATUS do_unlock(struct messaging_context *msg_ctx,
293 files_struct *fsp,
294 uint32 lock_pid,
295 uint64_t count,
296 uint64_t offset,
297 enum brl_flavour lock_flav)
299 bool ok = False;
300 struct byte_range_lock *br_lck = NULL;
302 if (!fsp->can_lock) {
303 return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
306 if (!lp_locking(fsp->conn->params)) {
307 return NT_STATUS_OK;
310 DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for fnum %d file %s\n",
311 (double)offset, (double)count, fsp->fnum,
312 fsp_str_dbg(fsp)));
314 br_lck = brl_get_locks(talloc_tos(), fsp);
315 if (!br_lck) {
316 return NT_STATUS_NO_MEMORY;
319 ok = brl_unlock(msg_ctx,
320 br_lck,
321 lock_pid,
322 procid_self(),
323 offset,
324 count,
325 lock_flav);
327 TALLOC_FREE(br_lck);
329 if (!ok) {
330 DEBUG(10,("do_unlock: returning ERRlock.\n" ));
331 return NT_STATUS_RANGE_NOT_LOCKED;
334 decrement_current_lock_count(fsp, lock_flav);
335 return NT_STATUS_OK;
338 /****************************************************************************
339 Cancel any pending blocked locks.
340 ****************************************************************************/
342 NTSTATUS do_lock_cancel(files_struct *fsp,
343 uint32 lock_pid,
344 uint64_t count,
345 uint64_t offset,
346 enum brl_flavour lock_flav,
347 struct blocking_lock_record *blr)
349 bool ok = False;
350 struct byte_range_lock *br_lck = NULL;
352 if (!fsp->can_lock) {
353 return fsp->is_directory ?
354 NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
357 if (!lp_locking(fsp->conn->params)) {
358 return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
361 DEBUG(10,("do_lock_cancel: cancel start=%.0f len=%.0f requested for fnum %d file %s\n",
362 (double)offset, (double)count, fsp->fnum,
363 fsp_str_dbg(fsp)));
365 br_lck = brl_get_locks(talloc_tos(), fsp);
366 if (!br_lck) {
367 return NT_STATUS_NO_MEMORY;
370 ok = brl_lock_cancel(br_lck,
371 lock_pid,
372 procid_self(),
373 offset,
374 count,
375 lock_flav,
376 blr);
378 TALLOC_FREE(br_lck);
380 if (!ok) {
381 DEBUG(10,("do_lock_cancel: returning ERRcancelviolation.\n" ));
382 return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
385 decrement_current_lock_count(fsp, lock_flav);
386 return NT_STATUS_OK;
389 /****************************************************************************
390 Remove any locks on this fd. Called from file_close().
391 ****************************************************************************/
393 void locking_close_file(struct messaging_context *msg_ctx,
394 files_struct *fsp)
396 struct byte_range_lock *br_lck;
398 if (!lp_locking(fsp->conn->params)) {
399 return;
402 /* If we have not outstanding locks or pending
403 * locks then we don't need to look in the lock db.
406 if (fsp->current_lock_count == 0) {
407 return;
410 br_lck = brl_get_locks(talloc_tos(),fsp);
412 if (br_lck) {
413 cancel_pending_lock_requests_by_fid(fsp, br_lck);
414 brl_close_fnum(msg_ctx, br_lck);
415 TALLOC_FREE(br_lck);
419 /****************************************************************************
420 Initialise the locking functions.
421 ****************************************************************************/
423 static bool locking_init_internal(bool read_only)
425 brl_init(read_only);
427 if (lock_db)
428 return True;
430 lock_db = db_open(NULL, lock_path("locking.tdb"),
431 lp_open_files_db_hash_size(),
432 TDB_DEFAULT|TDB_VOLATILE|TDB_CLEAR_IF_FIRST,
433 read_only?O_RDONLY:O_RDWR|O_CREAT, 0644);
435 if (!lock_db) {
436 DEBUG(0,("ERROR: Failed to initialise locking database\n"));
437 return False;
440 if (!posix_locking_init(read_only))
441 return False;
443 return True;
446 bool locking_init(void)
448 return locking_init_internal(false);
451 bool locking_init_readonly(void)
453 return locking_init_internal(true);
456 /*******************************************************************
457 Deinitialize the share_mode management.
458 ******************************************************************/
460 bool locking_end(void)
462 brl_shutdown();
463 TALLOC_FREE(lock_db);
464 return true;
467 /*******************************************************************
468 Form a static locking key for a dev/inode pair.
469 ******************************************************************/
471 static TDB_DATA locking_key(const struct file_id *id, struct file_id *tmp)
473 *tmp = *id;
474 return make_tdb_data((const uint8_t *)tmp, sizeof(*tmp));
477 /*******************************************************************
478 Print out a share mode.
479 ********************************************************************/
481 char *share_mode_str(TALLOC_CTX *ctx, int num, const struct share_mode_entry *e)
483 return talloc_asprintf(ctx, "share_mode_entry[%d]: %s "
484 "pid = %s, share_access = 0x%x, private_options = 0x%x, "
485 "access_mask = 0x%x, mid = 0x%x, type= 0x%x, gen_id = %lu, "
486 "uid = %u, flags = %u, file_id %s",
487 num,
488 e->op_type == UNUSED_SHARE_MODE_ENTRY ? "UNUSED" : "",
489 procid_str_static(&e->pid),
490 e->share_access, e->private_options,
491 e->access_mask, e->op_mid, e->op_type, e->share_file_id,
492 (unsigned int)e->uid, (unsigned int)e->flags,
493 file_id_string_tos(&e->id));
496 /*******************************************************************
497 Print out a share mode table.
498 ********************************************************************/
500 static void print_share_mode_table(struct locking_data *data)
502 int num_share_modes = data->u.s.num_share_mode_entries;
503 struct share_mode_entry *shares =
504 (struct share_mode_entry *)(data + 1);
505 int i;
507 for (i = 0; i < num_share_modes; i++) {
508 struct share_mode_entry entry;
509 char *str;
512 * We need to memcpy the entry here due to alignment
513 * restrictions that are not met when directly accessing
514 * shares[i]
517 memcpy(&entry, &shares[i], sizeof(struct share_mode_entry));
518 str = share_mode_str(talloc_tos(), i, &entry);
520 DEBUG(10,("print_share_mode_table: %s\n", str ? str : ""));
521 TALLOC_FREE(str);
525 /*******************************************************************
526 Get all share mode entries for a dev/inode pair.
527 ********************************************************************/
529 static bool parse_share_modes(const TDB_DATA dbuf, struct share_mode_lock *lck)
531 struct locking_data data;
532 int i;
534 if (dbuf.dsize < sizeof(struct locking_data)) {
535 smb_panic("parse_share_modes: buffer too short");
538 memcpy(&data, dbuf.dptr, sizeof(data));
540 lck->delete_on_close = data.u.s.delete_on_close;
541 lck->old_write_time = data.u.s.old_write_time;
542 lck->changed_write_time = data.u.s.changed_write_time;
543 lck->num_share_modes = data.u.s.num_share_mode_entries;
545 DEBUG(10, ("parse_share_modes: delete_on_close: %d, owrt: %s, "
546 "cwrt: %s, tok: %u, num_share_modes: %d\n",
547 lck->delete_on_close,
548 timestring(debug_ctx(),
549 convert_timespec_to_time_t(lck->old_write_time)),
550 timestring(debug_ctx(),
551 convert_timespec_to_time_t(
552 lck->changed_write_time)),
553 (unsigned int)data.u.s.delete_token_size,
554 lck->num_share_modes));
556 if ((lck->num_share_modes < 0) || (lck->num_share_modes > 1000000)) {
557 DEBUG(0, ("invalid number of share modes: %d\n",
558 lck->num_share_modes));
559 smb_panic("parse_share_modes: invalid number of share modes");
562 lck->share_modes = NULL;
564 if (lck->num_share_modes != 0) {
566 if (dbuf.dsize < (sizeof(struct locking_data) +
567 (lck->num_share_modes *
568 sizeof(struct share_mode_entry)))) {
569 smb_panic("parse_share_modes: buffer too short");
572 lck->share_modes = (struct share_mode_entry *)
573 TALLOC_MEMDUP(lck,
574 dbuf.dptr+sizeof(struct locking_data),
575 lck->num_share_modes *
576 sizeof(struct share_mode_entry));
578 if (lck->share_modes == NULL) {
579 smb_panic("parse_share_modes: talloc failed");
583 /* Get any delete token. */
584 if (data.u.s.delete_token_size) {
585 uint8 *p = dbuf.dptr + sizeof(struct locking_data) +
586 (lck->num_share_modes *
587 sizeof(struct share_mode_entry));
589 if ((data.u.s.delete_token_size < sizeof(uid_t) + sizeof(gid_t)) ||
590 ((data.u.s.delete_token_size - sizeof(uid_t)) % sizeof(gid_t)) != 0) {
591 DEBUG(0, ("parse_share_modes: invalid token size %d\n",
592 data.u.s.delete_token_size));
593 smb_panic("parse_share_modes: invalid token size");
596 lck->delete_token = TALLOC_P(lck, UNIX_USER_TOKEN);
597 if (!lck->delete_token) {
598 smb_panic("parse_share_modes: talloc failed");
601 /* Copy out the uid and gid. */
602 memcpy(&lck->delete_token->uid, p, sizeof(uid_t));
603 p += sizeof(uid_t);
604 memcpy(&lck->delete_token->gid, p, sizeof(gid_t));
605 p += sizeof(gid_t);
607 /* Any supplementary groups ? */
608 lck->delete_token->ngroups = (data.u.s.delete_token_size > (sizeof(uid_t) + sizeof(gid_t))) ?
609 ((data.u.s.delete_token_size -
610 (sizeof(uid_t) + sizeof(gid_t)))/sizeof(gid_t)) : 0;
612 if (lck->delete_token->ngroups) {
613 /* Make this a talloc child of lck->delete_token. */
614 lck->delete_token->groups = TALLOC_ARRAY(lck->delete_token, gid_t,
615 lck->delete_token->ngroups);
616 if (!lck->delete_token) {
617 smb_panic("parse_share_modes: talloc failed");
620 for (i = 0; i < lck->delete_token->ngroups; i++) {
621 memcpy(&lck->delete_token->groups[i], p, sizeof(gid_t));
622 p += sizeof(gid_t);
626 } else {
627 lck->delete_token = NULL;
630 /* Save off the associated service path and filename. */
631 lck->servicepath = (const char *)dbuf.dptr + sizeof(struct locking_data) +
632 (lck->num_share_modes * sizeof(struct share_mode_entry)) +
633 data.u.s.delete_token_size;
635 lck->base_name = (const char *)dbuf.dptr + sizeof(struct locking_data) +
636 (lck->num_share_modes * sizeof(struct share_mode_entry)) +
637 data.u.s.delete_token_size +
638 strlen(lck->servicepath) + 1;
640 lck->stream_name = (const char *)dbuf.dptr + sizeof(struct locking_data) +
641 (lck->num_share_modes * sizeof(struct share_mode_entry)) +
642 data.u.s.delete_token_size +
643 strlen(lck->servicepath) + 1 +
644 strlen(lck->base_name) + 1;
647 * Ensure that each entry has a real process attached.
650 for (i = 0; i < lck->num_share_modes; i++) {
651 struct share_mode_entry *entry_p = &lck->share_modes[i];
652 char *str = NULL;
653 if (DEBUGLEVEL >= 10) {
654 str = share_mode_str(NULL, i, entry_p);
656 DEBUG(10,("parse_share_modes: %s\n",
657 str ? str : ""));
658 if (!process_exists(entry_p->pid)) {
659 DEBUG(10,("parse_share_modes: deleted %s\n",
660 str ? str : ""));
661 entry_p->op_type = UNUSED_SHARE_MODE_ENTRY;
662 lck->modified = True;
664 TALLOC_FREE(str);
667 return True;
670 static TDB_DATA unparse_share_modes(const struct share_mode_lock *lck)
672 TDB_DATA result;
673 int num_valid = 0;
674 int i;
675 struct locking_data *data;
676 ssize_t offset;
677 ssize_t sp_len, bn_len, sn_len;
678 uint32 delete_token_size;
680 result.dptr = NULL;
681 result.dsize = 0;
683 for (i=0; i<lck->num_share_modes; i++) {
684 if (!is_unused_share_mode_entry(&lck->share_modes[i])) {
685 num_valid += 1;
689 if (num_valid == 0) {
690 return result;
693 sp_len = strlen(lck->servicepath);
694 bn_len = strlen(lck->base_name);
695 sn_len = lck->stream_name != NULL ? strlen(lck->stream_name) : 0;
697 delete_token_size = (lck->delete_token ?
698 (sizeof(uid_t) + sizeof(gid_t) + (lck->delete_token->ngroups*sizeof(gid_t))) : 0);
700 result.dsize = sizeof(*data) +
701 lck->num_share_modes * sizeof(struct share_mode_entry) +
702 delete_token_size +
703 sp_len + 1 +
704 bn_len + 1 +
705 sn_len + 1;
706 result.dptr = TALLOC_ARRAY(lck, uint8, result.dsize);
708 if (result.dptr == NULL) {
709 smb_panic("talloc failed");
712 data = (struct locking_data *)result.dptr;
713 ZERO_STRUCTP(data);
714 data->u.s.num_share_mode_entries = lck->num_share_modes;
715 data->u.s.delete_on_close = lck->delete_on_close;
716 data->u.s.old_write_time = lck->old_write_time;
717 data->u.s.changed_write_time = lck->changed_write_time;
718 data->u.s.delete_token_size = delete_token_size;
720 DEBUG(10,("unparse_share_modes: del: %d, owrt: %s cwrt: %s, tok: %u, "
721 "num: %d\n", data->u.s.delete_on_close,
722 timestring(debug_ctx(),
723 convert_timespec_to_time_t(lck->old_write_time)),
724 timestring(debug_ctx(),
725 convert_timespec_to_time_t(
726 lck->changed_write_time)),
727 (unsigned int)data->u.s.delete_token_size,
728 data->u.s.num_share_mode_entries));
730 memcpy(result.dptr + sizeof(*data), lck->share_modes,
731 sizeof(struct share_mode_entry)*lck->num_share_modes);
732 offset = sizeof(*data) +
733 sizeof(struct share_mode_entry)*lck->num_share_modes;
735 /* Store any delete on close token. */
736 if (lck->delete_token) {
737 uint8 *p = result.dptr + offset;
739 memcpy(p, &lck->delete_token->uid, sizeof(uid_t));
740 p += sizeof(uid_t);
742 memcpy(p, &lck->delete_token->gid, sizeof(gid_t));
743 p += sizeof(gid_t);
745 for (i = 0; i < lck->delete_token->ngroups; i++) {
746 memcpy(p, &lck->delete_token->groups[i], sizeof(gid_t));
747 p += sizeof(gid_t);
749 offset = p - result.dptr;
752 safe_strcpy((char *)result.dptr + offset, lck->servicepath,
753 result.dsize - offset - 1);
754 offset += sp_len + 1;
755 safe_strcpy((char *)result.dptr + offset, lck->base_name,
756 result.dsize - offset - 1);
757 offset += bn_len + 1;
758 safe_strcpy((char *)result.dptr + offset, lck->stream_name,
759 result.dsize - offset - 1);
761 if (DEBUGLEVEL >= 10) {
762 print_share_mode_table(data);
765 return result;
768 static int share_mode_lock_destructor(struct share_mode_lock *lck)
770 NTSTATUS status;
771 TDB_DATA data;
773 if (!lck->modified) {
774 return 0;
777 data = unparse_share_modes(lck);
779 if (data.dptr == NULL) {
780 if (!lck->fresh) {
781 /* There has been an entry before, delete it */
783 status = lck->record->delete_rec(lck->record);
784 if (!NT_STATUS_IS_OK(status)) {
785 DEBUG(0, ("delete_rec returned %s\n",
786 nt_errstr(status)));
787 smb_panic("could not delete share entry");
790 goto done;
793 status = lck->record->store(lck->record, data, TDB_REPLACE);
794 if (!NT_STATUS_IS_OK(status)) {
795 DEBUG(0, ("store returned %s\n", nt_errstr(status)));
796 smb_panic("could not store share mode entry");
799 done:
801 return 0;
804 static bool fill_share_mode_lock(struct share_mode_lock *lck,
805 struct file_id id,
806 const char *servicepath,
807 const struct smb_filename *smb_fname,
808 TDB_DATA share_mode_data,
809 const struct timespec *old_write_time)
811 /* Ensure we set every field here as the destructor must be
812 valid even if parse_share_modes fails. */
814 lck->servicepath = NULL;
815 lck->base_name = NULL;
816 lck->stream_name = NULL;
817 lck->id = id;
818 lck->num_share_modes = 0;
819 lck->share_modes = NULL;
820 lck->delete_token = NULL;
821 lck->delete_on_close = False;
822 ZERO_STRUCT(lck->old_write_time);
823 ZERO_STRUCT(lck->changed_write_time);
824 lck->fresh = False;
825 lck->modified = False;
827 lck->fresh = (share_mode_data.dptr == NULL);
829 if (lck->fresh) {
830 bool has_stream;
831 if (smb_fname == NULL || servicepath == NULL
832 || old_write_time == NULL) {
833 return False;
836 has_stream = smb_fname->stream_name != NULL;
838 lck->base_name = talloc_strdup(lck, smb_fname->base_name);
839 lck->stream_name = talloc_strdup(lck, smb_fname->stream_name);
840 lck->servicepath = talloc_strdup(lck, servicepath);
841 if (lck->base_name == NULL ||
842 (has_stream && lck->stream_name == NULL) ||
843 lck->servicepath == NULL) {
844 DEBUG(0, ("talloc failed\n"));
845 return False;
847 lck->old_write_time = *old_write_time;
848 } else {
849 if (!parse_share_modes(share_mode_data, lck)) {
850 DEBUG(0, ("Could not parse share modes\n"));
851 return False;
855 return True;
858 struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
859 const struct file_id id,
860 const char *servicepath,
861 const struct smb_filename *smb_fname,
862 const struct timespec *old_write_time)
864 struct share_mode_lock *lck;
865 struct file_id tmp;
866 TDB_DATA key = locking_key(&id, &tmp);
868 if (!(lck = TALLOC_P(mem_ctx, struct share_mode_lock))) {
869 DEBUG(0, ("talloc failed\n"));
870 return NULL;
873 if (!(lck->record = lock_db->fetch_locked(lock_db, lck, key))) {
874 DEBUG(3, ("Could not lock share entry\n"));
875 TALLOC_FREE(lck);
876 return NULL;
879 if (!fill_share_mode_lock(lck, id, servicepath, smb_fname,
880 lck->record->value, old_write_time)) {
881 DEBUG(3, ("fill_share_mode_lock failed\n"));
882 TALLOC_FREE(lck);
883 return NULL;
886 talloc_set_destructor(lck, share_mode_lock_destructor);
888 return lck;
891 struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx,
892 const struct file_id id)
894 struct share_mode_lock *lck;
895 struct file_id tmp;
896 TDB_DATA key = locking_key(&id, &tmp);
897 TDB_DATA data;
899 if (!(lck = TALLOC_P(mem_ctx, struct share_mode_lock))) {
900 DEBUG(0, ("talloc failed\n"));
901 return NULL;
904 if (lock_db->fetch(lock_db, lck, key, &data) == -1) {
905 DEBUG(3, ("Could not fetch share entry\n"));
906 TALLOC_FREE(lck);
907 return NULL;
910 if (!fill_share_mode_lock(lck, id, NULL, NULL, data, NULL)) {
911 DEBUG(10, ("fetch_share_mode_unlocked: no share_mode record "
912 "around (file not open)\n"));
913 TALLOC_FREE(lck);
914 return NULL;
917 return lck;
920 /*******************************************************************
921 Sets the service name and filename for rename.
922 At this point we emit "file renamed" messages to all
923 process id's that have this file open.
924 Based on an initial code idea from SATOH Fumiyasu <fumiya@samba.gr.jp>
925 ********************************************************************/
927 bool rename_share_filename(struct messaging_context *msg_ctx,
928 struct share_mode_lock *lck,
929 const char *servicepath,
930 const struct smb_filename *smb_fname_dst)
932 size_t sp_len;
933 size_t bn_len;
934 size_t sn_len;
935 size_t msg_len;
936 char *frm = NULL;
937 int i;
938 bool strip_two_chars = false;
939 bool has_stream = smb_fname_dst->stream_name != NULL;
941 DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n",
942 servicepath, smb_fname_dst->base_name));
945 * rename_internal_fsp() and rename_internals() add './' to
946 * head of newname if newname does not contain a '/'.
948 if (smb_fname_dst->base_name[0] &&
949 smb_fname_dst->base_name[1] &&
950 smb_fname_dst->base_name[0] == '.' &&
951 smb_fname_dst->base_name[1] == '/') {
952 strip_two_chars = true;
955 lck->servicepath = talloc_strdup(lck, servicepath);
956 lck->base_name = talloc_strdup(lck, smb_fname_dst->base_name +
957 (strip_two_chars ? 2 : 0));
958 lck->stream_name = talloc_strdup(lck, smb_fname_dst->stream_name);
959 if (lck->base_name == NULL ||
960 (has_stream && lck->stream_name == NULL) ||
961 lck->servicepath == NULL) {
962 DEBUG(0, ("rename_share_filename: talloc failed\n"));
963 return False;
965 lck->modified = True;
967 sp_len = strlen(lck->servicepath);
968 bn_len = strlen(lck->base_name);
969 sn_len = has_stream ? strlen(lck->stream_name) : 0;
971 msg_len = MSG_FILE_RENAMED_MIN_SIZE + sp_len + 1 + bn_len + 1 +
972 sn_len + 1;
974 /* Set up the name changed message. */
975 frm = TALLOC_ARRAY(lck, char, msg_len);
976 if (!frm) {
977 return False;
980 push_file_id_24(frm, &lck->id);
982 DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len ));
984 safe_strcpy(&frm[24], lck->servicepath, sp_len);
985 safe_strcpy(&frm[24 + sp_len + 1], lck->base_name, bn_len);
986 safe_strcpy(&frm[24 + sp_len + 1 + bn_len + 1], lck->stream_name,
987 sn_len);
989 /* Send the messages. */
990 for (i=0; i<lck->num_share_modes; i++) {
991 struct share_mode_entry *se = &lck->share_modes[i];
992 if (!is_valid_share_mode_entry(se)) {
993 continue;
995 /* But not to ourselves... */
996 if (procid_is_me(&se->pid)) {
997 continue;
1000 DEBUG(10,("rename_share_filename: sending rename message to "
1001 "pid %s file_id %s sharepath %s base_name %s "
1002 "stream_name %s\n",
1003 procid_str_static(&se->pid),
1004 file_id_string_tos(&lck->id),
1005 lck->servicepath, lck->base_name,
1006 has_stream ? lck->stream_name : ""));
1008 messaging_send_buf(msg_ctx, se->pid, MSG_SMB_FILE_RENAME,
1009 (uint8 *)frm, msg_len);
1012 return True;
1015 void get_file_infos(struct file_id id,
1016 bool *delete_on_close,
1017 struct timespec *write_time)
1019 struct share_mode_lock *lck;
1021 if (delete_on_close) {
1022 *delete_on_close = false;
1025 if (write_time) {
1026 ZERO_STRUCTP(write_time);
1029 if (!(lck = fetch_share_mode_unlocked(talloc_tos(), id))) {
1030 return;
1033 if (delete_on_close) {
1034 *delete_on_close = lck->delete_on_close;
1037 if (write_time) {
1038 struct timespec wt;
1040 wt = lck->changed_write_time;
1041 if (null_timespec(wt)) {
1042 wt = lck->old_write_time;
1045 *write_time = wt;
1048 TALLOC_FREE(lck);
1051 bool is_valid_share_mode_entry(const struct share_mode_entry *e)
1053 int num_props = 0;
1055 if (e->op_type == UNUSED_SHARE_MODE_ENTRY) {
1056 /* cope with dead entries from the process not
1057 existing. These should not be considered valid,
1058 otherwise we end up doing zero timeout sharing
1059 violation */
1060 return False;
1063 num_props += ((e->op_type == NO_OPLOCK) ? 1 : 0);
1064 num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0);
1065 num_props += (LEVEL_II_OPLOCK_TYPE(e->op_type) ? 1 : 0);
1067 SMB_ASSERT(num_props <= 1);
1068 return (num_props != 0);
1071 bool is_deferred_open_entry(const struct share_mode_entry *e)
1073 return (e->op_type == DEFERRED_OPEN_ENTRY);
1076 bool is_unused_share_mode_entry(const struct share_mode_entry *e)
1078 return (e->op_type == UNUSED_SHARE_MODE_ENTRY);
1081 /*******************************************************************
1082 Fill a share mode entry.
1083 ********************************************************************/
1085 static void fill_share_mode_entry(struct share_mode_entry *e,
1086 files_struct *fsp,
1087 uid_t uid, uint16 mid, uint16 op_type)
1089 ZERO_STRUCTP(e);
1090 e->pid = procid_self();
1091 e->share_access = fsp->share_access;
1092 e->private_options = fsp->fh->private_options;
1093 e->access_mask = fsp->access_mask;
1094 e->op_mid = mid;
1095 e->op_type = op_type;
1096 e->time.tv_sec = fsp->open_time.tv_sec;
1097 e->time.tv_usec = fsp->open_time.tv_usec;
1098 e->id = fsp->file_id;
1099 e->share_file_id = fsp->fh->gen_id;
1100 e->uid = (uint32)uid;
1101 e->flags = fsp->posix_open ? SHARE_MODE_FLAG_POSIX_OPEN : 0;
1104 static void fill_deferred_open_entry(struct share_mode_entry *e,
1105 const struct timeval request_time,
1106 struct file_id id, uint16 mid)
1108 ZERO_STRUCTP(e);
1109 e->pid = procid_self();
1110 e->op_mid = mid;
1111 e->op_type = DEFERRED_OPEN_ENTRY;
1112 e->time.tv_sec = request_time.tv_sec;
1113 e->time.tv_usec = request_time.tv_usec;
1114 e->id = id;
1115 e->uid = (uint32)-1;
1116 e->flags = 0;
1119 static void add_share_mode_entry(struct share_mode_lock *lck,
1120 const struct share_mode_entry *entry)
1122 int i;
1124 for (i=0; i<lck->num_share_modes; i++) {
1125 struct share_mode_entry *e = &lck->share_modes[i];
1126 if (is_unused_share_mode_entry(e)) {
1127 *e = *entry;
1128 break;
1132 if (i == lck->num_share_modes) {
1133 /* No unused entry found */
1134 ADD_TO_ARRAY(lck, struct share_mode_entry, *entry,
1135 &lck->share_modes, &lck->num_share_modes);
1137 lck->modified = True;
1140 void set_share_mode(struct share_mode_lock *lck, files_struct *fsp,
1141 uid_t uid, uint16 mid, uint16 op_type)
1143 struct share_mode_entry entry;
1144 fill_share_mode_entry(&entry, fsp, uid, mid, op_type);
1145 add_share_mode_entry(lck, &entry);
1148 void add_deferred_open(struct share_mode_lock *lck, uint16 mid,
1149 struct timeval request_time,
1150 struct file_id id)
1152 struct share_mode_entry entry;
1153 fill_deferred_open_entry(&entry, request_time, id, mid);
1154 add_share_mode_entry(lck, &entry);
1157 /*******************************************************************
1158 Check if two share mode entries are identical, ignoring oplock
1159 and mid info and desired_access. (Removed paranoia test - it's
1160 not automatically a logic error if they are identical. JRA.)
1161 ********************************************************************/
1163 static bool share_modes_identical(struct share_mode_entry *e1,
1164 struct share_mode_entry *e2)
1166 /* We used to check for e1->share_access == e2->share_access here
1167 as well as the other fields but 2 different DOS or FCB opens
1168 sharing the same share mode entry may validly differ in
1169 fsp->share_access field. */
1171 return (procid_equal(&e1->pid, &e2->pid) &&
1172 file_id_equal(&e1->id, &e2->id) &&
1173 e1->share_file_id == e2->share_file_id );
1176 static bool deferred_open_identical(struct share_mode_entry *e1,
1177 struct share_mode_entry *e2)
1179 return (procid_equal(&e1->pid, &e2->pid) &&
1180 (e1->op_mid == e2->op_mid) &&
1181 file_id_equal(&e1->id, &e2->id));
1184 static struct share_mode_entry *find_share_mode_entry(struct share_mode_lock *lck,
1185 struct share_mode_entry *entry)
1187 int i;
1189 for (i=0; i<lck->num_share_modes; i++) {
1190 struct share_mode_entry *e = &lck->share_modes[i];
1191 if (is_valid_share_mode_entry(entry) &&
1192 is_valid_share_mode_entry(e) &&
1193 share_modes_identical(e, entry)) {
1194 return e;
1196 if (is_deferred_open_entry(entry) &&
1197 is_deferred_open_entry(e) &&
1198 deferred_open_identical(e, entry)) {
1199 return e;
1202 return NULL;
1205 /*******************************************************************
1206 Del the share mode of a file for this process. Return the number of
1207 entries left.
1208 ********************************************************************/
1210 bool del_share_mode(struct share_mode_lock *lck, files_struct *fsp)
1212 struct share_mode_entry entry, *e;
1214 /* Don't care about the pid owner being correct here - just a search. */
1215 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1217 e = find_share_mode_entry(lck, &entry);
1218 if (e == NULL) {
1219 return False;
1222 e->op_type = UNUSED_SHARE_MODE_ENTRY;
1223 lck->modified = True;
1224 return True;
1227 void del_deferred_open_entry(struct share_mode_lock *lck, uint16 mid)
1229 struct share_mode_entry entry, *e;
1231 fill_deferred_open_entry(&entry, timeval_zero(),
1232 lck->id, mid);
1234 e = find_share_mode_entry(lck, &entry);
1235 if (e == NULL) {
1236 return;
1239 e->op_type = UNUSED_SHARE_MODE_ENTRY;
1240 lck->modified = True;
1243 /*******************************************************************
1244 Remove an oplock mid and mode entry from a share mode.
1245 ********************************************************************/
1247 bool remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
1249 struct share_mode_entry entry, *e;
1251 /* Don't care about the pid owner being correct here - just a search. */
1252 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1254 e = find_share_mode_entry(lck, &entry);
1255 if (e == NULL) {
1256 return False;
1259 e->op_mid = 0;
1260 if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1262 * Going from exclusive or batch,
1263 * we always go through FAKE_LEVEL_II
1264 * first.
1266 e->op_type = FAKE_LEVEL_II_OPLOCK;
1267 } else {
1268 e->op_type = NO_OPLOCK;
1270 lck->modified = True;
1271 return True;
1274 /*******************************************************************
1275 Downgrade a oplock type from exclusive to level II.
1276 ********************************************************************/
1278 bool downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
1280 struct share_mode_entry entry, *e;
1282 /* Don't care about the pid owner being correct here - just a search. */
1283 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1285 e = find_share_mode_entry(lck, &entry);
1286 if (e == NULL) {
1287 return False;
1290 e->op_type = LEVEL_II_OPLOCK;
1291 lck->modified = True;
1292 return True;
1295 /****************************************************************************
1296 Deal with the internal needs of setting the delete on close flag. Note that
1297 as the tdb locking is recursive, it is safe to call this from within
1298 open_file_ntcreate. JRA.
1299 ****************************************************************************/
1301 NTSTATUS can_set_delete_on_close(files_struct *fsp, bool delete_on_close,
1302 uint32 dosmode)
1304 if (!delete_on_close) {
1305 return NT_STATUS_OK;
1309 * Only allow delete on close for writable files.
1312 if ((dosmode & aRONLY) &&
1313 !lp_delete_readonly(SNUM(fsp->conn))) {
1314 DEBUG(10,("can_set_delete_on_close: file %s delete on close "
1315 "flag set but file attribute is readonly.\n",
1316 fsp_str_dbg(fsp)));
1317 return NT_STATUS_CANNOT_DELETE;
1321 * Only allow delete on close for writable shares.
1324 if (!CAN_WRITE(fsp->conn)) {
1325 DEBUG(10,("can_set_delete_on_close: file %s delete on "
1326 "close flag set but write access denied on share.\n",
1327 fsp_str_dbg(fsp)));
1328 return NT_STATUS_ACCESS_DENIED;
1332 * Only allow delete on close for files/directories opened with delete
1333 * intent.
1336 if (!(fsp->access_mask & DELETE_ACCESS)) {
1337 DEBUG(10,("can_set_delete_on_close: file %s delete on "
1338 "close flag set but delete access denied.\n",
1339 fsp_str_dbg(fsp)));
1340 return NT_STATUS_ACCESS_DENIED;
1343 /* Don't allow delete on close for non-empty directories. */
1344 if (fsp->is_directory) {
1345 SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name));
1346 return can_delete_directory(fsp->conn,
1347 fsp->fsp_name->base_name);
1350 return NT_STATUS_OK;
1353 /*************************************************************************
1354 Return a talloced copy of a UNIX_USER_TOKEN. NULL on fail.
1355 (Should this be in locking.c.... ?).
1356 *************************************************************************/
1358 static UNIX_USER_TOKEN *copy_unix_token(TALLOC_CTX *ctx, const UNIX_USER_TOKEN *tok)
1360 UNIX_USER_TOKEN *cpy;
1362 if (tok == NULL) {
1363 return NULL;
1366 cpy = TALLOC_P(ctx, UNIX_USER_TOKEN);
1367 if (!cpy) {
1368 return NULL;
1371 cpy->uid = tok->uid;
1372 cpy->gid = tok->gid;
1373 cpy->ngroups = tok->ngroups;
1374 if (tok->ngroups) {
1375 /* Make this a talloc child of cpy. */
1376 cpy->groups = TALLOC_ARRAY(cpy, gid_t, tok->ngroups);
1377 if (!cpy->groups) {
1378 return NULL;
1380 memcpy(cpy->groups, tok->groups, tok->ngroups * sizeof(gid_t));
1382 return cpy;
1385 /****************************************************************************
1386 Replace the delete on close token.
1387 ****************************************************************************/
1389 void set_delete_on_close_token(struct share_mode_lock *lck, const UNIX_USER_TOKEN *tok)
1391 TALLOC_FREE(lck->delete_token); /* Also deletes groups... */
1393 /* Copy the new token (can be NULL). */
1394 lck->delete_token = copy_unix_token(lck, tok);
1395 lck->modified = True;
1398 /****************************************************************************
1399 Sets the delete on close flag over all share modes on this file.
1400 Modify the share mode entry for all files open
1401 on this device and inode to tell other smbds we have
1402 changed the delete on close flag. This will be noticed
1403 in the close code, the last closer will delete the file
1404 if flag is set.
1405 This makes a copy of any UNIX_USER_TOKEN into the
1406 lck entry. This function is used when the lock is already granted.
1407 ****************************************************************************/
1409 void set_delete_on_close_lck(struct share_mode_lock *lck, bool delete_on_close, const UNIX_USER_TOKEN *tok)
1411 if (lck->delete_on_close != delete_on_close) {
1412 set_delete_on_close_token(lck, tok);
1413 lck->delete_on_close = delete_on_close;
1414 if (delete_on_close) {
1415 SMB_ASSERT(lck->delete_token != NULL);
1417 lck->modified = True;
1421 bool set_delete_on_close(files_struct *fsp, bool delete_on_close, const UNIX_USER_TOKEN *tok)
1423 UNIX_USER_TOKEN *tok_copy = NULL;
1424 struct share_mode_lock *lck;
1426 DEBUG(10,("set_delete_on_close: %s delete on close flag for "
1427 "fnum = %d, file %s\n",
1428 delete_on_close ? "Adding" : "Removing", fsp->fnum,
1429 fsp_str_dbg(fsp)));
1431 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
1432 NULL);
1433 if (lck == NULL) {
1434 return False;
1437 if (fsp->conn->admin_user) {
1438 tok_copy = copy_unix_token(lck, tok);
1439 if (tok_copy == NULL) {
1440 TALLOC_FREE(lck);
1441 return false;
1443 tok_copy->uid = (uid_t)0;
1444 tok = tok_copy;
1447 set_delete_on_close_lck(lck, delete_on_close, tok);
1449 if (fsp->is_directory) {
1450 SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name));
1451 send_stat_cache_delete_message(fsp->fsp_name->base_name);
1454 TALLOC_FREE(lck);
1455 return True;
1458 bool set_sticky_write_time(struct file_id fileid, struct timespec write_time)
1460 struct share_mode_lock *lck;
1462 DEBUG(5,("set_sticky_write_time: %s id=%s\n",
1463 timestring(debug_ctx(),
1464 convert_timespec_to_time_t(write_time)),
1465 file_id_string_tos(&fileid)));
1467 lck = get_share_mode_lock(NULL, fileid, NULL, NULL, NULL);
1468 if (lck == NULL) {
1469 return False;
1472 if (timespec_compare(&lck->changed_write_time, &write_time) != 0) {
1473 lck->modified = True;
1474 lck->changed_write_time = write_time;
1477 TALLOC_FREE(lck);
1478 return True;
1481 bool set_write_time(struct file_id fileid, struct timespec write_time)
1483 struct share_mode_lock *lck;
1485 DEBUG(5,("set_write_time: %s id=%s\n",
1486 timestring(debug_ctx(),
1487 convert_timespec_to_time_t(write_time)),
1488 file_id_string_tos(&fileid)));
1490 lck = get_share_mode_lock(NULL, fileid, NULL, NULL, NULL);
1491 if (lck == NULL) {
1492 return False;
1495 if (timespec_compare(&lck->old_write_time, &write_time) != 0) {
1496 lck->modified = True;
1497 lck->old_write_time = write_time;
1500 TALLOC_FREE(lck);
1501 return True;
1505 struct forall_state {
1506 void (*fn)(const struct share_mode_entry *entry,
1507 const char *sharepath,
1508 const char *fname,
1509 void *private_data);
1510 void *private_data;
1513 static int traverse_fn(struct db_record *rec, void *_state)
1515 struct forall_state *state = (struct forall_state *)_state;
1516 struct locking_data *data;
1517 struct share_mode_entry *shares;
1518 const char *sharepath;
1519 const char *fname;
1520 int i;
1522 /* Ensure this is a locking_key record. */
1523 if (rec->key.dsize != sizeof(struct file_id))
1524 return 0;
1526 data = (struct locking_data *)rec->value.dptr;
1527 shares = (struct share_mode_entry *)(rec->value.dptr + sizeof(*data));
1528 sharepath = (const char *)rec->value.dptr + sizeof(*data) +
1529 data->u.s.num_share_mode_entries*sizeof(*shares) +
1530 data->u.s.delete_token_size;
1531 fname = (const char *)rec->value.dptr + sizeof(*data) +
1532 data->u.s.num_share_mode_entries*sizeof(*shares) +
1533 data->u.s.delete_token_size +
1534 strlen(sharepath) + 1;
1536 for (i=0;i<data->u.s.num_share_mode_entries;i++) {
1537 state->fn(&shares[i], sharepath, fname,
1538 state->private_data);
1540 return 0;
1543 /*******************************************************************
1544 Call the specified function on each entry under management by the
1545 share mode system.
1546 ********************************************************************/
1548 int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *,
1549 const char *, void *),
1550 void *private_data)
1552 struct forall_state state;
1554 if (lock_db == NULL)
1555 return 0;
1557 state.fn = fn;
1558 state.private_data = private_data;
1560 return lock_db->traverse_read(lock_db, traverse_fn, (void *)&state);