s3: Remove procid_self() from do_unlock()
[Samba/gebeck_regimport.git] / source3 / locking / locking.c
blobead39ddcdb05c140a0d177814bca54a338addccf
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"
39 #include "librpc/gen_ndr/messaging.h"
40 #include "smbd/globals.h"
42 #undef DBGC_CLASS
43 #define DBGC_CLASS DBGC_LOCKING
45 #define NO_LOCKING_COUNT (-1)
47 /* the locking database handle */
48 static struct db_context *lock_db;
50 /****************************************************************************
51 Debugging aids :-).
52 ****************************************************************************/
54 const char *lock_type_name(enum brl_type lock_type)
56 switch (lock_type) {
57 case READ_LOCK:
58 return "READ";
59 case WRITE_LOCK:
60 return "WRITE";
61 case PENDING_READ_LOCK:
62 return "PENDING_READ";
63 case PENDING_WRITE_LOCK:
64 return "PENDING_WRITE";
65 default:
66 return "other";
70 const char *lock_flav_name(enum brl_flavour lock_flav)
72 return (lock_flav == WINDOWS_LOCK) ? "WINDOWS_LOCK" : "POSIX_LOCK";
75 /****************************************************************************
76 Utility function called to see if a file region is locked.
77 Called in the read/write codepath.
78 ****************************************************************************/
80 void init_strict_lock_struct(files_struct *fsp,
81 uint64_t smblctx,
82 br_off start,
83 br_off size,
84 enum brl_type lock_type,
85 struct lock_struct *plock)
87 SMB_ASSERT(lock_type == READ_LOCK || lock_type == WRITE_LOCK);
89 plock->context.smblctx = smblctx;
90 plock->context.tid = fsp->conn->cnum;
91 plock->context.pid = sconn_server_id(fsp->conn->sconn);
92 plock->start = start;
93 plock->size = size;
94 plock->fnum = fsp->fnum;
95 plock->lock_type = lock_type;
96 plock->lock_flav = lp_posix_cifsu_locktype(fsp);
99 bool strict_lock_default(files_struct *fsp, struct lock_struct *plock)
101 int strict_locking = lp_strict_locking(fsp->conn->params);
102 bool ret = False;
104 if (plock->size == 0) {
105 return True;
108 if (!lp_locking(fsp->conn->params) || !strict_locking) {
109 return True;
112 if (strict_locking == Auto) {
113 if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (plock->lock_type == READ_LOCK || plock->lock_type == WRITE_LOCK)) {
114 DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp_str_dbg(fsp)));
115 ret = True;
116 } else if ((fsp->oplock_type == LEVEL_II_OPLOCK) &&
117 (plock->lock_type == READ_LOCK)) {
118 DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp_str_dbg(fsp)));
119 ret = True;
120 } else {
121 struct byte_range_lock *br_lck;
123 br_lck = brl_get_locks_readonly(fsp);
124 if (!br_lck) {
125 return True;
127 ret = brl_locktest(br_lck,
128 plock->context.smblctx,
129 plock->context.pid,
130 plock->start,
131 plock->size,
132 plock->lock_type,
133 plock->lock_flav);
135 } else {
136 struct byte_range_lock *br_lck;
138 br_lck = brl_get_locks_readonly(fsp);
139 if (!br_lck) {
140 return True;
142 ret = brl_locktest(br_lck,
143 plock->context.smblctx,
144 plock->context.pid,
145 plock->start,
146 plock->size,
147 plock->lock_type,
148 plock->lock_flav);
151 DEBUG(10,("strict_lock_default: flavour = %s brl start=%.0f "
152 "len=%.0f %s for fnum %d file %s\n",
153 lock_flav_name(plock->lock_flav),
154 (double)plock->start, (double)plock->size,
155 ret ? "unlocked" : "locked",
156 plock->fnum, fsp_str_dbg(fsp)));
158 return ret;
161 void strict_unlock_default(files_struct *fsp, struct lock_struct *plock)
165 /****************************************************************************
166 Find out if a lock could be granted - return who is blocking us if we can't.
167 ****************************************************************************/
169 NTSTATUS query_lock(files_struct *fsp,
170 uint64_t *psmblctx,
171 uint64_t *pcount,
172 uint64_t *poffset,
173 enum brl_type *plock_type,
174 enum brl_flavour lock_flav)
176 struct byte_range_lock *br_lck = NULL;
178 if (!fsp->can_lock) {
179 return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
182 if (!lp_locking(fsp->conn->params)) {
183 return NT_STATUS_OK;
186 br_lck = brl_get_locks_readonly(fsp);
187 if (!br_lck) {
188 return NT_STATUS_NO_MEMORY;
191 return brl_lockquery(br_lck,
192 psmblctx,
193 sconn_server_id(fsp->conn->sconn),
194 poffset,
195 pcount,
196 plock_type,
197 lock_flav);
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 uint64_t smblctx,
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 uint64_t *psmblctx,
242 struct blocking_lock_record *blr)
244 struct byte_range_lock *br_lck = NULL;
246 /* silently return ok on print files as we don't do locking there */
247 if (fsp->print_file) {
248 *perr = NT_STATUS_OK;
249 return NULL;
252 if (!fsp->can_lock) {
253 *perr = fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
254 return NULL;
257 if (!lp_locking(fsp->conn->params)) {
258 *perr = NT_STATUS_OK;
259 return NULL;
262 /* NOTE! 0 byte long ranges ARE allowed and should be stored */
264 DEBUG(10,("do_lock: lock flavour %s lock type %s start=%.0f len=%.0f "
265 "blocking_lock=%s requested for fnum %d file %s\n",
266 lock_flav_name(lock_flav), lock_type_name(lock_type),
267 (double)offset, (double)count, blocking_lock ? "true" :
268 "false", fsp->fnum, fsp_str_dbg(fsp)));
270 br_lck = brl_get_locks(talloc_tos(), fsp);
271 if (!br_lck) {
272 *perr = NT_STATUS_NO_MEMORY;
273 return NULL;
276 *perr = brl_lock(msg_ctx,
277 br_lck,
278 smblctx,
279 sconn_server_id(fsp->conn->sconn),
280 offset,
281 count,
282 lock_type,
283 lock_flav,
284 blocking_lock,
285 psmblctx,
286 blr);
288 DEBUG(10, ("do_lock: returning status=%s\n", nt_errstr(*perr)));
290 increment_current_lock_count(fsp, lock_flav);
291 return br_lck;
294 /****************************************************************************
295 Utility function called by unlocking requests.
296 ****************************************************************************/
298 NTSTATUS do_unlock(struct messaging_context *msg_ctx,
299 files_struct *fsp,
300 uint64_t smblctx,
301 uint64_t count,
302 uint64_t offset,
303 enum brl_flavour lock_flav)
305 bool ok = False;
306 struct byte_range_lock *br_lck = NULL;
308 if (!fsp->can_lock) {
309 return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
312 if (!lp_locking(fsp->conn->params)) {
313 return NT_STATUS_OK;
316 DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for fnum %d file %s\n",
317 (double)offset, (double)count, fsp->fnum,
318 fsp_str_dbg(fsp)));
320 br_lck = brl_get_locks(talloc_tos(), fsp);
321 if (!br_lck) {
322 return NT_STATUS_NO_MEMORY;
325 ok = brl_unlock(msg_ctx,
326 br_lck,
327 smblctx,
328 sconn_server_id(fsp->conn->sconn),
329 offset,
330 count,
331 lock_flav);
333 TALLOC_FREE(br_lck);
335 if (!ok) {
336 DEBUG(10,("do_unlock: returning ERRlock.\n" ));
337 return NT_STATUS_RANGE_NOT_LOCKED;
340 decrement_current_lock_count(fsp, lock_flav);
341 return NT_STATUS_OK;
344 /****************************************************************************
345 Cancel any pending blocked locks.
346 ****************************************************************************/
348 NTSTATUS do_lock_cancel(files_struct *fsp,
349 uint64 smblctx,
350 uint64_t count,
351 uint64_t offset,
352 enum brl_flavour lock_flav,
353 struct blocking_lock_record *blr)
355 bool ok = False;
356 struct byte_range_lock *br_lck = NULL;
358 if (!fsp->can_lock) {
359 return fsp->is_directory ?
360 NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
363 if (!lp_locking(fsp->conn->params)) {
364 return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
367 DEBUG(10,("do_lock_cancel: cancel start=%.0f len=%.0f requested for fnum %d file %s\n",
368 (double)offset, (double)count, fsp->fnum,
369 fsp_str_dbg(fsp)));
371 br_lck = brl_get_locks(talloc_tos(), fsp);
372 if (!br_lck) {
373 return NT_STATUS_NO_MEMORY;
376 ok = brl_lock_cancel(br_lck,
377 smblctx,
378 procid_self(),
379 offset,
380 count,
381 lock_flav,
382 blr);
384 TALLOC_FREE(br_lck);
386 if (!ok) {
387 DEBUG(10,("do_lock_cancel: returning ERRcancelviolation.\n" ));
388 return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
391 decrement_current_lock_count(fsp, lock_flav);
392 return NT_STATUS_OK;
395 /****************************************************************************
396 Remove any locks on this fd. Called from file_close().
397 ****************************************************************************/
399 void locking_close_file(struct messaging_context *msg_ctx,
400 files_struct *fsp,
401 enum file_close_type close_type)
403 struct byte_range_lock *br_lck;
405 if (!lp_locking(fsp->conn->params)) {
406 return;
409 /* If we have not outstanding locks or pending
410 * locks then we don't need to look in the lock db.
413 if (fsp->current_lock_count == 0) {
414 return;
417 br_lck = brl_get_locks(talloc_tos(),fsp);
419 if (br_lck) {
420 cancel_pending_lock_requests_by_fid(fsp, br_lck, close_type);
421 brl_close_fnum(msg_ctx, br_lck);
422 TALLOC_FREE(br_lck);
426 /****************************************************************************
427 Initialise the locking functions.
428 ****************************************************************************/
430 static bool locking_init_internal(bool read_only)
432 brl_init(read_only);
434 if (lock_db)
435 return True;
437 lock_db = db_open(NULL, lock_path("locking.tdb"),
438 lp_open_files_db_hash_size(),
439 TDB_DEFAULT|TDB_VOLATILE|TDB_CLEAR_IF_FIRST,
440 read_only?O_RDONLY:O_RDWR|O_CREAT, 0644);
442 if (!lock_db) {
443 DEBUG(0,("ERROR: Failed to initialise locking database\n"));
444 return False;
447 if (!posix_locking_init(read_only))
448 return False;
450 return True;
453 bool locking_init(void)
455 return locking_init_internal(false);
458 bool locking_init_readonly(void)
460 return locking_init_internal(true);
463 /*******************************************************************
464 Deinitialize the share_mode management.
465 ******************************************************************/
467 bool locking_end(void)
469 brl_shutdown();
470 TALLOC_FREE(lock_db);
471 return true;
474 /*******************************************************************
475 Form a static locking key for a dev/inode pair.
476 ******************************************************************/
478 static TDB_DATA locking_key(const struct file_id *id, struct file_id *tmp)
480 *tmp = *id;
481 return make_tdb_data((const uint8_t *)tmp, sizeof(*tmp));
484 /*******************************************************************
485 Print out a share mode.
486 ********************************************************************/
488 char *share_mode_str(TALLOC_CTX *ctx, int num, const struct share_mode_entry *e)
490 return talloc_asprintf(ctx, "share_mode_entry[%d]: %s "
491 "pid = %s, share_access = 0x%x, private_options = 0x%x, "
492 "access_mask = 0x%x, mid = 0x%llx, type= 0x%x, gen_id = %lu, "
493 "uid = %u, flags = %u, file_id %s",
494 num,
495 e->op_type == UNUSED_SHARE_MODE_ENTRY ? "UNUSED" : "",
496 procid_str_static(&e->pid),
497 e->share_access, e->private_options,
498 e->access_mask, (unsigned long long)e->op_mid,
499 e->op_type, e->share_file_id,
500 (unsigned int)e->uid, (unsigned int)e->flags,
501 file_id_string_tos(&e->id));
504 /*******************************************************************
505 Print out a share mode table.
506 ********************************************************************/
508 static void print_share_mode_table(struct locking_data *data)
510 int num_share_modes = data->u.s.num_share_mode_entries;
511 struct share_mode_entry *shares =
512 (struct share_mode_entry *)(data + 1);
513 int i;
515 for (i = 0; i < num_share_modes; i++) {
516 struct share_mode_entry entry;
517 char *str;
520 * We need to memcpy the entry here due to alignment
521 * restrictions that are not met when directly accessing
522 * shares[i]
525 memcpy(&entry, &shares[i], sizeof(struct share_mode_entry));
526 str = share_mode_str(talloc_tos(), i, &entry);
528 DEBUG(10,("print_share_mode_table: %s\n", str ? str : ""));
529 TALLOC_FREE(str);
533 /*******************************************************************
534 Get all share mode entries for a dev/inode pair.
535 ********************************************************************/
537 static bool parse_share_modes(const TDB_DATA dbuf, struct share_mode_lock *lck)
539 struct locking_data data;
540 int i;
542 if (dbuf.dsize < sizeof(struct locking_data)) {
543 smb_panic("parse_share_modes: buffer too short");
546 memcpy(&data, dbuf.dptr, sizeof(data));
548 lck->delete_on_close = data.u.s.delete_on_close;
549 lck->old_write_time = data.u.s.old_write_time;
550 lck->changed_write_time = data.u.s.changed_write_time;
551 lck->num_share_modes = data.u.s.num_share_mode_entries;
553 DEBUG(10, ("parse_share_modes: delete_on_close: %d, owrt: %s, "
554 "cwrt: %s, tok: %u, num_share_modes: %d\n",
555 lck->delete_on_close,
556 timestring(talloc_tos(),
557 convert_timespec_to_time_t(lck->old_write_time)),
558 timestring(talloc_tos(),
559 convert_timespec_to_time_t(
560 lck->changed_write_time)),
561 (unsigned int)data.u.s.delete_token_size,
562 lck->num_share_modes));
564 if ((lck->num_share_modes < 0) || (lck->num_share_modes > 1000000)) {
565 DEBUG(0, ("invalid number of share modes: %d\n",
566 lck->num_share_modes));
567 smb_panic("parse_share_modes: invalid number of share modes");
570 lck->share_modes = NULL;
572 if (lck->num_share_modes != 0) {
574 if (dbuf.dsize < (sizeof(struct locking_data) +
575 (lck->num_share_modes *
576 sizeof(struct share_mode_entry)))) {
577 smb_panic("parse_share_modes: buffer too short");
580 lck->share_modes = (struct share_mode_entry *)
581 TALLOC_MEMDUP(lck,
582 dbuf.dptr+sizeof(struct locking_data),
583 lck->num_share_modes *
584 sizeof(struct share_mode_entry));
586 if (lck->share_modes == NULL) {
587 smb_panic("parse_share_modes: talloc failed");
591 /* Get any delete token. */
592 if (data.u.s.delete_token_size) {
593 uint8 *p = dbuf.dptr + sizeof(struct locking_data) +
594 (lck->num_share_modes *
595 sizeof(struct share_mode_entry));
597 if ((data.u.s.delete_token_size < sizeof(uid_t) + sizeof(gid_t)) ||
598 ((data.u.s.delete_token_size - sizeof(uid_t)) % sizeof(gid_t)) != 0) {
599 DEBUG(0, ("parse_share_modes: invalid token size %d\n",
600 data.u.s.delete_token_size));
601 smb_panic("parse_share_modes: invalid token size");
604 lck->delete_token = TALLOC_P(lck, UNIX_USER_TOKEN);
605 if (!lck->delete_token) {
606 smb_panic("parse_share_modes: talloc failed");
609 /* Copy out the uid and gid. */
610 memcpy(&lck->delete_token->uid, p, sizeof(uid_t));
611 p += sizeof(uid_t);
612 memcpy(&lck->delete_token->gid, p, sizeof(gid_t));
613 p += sizeof(gid_t);
615 /* Any supplementary groups ? */
616 lck->delete_token->ngroups = (data.u.s.delete_token_size > (sizeof(uid_t) + sizeof(gid_t))) ?
617 ((data.u.s.delete_token_size -
618 (sizeof(uid_t) + sizeof(gid_t)))/sizeof(gid_t)) : 0;
620 if (lck->delete_token->ngroups) {
621 /* Make this a talloc child of lck->delete_token. */
622 lck->delete_token->groups = TALLOC_ARRAY(lck->delete_token, gid_t,
623 lck->delete_token->ngroups);
624 if (!lck->delete_token) {
625 smb_panic("parse_share_modes: talloc failed");
628 for (i = 0; i < lck->delete_token->ngroups; i++) {
629 memcpy(&lck->delete_token->groups[i], p, sizeof(gid_t));
630 p += sizeof(gid_t);
634 } else {
635 lck->delete_token = NULL;
638 /* Save off the associated service path and filename. */
639 lck->servicepath = (const char *)dbuf.dptr + sizeof(struct locking_data) +
640 (lck->num_share_modes * sizeof(struct share_mode_entry)) +
641 data.u.s.delete_token_size;
643 lck->base_name = (const char *)dbuf.dptr + sizeof(struct locking_data) +
644 (lck->num_share_modes * sizeof(struct share_mode_entry)) +
645 data.u.s.delete_token_size +
646 strlen(lck->servicepath) + 1;
648 lck->stream_name = (const char *)dbuf.dptr + sizeof(struct locking_data) +
649 (lck->num_share_modes * sizeof(struct share_mode_entry)) +
650 data.u.s.delete_token_size +
651 strlen(lck->servicepath) + 1 +
652 strlen(lck->base_name) + 1;
655 * Ensure that each entry has a real process attached.
658 for (i = 0; i < lck->num_share_modes; i++) {
659 struct share_mode_entry *entry_p = &lck->share_modes[i];
660 char *str = NULL;
661 if (DEBUGLEVEL >= 10) {
662 str = share_mode_str(NULL, i, entry_p);
664 DEBUG(10,("parse_share_modes: %s\n",
665 str ? str : ""));
666 if (!serverid_exists(&entry_p->pid)) {
667 DEBUG(10,("parse_share_modes: deleted %s\n",
668 str ? str : ""));
669 entry_p->op_type = UNUSED_SHARE_MODE_ENTRY;
670 lck->modified = True;
672 TALLOC_FREE(str);
675 return True;
678 static TDB_DATA unparse_share_modes(const struct share_mode_lock *lck)
680 TDB_DATA result;
681 int num_valid = 0;
682 int i;
683 struct locking_data *data;
684 ssize_t offset;
685 ssize_t sp_len, bn_len, sn_len;
686 uint32 delete_token_size;
688 result.dptr = NULL;
689 result.dsize = 0;
691 for (i=0; i<lck->num_share_modes; i++) {
692 if (!is_unused_share_mode_entry(&lck->share_modes[i])) {
693 num_valid += 1;
697 if (num_valid == 0) {
698 return result;
701 sp_len = strlen(lck->servicepath);
702 bn_len = strlen(lck->base_name);
703 sn_len = lck->stream_name != NULL ? strlen(lck->stream_name) : 0;
705 delete_token_size = (lck->delete_token ?
706 (sizeof(uid_t) + sizeof(gid_t) + (lck->delete_token->ngroups*sizeof(gid_t))) : 0);
708 result.dsize = sizeof(*data) +
709 lck->num_share_modes * sizeof(struct share_mode_entry) +
710 delete_token_size +
711 sp_len + 1 +
712 bn_len + 1 +
713 sn_len + 1;
714 result.dptr = TALLOC_ARRAY(lck, uint8, result.dsize);
716 if (result.dptr == NULL) {
717 smb_panic("talloc failed");
720 data = (struct locking_data *)result.dptr;
721 ZERO_STRUCTP(data);
722 data->u.s.num_share_mode_entries = lck->num_share_modes;
723 data->u.s.delete_on_close = lck->delete_on_close;
724 data->u.s.old_write_time = lck->old_write_time;
725 data->u.s.changed_write_time = lck->changed_write_time;
726 data->u.s.delete_token_size = delete_token_size;
728 DEBUG(10,("unparse_share_modes: del: %d, owrt: %s cwrt: %s, tok: %u, "
729 "num: %d\n", data->u.s.delete_on_close,
730 timestring(talloc_tos(),
731 convert_timespec_to_time_t(lck->old_write_time)),
732 timestring(talloc_tos(),
733 convert_timespec_to_time_t(
734 lck->changed_write_time)),
735 (unsigned int)data->u.s.delete_token_size,
736 data->u.s.num_share_mode_entries));
738 memcpy(result.dptr + sizeof(*data), lck->share_modes,
739 sizeof(struct share_mode_entry)*lck->num_share_modes);
740 offset = sizeof(*data) +
741 sizeof(struct share_mode_entry)*lck->num_share_modes;
743 /* Store any delete on close token. */
744 if (lck->delete_token) {
745 uint8 *p = result.dptr + offset;
747 memcpy(p, &lck->delete_token->uid, sizeof(uid_t));
748 p += sizeof(uid_t);
750 memcpy(p, &lck->delete_token->gid, sizeof(gid_t));
751 p += sizeof(gid_t);
753 for (i = 0; i < lck->delete_token->ngroups; i++) {
754 memcpy(p, &lck->delete_token->groups[i], sizeof(gid_t));
755 p += sizeof(gid_t);
757 offset = p - result.dptr;
760 safe_strcpy((char *)result.dptr + offset, lck->servicepath,
761 result.dsize - offset - 1);
762 offset += sp_len + 1;
763 safe_strcpy((char *)result.dptr + offset, lck->base_name,
764 result.dsize - offset - 1);
765 offset += bn_len + 1;
766 safe_strcpy((char *)result.dptr + offset, lck->stream_name,
767 result.dsize - offset - 1);
769 if (DEBUGLEVEL >= 10) {
770 print_share_mode_table(data);
773 return result;
776 static int share_mode_lock_destructor(struct share_mode_lock *lck)
778 NTSTATUS status;
779 TDB_DATA data;
781 if (!lck->modified) {
782 return 0;
785 data = unparse_share_modes(lck);
787 if (data.dptr == NULL) {
788 if (!lck->fresh) {
789 /* There has been an entry before, delete it */
791 status = lck->record->delete_rec(lck->record);
792 if (!NT_STATUS_IS_OK(status)) {
793 char *errmsg;
795 DEBUG(0, ("delete_rec returned %s\n",
796 nt_errstr(status)));
798 if (asprintf(&errmsg, "could not delete share "
799 "entry: %s\n",
800 nt_errstr(status)) == -1) {
801 smb_panic("could not delete share"
802 "entry");
804 smb_panic(errmsg);
807 goto done;
810 status = lck->record->store(lck->record, data, TDB_REPLACE);
811 if (!NT_STATUS_IS_OK(status)) {
812 char *errmsg;
814 DEBUG(0, ("store returned %s\n", nt_errstr(status)));
816 if (asprintf(&errmsg, "could not store share mode entry: %s",
817 nt_errstr(status)) == -1) {
818 smb_panic("could not store share mode entry");
820 smb_panic(errmsg);
823 done:
825 return 0;
828 static bool fill_share_mode_lock(struct share_mode_lock *lck,
829 struct file_id id,
830 const char *servicepath,
831 const struct smb_filename *smb_fname,
832 TDB_DATA share_mode_data,
833 const struct timespec *old_write_time)
835 /* Ensure we set every field here as the destructor must be
836 valid even if parse_share_modes fails. */
838 lck->servicepath = NULL;
839 lck->base_name = NULL;
840 lck->stream_name = NULL;
841 lck->id = id;
842 lck->num_share_modes = 0;
843 lck->share_modes = NULL;
844 lck->delete_token = NULL;
845 lck->delete_on_close = False;
846 ZERO_STRUCT(lck->old_write_time);
847 ZERO_STRUCT(lck->changed_write_time);
848 lck->fresh = False;
849 lck->modified = False;
851 lck->fresh = (share_mode_data.dptr == NULL);
853 if (lck->fresh) {
854 bool has_stream;
855 if (smb_fname == NULL || servicepath == NULL
856 || old_write_time == NULL) {
857 return False;
860 has_stream = smb_fname->stream_name != NULL;
862 lck->base_name = talloc_strdup(lck, smb_fname->base_name);
863 lck->stream_name = talloc_strdup(lck, smb_fname->stream_name);
864 lck->servicepath = talloc_strdup(lck, servicepath);
865 if (lck->base_name == NULL ||
866 (has_stream && lck->stream_name == NULL) ||
867 lck->servicepath == NULL) {
868 DEBUG(0, ("talloc failed\n"));
869 return False;
871 lck->old_write_time = *old_write_time;
872 } else {
873 if (!parse_share_modes(share_mode_data, lck)) {
874 DEBUG(0, ("Could not parse share modes\n"));
875 return False;
879 return True;
882 struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
883 const struct file_id id,
884 const char *servicepath,
885 const struct smb_filename *smb_fname,
886 const struct timespec *old_write_time)
888 struct share_mode_lock *lck;
889 struct file_id tmp;
890 TDB_DATA key = locking_key(&id, &tmp);
892 if (!(lck = TALLOC_P(mem_ctx, struct share_mode_lock))) {
893 DEBUG(0, ("talloc failed\n"));
894 return NULL;
897 if (!(lck->record = lock_db->fetch_locked(lock_db, lck, key))) {
898 DEBUG(3, ("Could not lock share entry\n"));
899 TALLOC_FREE(lck);
900 return NULL;
903 if (!fill_share_mode_lock(lck, id, servicepath, smb_fname,
904 lck->record->value, old_write_time)) {
905 DEBUG(3, ("fill_share_mode_lock failed\n"));
906 TALLOC_FREE(lck);
907 return NULL;
910 talloc_set_destructor(lck, share_mode_lock_destructor);
912 return lck;
915 struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx,
916 const struct file_id id)
918 struct share_mode_lock *lck;
919 struct file_id tmp;
920 TDB_DATA key = locking_key(&id, &tmp);
921 TDB_DATA data;
923 if (!(lck = TALLOC_P(mem_ctx, struct share_mode_lock))) {
924 DEBUG(0, ("talloc failed\n"));
925 return NULL;
928 if (lock_db->fetch(lock_db, lck, key, &data) == -1) {
929 DEBUG(3, ("Could not fetch share entry\n"));
930 TALLOC_FREE(lck);
931 return NULL;
934 if (!fill_share_mode_lock(lck, id, NULL, NULL, data, NULL)) {
935 DEBUG(10, ("fetch_share_mode_unlocked: no share_mode record "
936 "around (file not open)\n"));
937 TALLOC_FREE(lck);
938 return NULL;
941 return lck;
944 /*******************************************************************
945 Sets the service name and filename for rename.
946 At this point we emit "file renamed" messages to all
947 process id's that have this file open.
948 Based on an initial code idea from SATOH Fumiyasu <fumiya@samba.gr.jp>
949 ********************************************************************/
951 bool rename_share_filename(struct messaging_context *msg_ctx,
952 struct share_mode_lock *lck,
953 const char *servicepath,
954 const struct smb_filename *smb_fname_dst)
956 size_t sp_len;
957 size_t bn_len;
958 size_t sn_len;
959 size_t msg_len;
960 char *frm = NULL;
961 int i;
962 bool strip_two_chars = false;
963 bool has_stream = smb_fname_dst->stream_name != NULL;
965 DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n",
966 servicepath, smb_fname_dst->base_name));
969 * rename_internal_fsp() and rename_internals() add './' to
970 * head of newname if newname does not contain a '/'.
972 if (smb_fname_dst->base_name[0] &&
973 smb_fname_dst->base_name[1] &&
974 smb_fname_dst->base_name[0] == '.' &&
975 smb_fname_dst->base_name[1] == '/') {
976 strip_two_chars = true;
979 lck->servicepath = talloc_strdup(lck, servicepath);
980 lck->base_name = talloc_strdup(lck, smb_fname_dst->base_name +
981 (strip_two_chars ? 2 : 0));
982 lck->stream_name = talloc_strdup(lck, smb_fname_dst->stream_name);
983 if (lck->base_name == NULL ||
984 (has_stream && lck->stream_name == NULL) ||
985 lck->servicepath == NULL) {
986 DEBUG(0, ("rename_share_filename: talloc failed\n"));
987 return False;
989 lck->modified = True;
991 sp_len = strlen(lck->servicepath);
992 bn_len = strlen(lck->base_name);
993 sn_len = has_stream ? strlen(lck->stream_name) : 0;
995 msg_len = MSG_FILE_RENAMED_MIN_SIZE + sp_len + 1 + bn_len + 1 +
996 sn_len + 1;
998 /* Set up the name changed message. */
999 frm = TALLOC_ARRAY(lck, char, msg_len);
1000 if (!frm) {
1001 return False;
1004 push_file_id_24(frm, &lck->id);
1006 DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len ));
1008 safe_strcpy(&frm[24], lck->servicepath, sp_len);
1009 safe_strcpy(&frm[24 + sp_len + 1], lck->base_name, bn_len);
1010 safe_strcpy(&frm[24 + sp_len + 1 + bn_len + 1], lck->stream_name,
1011 sn_len);
1013 /* Send the messages. */
1014 for (i=0; i<lck->num_share_modes; i++) {
1015 struct share_mode_entry *se = &lck->share_modes[i];
1016 if (!is_valid_share_mode_entry(se)) {
1017 continue;
1019 /* But not to ourselves... */
1020 if (procid_is_me(&se->pid)) {
1021 continue;
1024 DEBUG(10,("rename_share_filename: sending rename message to "
1025 "pid %s file_id %s sharepath %s base_name %s "
1026 "stream_name %s\n",
1027 procid_str_static(&se->pid),
1028 file_id_string_tos(&lck->id),
1029 lck->servicepath, lck->base_name,
1030 has_stream ? lck->stream_name : ""));
1032 messaging_send_buf(msg_ctx, se->pid, MSG_SMB_FILE_RENAME,
1033 (uint8 *)frm, msg_len);
1036 return True;
1039 void get_file_infos(struct file_id id,
1040 bool *delete_on_close,
1041 struct timespec *write_time)
1043 struct share_mode_lock *lck;
1045 if (delete_on_close) {
1046 *delete_on_close = false;
1049 if (write_time) {
1050 ZERO_STRUCTP(write_time);
1053 if (!(lck = fetch_share_mode_unlocked(talloc_tos(), id))) {
1054 return;
1057 if (delete_on_close) {
1058 *delete_on_close = lck->delete_on_close;
1061 if (write_time) {
1062 struct timespec wt;
1064 wt = lck->changed_write_time;
1065 if (null_timespec(wt)) {
1066 wt = lck->old_write_time;
1069 *write_time = wt;
1072 TALLOC_FREE(lck);
1075 bool is_valid_share_mode_entry(const struct share_mode_entry *e)
1077 int num_props = 0;
1079 if (e->op_type == UNUSED_SHARE_MODE_ENTRY) {
1080 /* cope with dead entries from the process not
1081 existing. These should not be considered valid,
1082 otherwise we end up doing zero timeout sharing
1083 violation */
1084 return False;
1087 num_props += ((e->op_type == NO_OPLOCK) ? 1 : 0);
1088 num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0);
1089 num_props += (LEVEL_II_OPLOCK_TYPE(e->op_type) ? 1 : 0);
1091 SMB_ASSERT(num_props <= 1);
1092 return (num_props != 0);
1095 bool is_deferred_open_entry(const struct share_mode_entry *e)
1097 return (e->op_type == DEFERRED_OPEN_ENTRY);
1100 bool is_unused_share_mode_entry(const struct share_mode_entry *e)
1102 return (e->op_type == UNUSED_SHARE_MODE_ENTRY);
1105 /*******************************************************************
1106 Fill a share mode entry.
1107 ********************************************************************/
1109 static void fill_share_mode_entry(struct share_mode_entry *e,
1110 files_struct *fsp,
1111 uid_t uid, uint64_t mid, uint16 op_type)
1113 ZERO_STRUCTP(e);
1114 e->pid = sconn_server_id(fsp->conn->sconn);
1115 e->share_access = fsp->share_access;
1116 e->private_options = fsp->fh->private_options;
1117 e->access_mask = fsp->access_mask;
1118 e->op_mid = mid;
1119 e->op_type = op_type;
1120 e->time.tv_sec = fsp->open_time.tv_sec;
1121 e->time.tv_usec = fsp->open_time.tv_usec;
1122 e->id = fsp->file_id;
1123 e->share_file_id = fsp->fh->gen_id;
1124 e->uid = (uint32)uid;
1125 e->flags = fsp->posix_open ? SHARE_MODE_FLAG_POSIX_OPEN : 0;
1128 static void fill_deferred_open_entry(struct share_mode_entry *e,
1129 const struct timeval request_time,
1130 struct file_id id, uint64_t mid)
1132 ZERO_STRUCTP(e);
1133 e->pid = procid_self();
1134 e->op_mid = mid;
1135 e->op_type = DEFERRED_OPEN_ENTRY;
1136 e->time.tv_sec = request_time.tv_sec;
1137 e->time.tv_usec = request_time.tv_usec;
1138 e->id = id;
1139 e->uid = (uint32)-1;
1140 e->flags = 0;
1143 static void add_share_mode_entry(struct share_mode_lock *lck,
1144 const struct share_mode_entry *entry)
1146 int i;
1148 for (i=0; i<lck->num_share_modes; i++) {
1149 struct share_mode_entry *e = &lck->share_modes[i];
1150 if (is_unused_share_mode_entry(e)) {
1151 *e = *entry;
1152 break;
1156 if (i == lck->num_share_modes) {
1157 /* No unused entry found */
1158 ADD_TO_ARRAY(lck, struct share_mode_entry, *entry,
1159 &lck->share_modes, &lck->num_share_modes);
1161 lck->modified = True;
1164 void set_share_mode(struct share_mode_lock *lck, files_struct *fsp,
1165 uid_t uid, uint64_t mid, uint16 op_type)
1167 struct share_mode_entry entry;
1168 fill_share_mode_entry(&entry, fsp, uid, mid, op_type);
1169 add_share_mode_entry(lck, &entry);
1172 void add_deferred_open(struct share_mode_lock *lck, uint64_t mid,
1173 struct timeval request_time,
1174 struct file_id id)
1176 struct share_mode_entry entry;
1177 fill_deferred_open_entry(&entry, request_time, id, mid);
1178 add_share_mode_entry(lck, &entry);
1181 /*******************************************************************
1182 Check if two share mode entries are identical, ignoring oplock
1183 and mid info and desired_access. (Removed paranoia test - it's
1184 not automatically a logic error if they are identical. JRA.)
1185 ********************************************************************/
1187 static bool share_modes_identical(struct share_mode_entry *e1,
1188 struct share_mode_entry *e2)
1190 /* We used to check for e1->share_access == e2->share_access here
1191 as well as the other fields but 2 different DOS or FCB opens
1192 sharing the same share mode entry may validly differ in
1193 fsp->share_access field. */
1195 return (procid_equal(&e1->pid, &e2->pid) &&
1196 file_id_equal(&e1->id, &e2->id) &&
1197 e1->share_file_id == e2->share_file_id );
1200 static bool deferred_open_identical(struct share_mode_entry *e1,
1201 struct share_mode_entry *e2)
1203 return (procid_equal(&e1->pid, &e2->pid) &&
1204 (e1->op_mid == e2->op_mid) &&
1205 file_id_equal(&e1->id, &e2->id));
1208 static struct share_mode_entry *find_share_mode_entry(struct share_mode_lock *lck,
1209 struct share_mode_entry *entry)
1211 int i;
1213 for (i=0; i<lck->num_share_modes; i++) {
1214 struct share_mode_entry *e = &lck->share_modes[i];
1215 if (is_valid_share_mode_entry(entry) &&
1216 is_valid_share_mode_entry(e) &&
1217 share_modes_identical(e, entry)) {
1218 return e;
1220 if (is_deferred_open_entry(entry) &&
1221 is_deferred_open_entry(e) &&
1222 deferred_open_identical(e, entry)) {
1223 return e;
1226 return NULL;
1229 /*******************************************************************
1230 Del the share mode of a file for this process. Return the number of
1231 entries left.
1232 ********************************************************************/
1234 bool del_share_mode(struct share_mode_lock *lck, files_struct *fsp)
1236 struct share_mode_entry entry, *e;
1238 /* Don't care about the pid owner being correct here - just a search. */
1239 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1241 e = find_share_mode_entry(lck, &entry);
1242 if (e == NULL) {
1243 return False;
1246 e->op_type = UNUSED_SHARE_MODE_ENTRY;
1247 lck->modified = True;
1248 return True;
1251 void del_deferred_open_entry(struct share_mode_lock *lck, uint64_t mid)
1253 struct share_mode_entry entry, *e;
1255 fill_deferred_open_entry(&entry, timeval_zero(),
1256 lck->id, mid);
1258 e = find_share_mode_entry(lck, &entry);
1259 if (e == NULL) {
1260 return;
1263 e->op_type = UNUSED_SHARE_MODE_ENTRY;
1264 lck->modified = True;
1267 /*******************************************************************
1268 Remove an oplock mid and mode entry from a share mode.
1269 ********************************************************************/
1271 bool remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
1273 struct share_mode_entry entry, *e;
1275 /* Don't care about the pid owner being correct here - just a search. */
1276 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1278 e = find_share_mode_entry(lck, &entry);
1279 if (e == NULL) {
1280 return False;
1283 e->op_mid = 0;
1284 if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1286 * Going from exclusive or batch,
1287 * we always go through FAKE_LEVEL_II
1288 * first.
1290 e->op_type = FAKE_LEVEL_II_OPLOCK;
1291 } else {
1292 e->op_type = NO_OPLOCK;
1294 lck->modified = True;
1295 return True;
1298 /*******************************************************************
1299 Downgrade a oplock type from exclusive to level II.
1300 ********************************************************************/
1302 bool downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
1304 struct share_mode_entry entry, *e;
1306 /* Don't care about the pid owner being correct here - just a search. */
1307 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1309 e = find_share_mode_entry(lck, &entry);
1310 if (e == NULL) {
1311 return False;
1314 e->op_type = LEVEL_II_OPLOCK;
1315 lck->modified = True;
1316 return True;
1319 /****************************************************************************
1320 Check if setting delete on close is allowed on this fsp.
1321 ****************************************************************************/
1323 NTSTATUS can_set_delete_on_close(files_struct *fsp, uint32 dosmode)
1326 * Only allow delete on close for writable files.
1329 if ((dosmode & aRONLY) &&
1330 !lp_delete_readonly(SNUM(fsp->conn))) {
1331 DEBUG(10,("can_set_delete_on_close: file %s delete on close "
1332 "flag set but file attribute is readonly.\n",
1333 fsp_str_dbg(fsp)));
1334 return NT_STATUS_CANNOT_DELETE;
1338 * Only allow delete on close for writable shares.
1341 if (!CAN_WRITE(fsp->conn)) {
1342 DEBUG(10,("can_set_delete_on_close: file %s delete on "
1343 "close flag set but write access denied on share.\n",
1344 fsp_str_dbg(fsp)));
1345 return NT_STATUS_ACCESS_DENIED;
1349 * Only allow delete on close for files/directories opened with delete
1350 * intent.
1353 if (!(fsp->access_mask & DELETE_ACCESS)) {
1354 DEBUG(10,("can_set_delete_on_close: file %s delete on "
1355 "close flag set but delete access denied.\n",
1356 fsp_str_dbg(fsp)));
1357 return NT_STATUS_ACCESS_DENIED;
1360 /* Don't allow delete on close for non-empty directories. */
1361 if (fsp->is_directory) {
1362 SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name));
1363 return can_delete_directory(fsp->conn,
1364 fsp->fsp_name->base_name);
1367 return NT_STATUS_OK;
1370 /*************************************************************************
1371 Return a talloced copy of a UNIX_USER_TOKEN. NULL on fail.
1372 (Should this be in locking.c.... ?).
1373 *************************************************************************/
1375 static UNIX_USER_TOKEN *copy_unix_token(TALLOC_CTX *ctx, const UNIX_USER_TOKEN *tok)
1377 UNIX_USER_TOKEN *cpy;
1379 if (tok == NULL) {
1380 return NULL;
1383 cpy = TALLOC_P(ctx, UNIX_USER_TOKEN);
1384 if (!cpy) {
1385 return NULL;
1388 cpy->uid = tok->uid;
1389 cpy->gid = tok->gid;
1390 cpy->ngroups = tok->ngroups;
1391 if (tok->ngroups) {
1392 /* Make this a talloc child of cpy. */
1393 cpy->groups = TALLOC_ARRAY(cpy, gid_t, tok->ngroups);
1394 if (!cpy->groups) {
1395 return NULL;
1397 memcpy(cpy->groups, tok->groups, tok->ngroups * sizeof(gid_t));
1399 return cpy;
1402 /****************************************************************************
1403 Replace the delete on close token.
1404 ****************************************************************************/
1406 void set_delete_on_close_token(struct share_mode_lock *lck, const UNIX_USER_TOKEN *tok)
1408 TALLOC_FREE(lck->delete_token); /* Also deletes groups... */
1410 /* Copy the new token (can be NULL). */
1411 lck->delete_token = copy_unix_token(lck, tok);
1412 lck->modified = True;
1415 /****************************************************************************
1416 Sets the delete on close flag over all share modes on this file.
1417 Modify the share mode entry for all files open
1418 on this device and inode to tell other smbds we have
1419 changed the delete on close flag. This will be noticed
1420 in the close code, the last closer will delete the file
1421 if flag is set.
1422 This makes a copy of any UNIX_USER_TOKEN into the
1423 lck entry. This function is used when the lock is already granted.
1424 ****************************************************************************/
1426 void set_delete_on_close_lck(struct share_mode_lock *lck, bool delete_on_close, const UNIX_USER_TOKEN *tok)
1428 if (lck->delete_on_close != delete_on_close) {
1429 set_delete_on_close_token(lck, tok);
1430 lck->delete_on_close = delete_on_close;
1431 if (delete_on_close) {
1432 SMB_ASSERT(lck->delete_token != NULL);
1434 lck->modified = True;
1438 bool set_delete_on_close(files_struct *fsp, bool delete_on_close, const UNIX_USER_TOKEN *tok)
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 set_delete_on_close_lck(lck, delete_on_close, tok);
1455 if (fsp->is_directory) {
1456 SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name));
1457 send_stat_cache_delete_message(fsp->fsp_name->base_name);
1460 TALLOC_FREE(lck);
1462 fsp->delete_on_close = delete_on_close;
1464 return True;
1467 bool set_sticky_write_time(struct file_id fileid, struct timespec write_time)
1469 struct share_mode_lock *lck;
1471 DEBUG(5,("set_sticky_write_time: %s id=%s\n",
1472 timestring(talloc_tos(),
1473 convert_timespec_to_time_t(write_time)),
1474 file_id_string_tos(&fileid)));
1476 lck = get_share_mode_lock(NULL, fileid, NULL, NULL, NULL);
1477 if (lck == NULL) {
1478 return False;
1481 if (timespec_compare(&lck->changed_write_time, &write_time) != 0) {
1482 lck->modified = True;
1483 lck->changed_write_time = write_time;
1486 TALLOC_FREE(lck);
1487 return True;
1490 bool set_write_time(struct file_id fileid, struct timespec write_time)
1492 struct share_mode_lock *lck;
1494 DEBUG(5,("set_write_time: %s id=%s\n",
1495 timestring(talloc_tos(),
1496 convert_timespec_to_time_t(write_time)),
1497 file_id_string_tos(&fileid)));
1499 lck = get_share_mode_lock(NULL, fileid, NULL, NULL, NULL);
1500 if (lck == NULL) {
1501 return False;
1504 if (timespec_compare(&lck->old_write_time, &write_time) != 0) {
1505 lck->modified = True;
1506 lck->old_write_time = write_time;
1509 TALLOC_FREE(lck);
1510 return True;
1514 struct forall_state {
1515 void (*fn)(const struct share_mode_entry *entry,
1516 const char *sharepath,
1517 const char *fname,
1518 void *private_data);
1519 void *private_data;
1522 static int traverse_fn(struct db_record *rec, void *_state)
1524 struct forall_state *state = (struct forall_state *)_state;
1525 struct locking_data *data;
1526 struct share_mode_entry *shares;
1527 const char *sharepath;
1528 const char *fname;
1529 int i;
1531 /* Ensure this is a locking_key record. */
1532 if (rec->key.dsize != sizeof(struct file_id))
1533 return 0;
1535 data = (struct locking_data *)rec->value.dptr;
1536 shares = (struct share_mode_entry *)(rec->value.dptr + sizeof(*data));
1537 sharepath = (const char *)rec->value.dptr + sizeof(*data) +
1538 data->u.s.num_share_mode_entries*sizeof(*shares) +
1539 data->u.s.delete_token_size;
1540 fname = (const char *)rec->value.dptr + sizeof(*data) +
1541 data->u.s.num_share_mode_entries*sizeof(*shares) +
1542 data->u.s.delete_token_size +
1543 strlen(sharepath) + 1;
1545 for (i=0;i<data->u.s.num_share_mode_entries;i++) {
1546 state->fn(&shares[i], sharepath, fname,
1547 state->private_data);
1549 return 0;
1552 /*******************************************************************
1553 Call the specified function on each entry under management by the
1554 share mode system.
1555 ********************************************************************/
1557 int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *,
1558 const char *, void *),
1559 void *private_data)
1561 struct forall_state state;
1563 if (lock_db == NULL)
1564 return 0;
1566 state.fn = fn;
1567 state.private_data = private_data;
1569 return lock_db->traverse_read(lock_db, traverse_fn, (void *)&state);