s3/VERSION: Raise version up to 3.5.0.
[Samba/id10ts.git] / source3 / locking / locking.c
blob5b17e3b6e8befa7b1cbfefccec37b2a158443b7b
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 char *errmsg;
787 DEBUG(0, ("delete_rec returned %s\n",
788 nt_errstr(status)));
790 if (asprintf(&errmsg, "could not delete share "
791 "entry: %s\n",
792 nt_errstr(status)) == -1) {
793 smb_panic("could not delete share"
794 "entry");
796 smb_panic(errmsg);
799 goto done;
802 status = lck->record->store(lck->record, data, TDB_REPLACE);
803 if (!NT_STATUS_IS_OK(status)) {
804 char *errmsg;
806 DEBUG(0, ("store returned %s\n", nt_errstr(status)));
808 if (asprintf(&errmsg, "could not store share mode entry: %s",
809 nt_errstr(status)) == -1) {
810 smb_panic("could not store share mode entry");
812 smb_panic(errmsg);
815 done:
817 return 0;
820 static bool fill_share_mode_lock(struct share_mode_lock *lck,
821 struct file_id id,
822 const char *servicepath,
823 const struct smb_filename *smb_fname,
824 TDB_DATA share_mode_data,
825 const struct timespec *old_write_time)
827 /* Ensure we set every field here as the destructor must be
828 valid even if parse_share_modes fails. */
830 lck->servicepath = NULL;
831 lck->base_name = NULL;
832 lck->stream_name = NULL;
833 lck->id = id;
834 lck->num_share_modes = 0;
835 lck->share_modes = NULL;
836 lck->delete_token = NULL;
837 lck->delete_on_close = False;
838 ZERO_STRUCT(lck->old_write_time);
839 ZERO_STRUCT(lck->changed_write_time);
840 lck->fresh = False;
841 lck->modified = False;
843 lck->fresh = (share_mode_data.dptr == NULL);
845 if (lck->fresh) {
846 bool has_stream;
847 if (smb_fname == NULL || servicepath == NULL
848 || old_write_time == NULL) {
849 return False;
852 has_stream = smb_fname->stream_name != NULL;
854 lck->base_name = talloc_strdup(lck, smb_fname->base_name);
855 lck->stream_name = talloc_strdup(lck, smb_fname->stream_name);
856 lck->servicepath = talloc_strdup(lck, servicepath);
857 if (lck->base_name == NULL ||
858 (has_stream && lck->stream_name == NULL) ||
859 lck->servicepath == NULL) {
860 DEBUG(0, ("talloc failed\n"));
861 return False;
863 lck->old_write_time = *old_write_time;
864 } else {
865 if (!parse_share_modes(share_mode_data, lck)) {
866 DEBUG(0, ("Could not parse share modes\n"));
867 return False;
871 return True;
874 struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
875 const struct file_id id,
876 const char *servicepath,
877 const struct smb_filename *smb_fname,
878 const struct timespec *old_write_time)
880 struct share_mode_lock *lck;
881 struct file_id tmp;
882 TDB_DATA key = locking_key(&id, &tmp);
884 if (!(lck = TALLOC_P(mem_ctx, struct share_mode_lock))) {
885 DEBUG(0, ("talloc failed\n"));
886 return NULL;
889 if (!(lck->record = lock_db->fetch_locked(lock_db, lck, key))) {
890 DEBUG(3, ("Could not lock share entry\n"));
891 TALLOC_FREE(lck);
892 return NULL;
895 if (!fill_share_mode_lock(lck, id, servicepath, smb_fname,
896 lck->record->value, old_write_time)) {
897 DEBUG(3, ("fill_share_mode_lock failed\n"));
898 TALLOC_FREE(lck);
899 return NULL;
902 talloc_set_destructor(lck, share_mode_lock_destructor);
904 return lck;
907 struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx,
908 const struct file_id id)
910 struct share_mode_lock *lck;
911 struct file_id tmp;
912 TDB_DATA key = locking_key(&id, &tmp);
913 TDB_DATA data;
915 if (!(lck = TALLOC_P(mem_ctx, struct share_mode_lock))) {
916 DEBUG(0, ("talloc failed\n"));
917 return NULL;
920 if (lock_db->fetch(lock_db, lck, key, &data) == -1) {
921 DEBUG(3, ("Could not fetch share entry\n"));
922 TALLOC_FREE(lck);
923 return NULL;
926 if (!fill_share_mode_lock(lck, id, NULL, NULL, data, NULL)) {
927 DEBUG(10, ("fetch_share_mode_unlocked: no share_mode record "
928 "around (file not open)\n"));
929 TALLOC_FREE(lck);
930 return NULL;
933 return lck;
936 /*******************************************************************
937 Sets the service name and filename for rename.
938 At this point we emit "file renamed" messages to all
939 process id's that have this file open.
940 Based on an initial code idea from SATOH Fumiyasu <fumiya@samba.gr.jp>
941 ********************************************************************/
943 bool rename_share_filename(struct messaging_context *msg_ctx,
944 struct share_mode_lock *lck,
945 const char *servicepath,
946 const struct smb_filename *smb_fname_dst)
948 size_t sp_len;
949 size_t bn_len;
950 size_t sn_len;
951 size_t msg_len;
952 char *frm = NULL;
953 int i;
954 bool strip_two_chars = false;
955 bool has_stream = smb_fname_dst->stream_name != NULL;
957 DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n",
958 servicepath, smb_fname_dst->base_name));
961 * rename_internal_fsp() and rename_internals() add './' to
962 * head of newname if newname does not contain a '/'.
964 if (smb_fname_dst->base_name[0] &&
965 smb_fname_dst->base_name[1] &&
966 smb_fname_dst->base_name[0] == '.' &&
967 smb_fname_dst->base_name[1] == '/') {
968 strip_two_chars = true;
971 lck->servicepath = talloc_strdup(lck, servicepath);
972 lck->base_name = talloc_strdup(lck, smb_fname_dst->base_name +
973 (strip_two_chars ? 2 : 0));
974 lck->stream_name = talloc_strdup(lck, smb_fname_dst->stream_name);
975 if (lck->base_name == NULL ||
976 (has_stream && lck->stream_name == NULL) ||
977 lck->servicepath == NULL) {
978 DEBUG(0, ("rename_share_filename: talloc failed\n"));
979 return False;
981 lck->modified = True;
983 sp_len = strlen(lck->servicepath);
984 bn_len = strlen(lck->base_name);
985 sn_len = has_stream ? strlen(lck->stream_name) : 0;
987 msg_len = MSG_FILE_RENAMED_MIN_SIZE + sp_len + 1 + bn_len + 1 +
988 sn_len + 1;
990 /* Set up the name changed message. */
991 frm = TALLOC_ARRAY(lck, char, msg_len);
992 if (!frm) {
993 return False;
996 push_file_id_24(frm, &lck->id);
998 DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len ));
1000 safe_strcpy(&frm[24], lck->servicepath, sp_len);
1001 safe_strcpy(&frm[24 + sp_len + 1], lck->base_name, bn_len);
1002 safe_strcpy(&frm[24 + sp_len + 1 + bn_len + 1], lck->stream_name,
1003 sn_len);
1005 /* Send the messages. */
1006 for (i=0; i<lck->num_share_modes; i++) {
1007 struct share_mode_entry *se = &lck->share_modes[i];
1008 if (!is_valid_share_mode_entry(se)) {
1009 continue;
1011 /* But not to ourselves... */
1012 if (procid_is_me(&se->pid)) {
1013 continue;
1016 DEBUG(10,("rename_share_filename: sending rename message to "
1017 "pid %s file_id %s sharepath %s base_name %s "
1018 "stream_name %s\n",
1019 procid_str_static(&se->pid),
1020 file_id_string_tos(&lck->id),
1021 lck->servicepath, lck->base_name,
1022 has_stream ? lck->stream_name : ""));
1024 messaging_send_buf(msg_ctx, se->pid, MSG_SMB_FILE_RENAME,
1025 (uint8 *)frm, msg_len);
1028 return True;
1031 void get_file_infos(struct file_id id,
1032 bool *delete_on_close,
1033 struct timespec *write_time)
1035 struct share_mode_lock *lck;
1037 if (delete_on_close) {
1038 *delete_on_close = false;
1041 if (write_time) {
1042 ZERO_STRUCTP(write_time);
1045 if (!(lck = fetch_share_mode_unlocked(talloc_tos(), id))) {
1046 return;
1049 if (delete_on_close) {
1050 *delete_on_close = lck->delete_on_close;
1053 if (write_time) {
1054 struct timespec wt;
1056 wt = lck->changed_write_time;
1057 if (null_timespec(wt)) {
1058 wt = lck->old_write_time;
1061 *write_time = wt;
1064 TALLOC_FREE(lck);
1067 bool is_valid_share_mode_entry(const struct share_mode_entry *e)
1069 int num_props = 0;
1071 if (e->op_type == UNUSED_SHARE_MODE_ENTRY) {
1072 /* cope with dead entries from the process not
1073 existing. These should not be considered valid,
1074 otherwise we end up doing zero timeout sharing
1075 violation */
1076 return False;
1079 num_props += ((e->op_type == NO_OPLOCK) ? 1 : 0);
1080 num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0);
1081 num_props += (LEVEL_II_OPLOCK_TYPE(e->op_type) ? 1 : 0);
1083 SMB_ASSERT(num_props <= 1);
1084 return (num_props != 0);
1087 bool is_deferred_open_entry(const struct share_mode_entry *e)
1089 return (e->op_type == DEFERRED_OPEN_ENTRY);
1092 bool is_unused_share_mode_entry(const struct share_mode_entry *e)
1094 return (e->op_type == UNUSED_SHARE_MODE_ENTRY);
1097 /*******************************************************************
1098 Fill a share mode entry.
1099 ********************************************************************/
1101 static void fill_share_mode_entry(struct share_mode_entry *e,
1102 files_struct *fsp,
1103 uid_t uid, uint16 mid, uint16 op_type)
1105 ZERO_STRUCTP(e);
1106 e->pid = procid_self();
1107 e->share_access = fsp->share_access;
1108 e->private_options = fsp->fh->private_options;
1109 e->access_mask = fsp->access_mask;
1110 e->op_mid = mid;
1111 e->op_type = op_type;
1112 e->time.tv_sec = fsp->open_time.tv_sec;
1113 e->time.tv_usec = fsp->open_time.tv_usec;
1114 e->id = fsp->file_id;
1115 e->share_file_id = fsp->fh->gen_id;
1116 e->uid = (uint32)uid;
1117 e->flags = fsp->posix_open ? SHARE_MODE_FLAG_POSIX_OPEN : 0;
1120 static void fill_deferred_open_entry(struct share_mode_entry *e,
1121 const struct timeval request_time,
1122 struct file_id id, uint16 mid)
1124 ZERO_STRUCTP(e);
1125 e->pid = procid_self();
1126 e->op_mid = mid;
1127 e->op_type = DEFERRED_OPEN_ENTRY;
1128 e->time.tv_sec = request_time.tv_sec;
1129 e->time.tv_usec = request_time.tv_usec;
1130 e->id = id;
1131 e->uid = (uint32)-1;
1132 e->flags = 0;
1135 static void add_share_mode_entry(struct share_mode_lock *lck,
1136 const struct share_mode_entry *entry)
1138 int i;
1140 for (i=0; i<lck->num_share_modes; i++) {
1141 struct share_mode_entry *e = &lck->share_modes[i];
1142 if (is_unused_share_mode_entry(e)) {
1143 *e = *entry;
1144 break;
1148 if (i == lck->num_share_modes) {
1149 /* No unused entry found */
1150 ADD_TO_ARRAY(lck, struct share_mode_entry, *entry,
1151 &lck->share_modes, &lck->num_share_modes);
1153 lck->modified = True;
1156 void set_share_mode(struct share_mode_lock *lck, files_struct *fsp,
1157 uid_t uid, uint16 mid, uint16 op_type)
1159 struct share_mode_entry entry;
1160 fill_share_mode_entry(&entry, fsp, uid, mid, op_type);
1161 add_share_mode_entry(lck, &entry);
1164 void add_deferred_open(struct share_mode_lock *lck, uint16 mid,
1165 struct timeval request_time,
1166 struct file_id id)
1168 struct share_mode_entry entry;
1169 fill_deferred_open_entry(&entry, request_time, id, mid);
1170 add_share_mode_entry(lck, &entry);
1173 /*******************************************************************
1174 Check if two share mode entries are identical, ignoring oplock
1175 and mid info and desired_access. (Removed paranoia test - it's
1176 not automatically a logic error if they are identical. JRA.)
1177 ********************************************************************/
1179 static bool share_modes_identical(struct share_mode_entry *e1,
1180 struct share_mode_entry *e2)
1182 /* We used to check for e1->share_access == e2->share_access here
1183 as well as the other fields but 2 different DOS or FCB opens
1184 sharing the same share mode entry may validly differ in
1185 fsp->share_access field. */
1187 return (procid_equal(&e1->pid, &e2->pid) &&
1188 file_id_equal(&e1->id, &e2->id) &&
1189 e1->share_file_id == e2->share_file_id );
1192 static bool deferred_open_identical(struct share_mode_entry *e1,
1193 struct share_mode_entry *e2)
1195 return (procid_equal(&e1->pid, &e2->pid) &&
1196 (e1->op_mid == e2->op_mid) &&
1197 file_id_equal(&e1->id, &e2->id));
1200 static struct share_mode_entry *find_share_mode_entry(struct share_mode_lock *lck,
1201 struct share_mode_entry *entry)
1203 int i;
1205 for (i=0; i<lck->num_share_modes; i++) {
1206 struct share_mode_entry *e = &lck->share_modes[i];
1207 if (is_valid_share_mode_entry(entry) &&
1208 is_valid_share_mode_entry(e) &&
1209 share_modes_identical(e, entry)) {
1210 return e;
1212 if (is_deferred_open_entry(entry) &&
1213 is_deferred_open_entry(e) &&
1214 deferred_open_identical(e, entry)) {
1215 return e;
1218 return NULL;
1221 /*******************************************************************
1222 Del the share mode of a file for this process. Return the number of
1223 entries left.
1224 ********************************************************************/
1226 bool del_share_mode(struct share_mode_lock *lck, files_struct *fsp)
1228 struct share_mode_entry entry, *e;
1230 /* Don't care about the pid owner being correct here - just a search. */
1231 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1233 e = find_share_mode_entry(lck, &entry);
1234 if (e == NULL) {
1235 return False;
1238 e->op_type = UNUSED_SHARE_MODE_ENTRY;
1239 lck->modified = True;
1240 return True;
1243 void del_deferred_open_entry(struct share_mode_lock *lck, uint16 mid)
1245 struct share_mode_entry entry, *e;
1247 fill_deferred_open_entry(&entry, timeval_zero(),
1248 lck->id, mid);
1250 e = find_share_mode_entry(lck, &entry);
1251 if (e == NULL) {
1252 return;
1255 e->op_type = UNUSED_SHARE_MODE_ENTRY;
1256 lck->modified = True;
1259 /*******************************************************************
1260 Remove an oplock mid and mode entry from a share mode.
1261 ********************************************************************/
1263 bool remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
1265 struct share_mode_entry entry, *e;
1267 /* Don't care about the pid owner being correct here - just a search. */
1268 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1270 e = find_share_mode_entry(lck, &entry);
1271 if (e == NULL) {
1272 return False;
1275 e->op_mid = 0;
1276 if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1278 * Going from exclusive or batch,
1279 * we always go through FAKE_LEVEL_II
1280 * first.
1282 e->op_type = FAKE_LEVEL_II_OPLOCK;
1283 } else {
1284 e->op_type = NO_OPLOCK;
1286 lck->modified = True;
1287 return True;
1290 /*******************************************************************
1291 Downgrade a oplock type from exclusive to level II.
1292 ********************************************************************/
1294 bool downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
1296 struct share_mode_entry entry, *e;
1298 /* Don't care about the pid owner being correct here - just a search. */
1299 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1301 e = find_share_mode_entry(lck, &entry);
1302 if (e == NULL) {
1303 return False;
1306 e->op_type = LEVEL_II_OPLOCK;
1307 lck->modified = True;
1308 return True;
1311 /****************************************************************************
1312 Deal with the internal needs of setting the delete on close flag. Note that
1313 as the tdb locking is recursive, it is safe to call this from within
1314 open_file_ntcreate. JRA.
1315 ****************************************************************************/
1317 NTSTATUS can_set_delete_on_close(files_struct *fsp, bool delete_on_close,
1318 uint32 dosmode)
1320 if (!delete_on_close) {
1321 return NT_STATUS_OK;
1325 * Only allow delete on close for writable files.
1328 if ((dosmode & aRONLY) &&
1329 !lp_delete_readonly(SNUM(fsp->conn))) {
1330 DEBUG(10,("can_set_delete_on_close: file %s delete on close "
1331 "flag set but file attribute is readonly.\n",
1332 fsp_str_dbg(fsp)));
1333 return NT_STATUS_CANNOT_DELETE;
1337 * Only allow delete on close for writable shares.
1340 if (!CAN_WRITE(fsp->conn)) {
1341 DEBUG(10,("can_set_delete_on_close: file %s delete on "
1342 "close flag set but write access denied on share.\n",
1343 fsp_str_dbg(fsp)));
1344 return NT_STATUS_ACCESS_DENIED;
1348 * Only allow delete on close for files/directories opened with delete
1349 * intent.
1352 if (!(fsp->access_mask & DELETE_ACCESS)) {
1353 DEBUG(10,("can_set_delete_on_close: file %s delete on "
1354 "close flag set but delete access denied.\n",
1355 fsp_str_dbg(fsp)));
1356 return NT_STATUS_ACCESS_DENIED;
1359 /* Don't allow delete on close for non-empty directories. */
1360 if (fsp->is_directory) {
1361 SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name));
1362 return can_delete_directory(fsp->conn,
1363 fsp->fsp_name->base_name);
1366 return NT_STATUS_OK;
1369 /*************************************************************************
1370 Return a talloced copy of a UNIX_USER_TOKEN. NULL on fail.
1371 (Should this be in locking.c.... ?).
1372 *************************************************************************/
1374 static UNIX_USER_TOKEN *copy_unix_token(TALLOC_CTX *ctx, const UNIX_USER_TOKEN *tok)
1376 UNIX_USER_TOKEN *cpy;
1378 if (tok == NULL) {
1379 return NULL;
1382 cpy = TALLOC_P(ctx, UNIX_USER_TOKEN);
1383 if (!cpy) {
1384 return NULL;
1387 cpy->uid = tok->uid;
1388 cpy->gid = tok->gid;
1389 cpy->ngroups = tok->ngroups;
1390 if (tok->ngroups) {
1391 /* Make this a talloc child of cpy. */
1392 cpy->groups = TALLOC_ARRAY(cpy, gid_t, tok->ngroups);
1393 if (!cpy->groups) {
1394 return NULL;
1396 memcpy(cpy->groups, tok->groups, tok->ngroups * sizeof(gid_t));
1398 return cpy;
1401 /****************************************************************************
1402 Replace the delete on close token.
1403 ****************************************************************************/
1405 void set_delete_on_close_token(struct share_mode_lock *lck, const UNIX_USER_TOKEN *tok)
1407 TALLOC_FREE(lck->delete_token); /* Also deletes groups... */
1409 /* Copy the new token (can be NULL). */
1410 lck->delete_token = copy_unix_token(lck, tok);
1411 lck->modified = True;
1414 /****************************************************************************
1415 Sets the delete on close flag over all share modes on this file.
1416 Modify the share mode entry for all files open
1417 on this device and inode to tell other smbds we have
1418 changed the delete on close flag. This will be noticed
1419 in the close code, the last closer will delete the file
1420 if flag is set.
1421 This makes a copy of any UNIX_USER_TOKEN into the
1422 lck entry. This function is used when the lock is already granted.
1423 ****************************************************************************/
1425 void set_delete_on_close_lck(struct share_mode_lock *lck, bool delete_on_close, const UNIX_USER_TOKEN *tok)
1427 if (lck->delete_on_close != delete_on_close) {
1428 set_delete_on_close_token(lck, tok);
1429 lck->delete_on_close = delete_on_close;
1430 if (delete_on_close) {
1431 SMB_ASSERT(lck->delete_token != NULL);
1433 lck->modified = True;
1437 bool set_delete_on_close(files_struct *fsp, bool delete_on_close, const UNIX_USER_TOKEN *tok)
1439 UNIX_USER_TOKEN *tok_copy = NULL;
1440 struct share_mode_lock *lck;
1442 DEBUG(10,("set_delete_on_close: %s delete on close flag for "
1443 "fnum = %d, file %s\n",
1444 delete_on_close ? "Adding" : "Removing", fsp->fnum,
1445 fsp_str_dbg(fsp)));
1447 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
1448 NULL);
1449 if (lck == NULL) {
1450 return False;
1453 if (fsp->conn->admin_user) {
1454 tok_copy = copy_unix_token(lck, tok);
1455 if (tok_copy == NULL) {
1456 TALLOC_FREE(lck);
1457 return false;
1459 tok_copy->uid = (uid_t)0;
1460 tok = tok_copy;
1463 set_delete_on_close_lck(lck, delete_on_close, tok);
1465 if (fsp->is_directory) {
1466 SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name));
1467 send_stat_cache_delete_message(fsp->fsp_name->base_name);
1470 TALLOC_FREE(lck);
1471 return True;
1474 bool set_sticky_write_time(struct file_id fileid, struct timespec write_time)
1476 struct share_mode_lock *lck;
1478 DEBUG(5,("set_sticky_write_time: %s id=%s\n",
1479 timestring(debug_ctx(),
1480 convert_timespec_to_time_t(write_time)),
1481 file_id_string_tos(&fileid)));
1483 lck = get_share_mode_lock(NULL, fileid, NULL, NULL, NULL);
1484 if (lck == NULL) {
1485 return False;
1488 if (timespec_compare(&lck->changed_write_time, &write_time) != 0) {
1489 lck->modified = True;
1490 lck->changed_write_time = write_time;
1493 TALLOC_FREE(lck);
1494 return True;
1497 bool set_write_time(struct file_id fileid, struct timespec write_time)
1499 struct share_mode_lock *lck;
1501 DEBUG(5,("set_write_time: %s id=%s\n",
1502 timestring(debug_ctx(),
1503 convert_timespec_to_time_t(write_time)),
1504 file_id_string_tos(&fileid)));
1506 lck = get_share_mode_lock(NULL, fileid, NULL, NULL, NULL);
1507 if (lck == NULL) {
1508 return False;
1511 if (timespec_compare(&lck->old_write_time, &write_time) != 0) {
1512 lck->modified = True;
1513 lck->old_write_time = write_time;
1516 TALLOC_FREE(lck);
1517 return True;
1521 struct forall_state {
1522 void (*fn)(const struct share_mode_entry *entry,
1523 const char *sharepath,
1524 const char *fname,
1525 void *private_data);
1526 void *private_data;
1529 static int traverse_fn(struct db_record *rec, void *_state)
1531 struct forall_state *state = (struct forall_state *)_state;
1532 struct locking_data *data;
1533 struct share_mode_entry *shares;
1534 const char *sharepath;
1535 const char *fname;
1536 int i;
1538 /* Ensure this is a locking_key record. */
1539 if (rec->key.dsize != sizeof(struct file_id))
1540 return 0;
1542 data = (struct locking_data *)rec->value.dptr;
1543 shares = (struct share_mode_entry *)(rec->value.dptr + sizeof(*data));
1544 sharepath = (const char *)rec->value.dptr + sizeof(*data) +
1545 data->u.s.num_share_mode_entries*sizeof(*shares) +
1546 data->u.s.delete_token_size;
1547 fname = (const char *)rec->value.dptr + sizeof(*data) +
1548 data->u.s.num_share_mode_entries*sizeof(*shares) +
1549 data->u.s.delete_token_size +
1550 strlen(sharepath) + 1;
1552 for (i=0;i<data->u.s.num_share_mode_entries;i++) {
1553 state->fn(&shares[i], sharepath, fname,
1554 state->private_data);
1556 return 0;
1559 /*******************************************************************
1560 Call the specified function on each entry under management by the
1561 share mode system.
1562 ********************************************************************/
1564 int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *,
1565 const char *, void *),
1566 void *private_data)
1568 struct forall_state state;
1570 if (lock_db == NULL)
1571 return 0;
1573 state.fn = fn;
1574 state.private_data = private_data;
1576 return lock_db->traverse_read(lock_db, traverse_fn, (void *)&state);