s3-netlogon: use SAMR in _netr_ServerAuthenticate3.
[Samba/ekacnet.git] / source3 / locking / locking.c
blob917b436e1854135efb3e605717a86f0d93db4b25
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"
41 #undef DBGC_CLASS
42 #define DBGC_CLASS DBGC_LOCKING
44 #define NO_LOCKING_COUNT (-1)
46 /* the locking database handle */
47 static struct db_context *lock_db;
49 /****************************************************************************
50 Debugging aids :-).
51 ****************************************************************************/
53 const char *lock_type_name(enum brl_type lock_type)
55 switch (lock_type) {
56 case READ_LOCK:
57 return "READ";
58 case WRITE_LOCK:
59 return "WRITE";
60 case PENDING_READ_LOCK:
61 return "PENDING_READ";
62 case PENDING_WRITE_LOCK:
63 return "PENDING_WRITE";
64 default:
65 return "other";
69 const char *lock_flav_name(enum brl_flavour lock_flav)
71 return (lock_flav == WINDOWS_LOCK) ? "WINDOWS_LOCK" : "POSIX_LOCK";
74 /****************************************************************************
75 Utility function called to see if a file region is locked.
76 Called in the read/write codepath.
77 ****************************************************************************/
79 void init_strict_lock_struct(files_struct *fsp,
80 uint64_t smblctx,
81 br_off start,
82 br_off size,
83 enum brl_type lock_type,
84 struct lock_struct *plock)
86 SMB_ASSERT(lock_type == READ_LOCK || lock_type == WRITE_LOCK);
88 plock->context.smblctx = smblctx;
89 plock->context.tid = fsp->conn->cnum;
90 plock->context.pid = procid_self();
91 plock->start = start;
92 plock->size = size;
93 plock->fnum = fsp->fnum;
94 plock->lock_type = lock_type;
95 plock->lock_flav = lp_posix_cifsu_locktype(fsp);
98 bool strict_lock_default(files_struct *fsp, struct lock_struct *plock)
100 int strict_locking = lp_strict_locking(fsp->conn->params);
101 bool ret = False;
103 if (plock->size == 0) {
104 return True;
107 if (!lp_locking(fsp->conn->params) || !strict_locking) {
108 return True;
111 if (strict_locking == Auto) {
112 if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (plock->lock_type == READ_LOCK || plock->lock_type == WRITE_LOCK)) {
113 DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp_str_dbg(fsp)));
114 ret = True;
115 } else if ((fsp->oplock_type == LEVEL_II_OPLOCK) &&
116 (plock->lock_type == READ_LOCK)) {
117 DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp_str_dbg(fsp)));
118 ret = True;
119 } else {
120 struct byte_range_lock *br_lck;
122 br_lck = brl_get_locks_readonly(fsp);
123 if (!br_lck) {
124 return True;
126 ret = brl_locktest(br_lck,
127 plock->context.smblctx,
128 plock->context.pid,
129 plock->start,
130 plock->size,
131 plock->lock_type,
132 plock->lock_flav);
134 } else {
135 struct byte_range_lock *br_lck;
137 br_lck = brl_get_locks_readonly(fsp);
138 if (!br_lck) {
139 return True;
141 ret = brl_locktest(br_lck,
142 plock->context.smblctx,
143 plock->context.pid,
144 plock->start,
145 plock->size,
146 plock->lock_type,
147 plock->lock_flav);
150 DEBUG(10,("strict_lock_default: flavour = %s brl start=%.0f "
151 "len=%.0f %s for fnum %d file %s\n",
152 lock_flav_name(plock->lock_flav),
153 (double)plock->start, (double)plock->size,
154 ret ? "unlocked" : "locked",
155 plock->fnum, fsp_str_dbg(fsp)));
157 return ret;
160 void strict_unlock_default(files_struct *fsp, struct lock_struct *plock)
164 /****************************************************************************
165 Find out if a lock could be granted - return who is blocking us if we can't.
166 ****************************************************************************/
168 NTSTATUS query_lock(files_struct *fsp,
169 uint64_t *psmblctx,
170 uint64_t *pcount,
171 uint64_t *poffset,
172 enum brl_type *plock_type,
173 enum brl_flavour lock_flav)
175 struct byte_range_lock *br_lck = NULL;
177 if (!fsp->can_lock) {
178 return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
181 if (!lp_locking(fsp->conn->params)) {
182 return NT_STATUS_OK;
185 br_lck = brl_get_locks_readonly(fsp);
186 if (!br_lck) {
187 return NT_STATUS_NO_MEMORY;
190 return brl_lockquery(br_lck,
191 psmblctx,
192 procid_self(),
193 poffset,
194 pcount,
195 plock_type,
196 lock_flav);
199 static void increment_current_lock_count(files_struct *fsp,
200 enum brl_flavour lock_flav)
202 if (lock_flav == WINDOWS_LOCK &&
203 fsp->current_lock_count != NO_LOCKING_COUNT) {
204 /* blocking ie. pending, locks also count here,
205 * as this is an efficiency counter to avoid checking
206 * the lock db. on close. JRA. */
208 fsp->current_lock_count++;
209 } else {
210 /* Notice that this has had a POSIX lock request.
211 * We can't count locks after this so forget them.
213 fsp->current_lock_count = NO_LOCKING_COUNT;
217 static void decrement_current_lock_count(files_struct *fsp,
218 enum brl_flavour lock_flav)
220 if (lock_flav == WINDOWS_LOCK &&
221 fsp->current_lock_count != NO_LOCKING_COUNT) {
222 SMB_ASSERT(fsp->current_lock_count > 0);
223 fsp->current_lock_count--;
227 /****************************************************************************
228 Utility function called by locking requests.
229 ****************************************************************************/
231 struct byte_range_lock *do_lock(struct messaging_context *msg_ctx,
232 files_struct *fsp,
233 uint64_t smblctx,
234 uint64_t count,
235 uint64_t offset,
236 enum brl_type lock_type,
237 enum brl_flavour lock_flav,
238 bool blocking_lock,
239 NTSTATUS *perr,
240 uint64_t *psmblctx,
241 struct blocking_lock_record *blr)
243 struct byte_range_lock *br_lck = NULL;
245 /* silently return ok on print files as we don't do locking there */
246 if (fsp->print_file) {
247 *perr = NT_STATUS_OK;
248 return NULL;
251 if (!fsp->can_lock) {
252 *perr = fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
253 return NULL;
256 if (!lp_locking(fsp->conn->params)) {
257 *perr = NT_STATUS_OK;
258 return NULL;
261 /* NOTE! 0 byte long ranges ARE allowed and should be stored */
263 DEBUG(10,("do_lock: lock flavour %s lock type %s start=%.0f len=%.0f "
264 "blocking_lock=%s requested for fnum %d file %s\n",
265 lock_flav_name(lock_flav), lock_type_name(lock_type),
266 (double)offset, (double)count, blocking_lock ? "true" :
267 "false", fsp->fnum, fsp_str_dbg(fsp)));
269 br_lck = brl_get_locks(talloc_tos(), fsp);
270 if (!br_lck) {
271 *perr = NT_STATUS_NO_MEMORY;
272 return NULL;
275 *perr = brl_lock(msg_ctx,
276 br_lck,
277 smblctx,
278 procid_self(),
279 offset,
280 count,
281 lock_type,
282 lock_flav,
283 blocking_lock,
284 psmblctx,
285 blr);
287 DEBUG(10, ("do_lock: returning status=%s\n", nt_errstr(*perr)));
289 increment_current_lock_count(fsp, lock_flav);
290 return br_lck;
293 /****************************************************************************
294 Utility function called by unlocking requests.
295 ****************************************************************************/
297 NTSTATUS do_unlock(struct messaging_context *msg_ctx,
298 files_struct *fsp,
299 uint64_t smblctx,
300 uint64_t count,
301 uint64_t offset,
302 enum brl_flavour lock_flav)
304 bool ok = False;
305 struct byte_range_lock *br_lck = NULL;
307 if (!fsp->can_lock) {
308 return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
311 if (!lp_locking(fsp->conn->params)) {
312 return NT_STATUS_OK;
315 DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for fnum %d file %s\n",
316 (double)offset, (double)count, fsp->fnum,
317 fsp_str_dbg(fsp)));
319 br_lck = brl_get_locks(talloc_tos(), fsp);
320 if (!br_lck) {
321 return NT_STATUS_NO_MEMORY;
324 ok = brl_unlock(msg_ctx,
325 br_lck,
326 smblctx,
327 procid_self(),
328 offset,
329 count,
330 lock_flav);
332 TALLOC_FREE(br_lck);
334 if (!ok) {
335 DEBUG(10,("do_unlock: returning ERRlock.\n" ));
336 return NT_STATUS_RANGE_NOT_LOCKED;
339 decrement_current_lock_count(fsp, lock_flav);
340 return NT_STATUS_OK;
343 /****************************************************************************
344 Cancel any pending blocked locks.
345 ****************************************************************************/
347 NTSTATUS do_lock_cancel(files_struct *fsp,
348 uint64 smblctx,
349 uint64_t count,
350 uint64_t offset,
351 enum brl_flavour lock_flav,
352 struct blocking_lock_record *blr)
354 bool ok = False;
355 struct byte_range_lock *br_lck = NULL;
357 if (!fsp->can_lock) {
358 return fsp->is_directory ?
359 NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
362 if (!lp_locking(fsp->conn->params)) {
363 return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
366 DEBUG(10,("do_lock_cancel: cancel start=%.0f len=%.0f requested for fnum %d file %s\n",
367 (double)offset, (double)count, fsp->fnum,
368 fsp_str_dbg(fsp)));
370 br_lck = brl_get_locks(talloc_tos(), fsp);
371 if (!br_lck) {
372 return NT_STATUS_NO_MEMORY;
375 ok = brl_lock_cancel(br_lck,
376 smblctx,
377 procid_self(),
378 offset,
379 count,
380 lock_flav,
381 blr);
383 TALLOC_FREE(br_lck);
385 if (!ok) {
386 DEBUG(10,("do_lock_cancel: returning ERRcancelviolation.\n" ));
387 return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
390 decrement_current_lock_count(fsp, lock_flav);
391 return NT_STATUS_OK;
394 /****************************************************************************
395 Remove any locks on this fd. Called from file_close().
396 ****************************************************************************/
398 void locking_close_file(struct messaging_context *msg_ctx,
399 files_struct *fsp,
400 enum file_close_type close_type)
402 struct byte_range_lock *br_lck;
404 if (!lp_locking(fsp->conn->params)) {
405 return;
408 /* If we have not outstanding locks or pending
409 * locks then we don't need to look in the lock db.
412 if (fsp->current_lock_count == 0) {
413 return;
416 br_lck = brl_get_locks(talloc_tos(),fsp);
418 if (br_lck) {
419 cancel_pending_lock_requests_by_fid(fsp, br_lck, close_type);
420 brl_close_fnum(msg_ctx, br_lck);
421 TALLOC_FREE(br_lck);
425 /****************************************************************************
426 Initialise the locking functions.
427 ****************************************************************************/
429 static bool locking_init_internal(bool read_only)
431 brl_init(read_only);
433 if (lock_db)
434 return True;
436 lock_db = db_open(NULL, lock_path("locking.tdb"),
437 lp_open_files_db_hash_size(),
438 TDB_DEFAULT|TDB_VOLATILE|TDB_CLEAR_IF_FIRST,
439 read_only?O_RDONLY:O_RDWR|O_CREAT, 0644);
441 if (!lock_db) {
442 DEBUG(0,("ERROR: Failed to initialise locking database\n"));
443 return False;
446 if (!posix_locking_init(read_only))
447 return False;
449 return True;
452 bool locking_init(void)
454 return locking_init_internal(false);
457 bool locking_init_readonly(void)
459 return locking_init_internal(true);
462 /*******************************************************************
463 Deinitialize the share_mode management.
464 ******************************************************************/
466 bool locking_end(void)
468 brl_shutdown();
469 TALLOC_FREE(lock_db);
470 return true;
473 /*******************************************************************
474 Form a static locking key for a dev/inode pair.
475 ******************************************************************/
477 static TDB_DATA locking_key(const struct file_id *id, struct file_id *tmp)
479 *tmp = *id;
480 return make_tdb_data((const uint8_t *)tmp, sizeof(*tmp));
483 /*******************************************************************
484 Print out a share mode.
485 ********************************************************************/
487 char *share_mode_str(TALLOC_CTX *ctx, int num, const struct share_mode_entry *e)
489 return talloc_asprintf(ctx, "share_mode_entry[%d]: %s "
490 "pid = %s, share_access = 0x%x, private_options = 0x%x, "
491 "access_mask = 0x%x, mid = 0x%llx, type= 0x%x, gen_id = %lu, "
492 "uid = %u, flags = %u, file_id %s",
493 num,
494 e->op_type == UNUSED_SHARE_MODE_ENTRY ? "UNUSED" : "",
495 procid_str_static(&e->pid),
496 e->share_access, e->private_options,
497 e->access_mask, (unsigned long long)e->op_mid,
498 e->op_type, e->share_file_id,
499 (unsigned int)e->uid, (unsigned int)e->flags,
500 file_id_string_tos(&e->id));
503 /*******************************************************************
504 Print out a share mode table.
505 ********************************************************************/
507 static void print_share_mode_table(struct locking_data *data)
509 int num_share_modes = data->u.s.num_share_mode_entries;
510 struct share_mode_entry *shares =
511 (struct share_mode_entry *)(data + 1);
512 int i;
514 for (i = 0; i < num_share_modes; i++) {
515 struct share_mode_entry entry;
516 char *str;
519 * We need to memcpy the entry here due to alignment
520 * restrictions that are not met when directly accessing
521 * shares[i]
524 memcpy(&entry, &shares[i], sizeof(struct share_mode_entry));
525 str = share_mode_str(talloc_tos(), i, &entry);
527 DEBUG(10,("print_share_mode_table: %s\n", str ? str : ""));
528 TALLOC_FREE(str);
532 /*******************************************************************
533 Get all share mode entries for a dev/inode pair.
534 ********************************************************************/
536 static bool parse_share_modes(const TDB_DATA dbuf, struct share_mode_lock *lck)
538 struct locking_data data;
539 int i;
541 if (dbuf.dsize < sizeof(struct locking_data)) {
542 smb_panic("parse_share_modes: buffer too short");
545 memcpy(&data, dbuf.dptr, sizeof(data));
547 lck->delete_on_close = data.u.s.delete_on_close;
548 lck->old_write_time = data.u.s.old_write_time;
549 lck->changed_write_time = data.u.s.changed_write_time;
550 lck->num_share_modes = data.u.s.num_share_mode_entries;
552 DEBUG(10, ("parse_share_modes: delete_on_close: %d, owrt: %s, "
553 "cwrt: %s, tok: %u, num_share_modes: %d\n",
554 lck->delete_on_close,
555 timestring(talloc_tos(),
556 convert_timespec_to_time_t(lck->old_write_time)),
557 timestring(talloc_tos(),
558 convert_timespec_to_time_t(
559 lck->changed_write_time)),
560 (unsigned int)data.u.s.delete_token_size,
561 lck->num_share_modes));
563 if ((lck->num_share_modes < 0) || (lck->num_share_modes > 1000000)) {
564 DEBUG(0, ("invalid number of share modes: %d\n",
565 lck->num_share_modes));
566 smb_panic("parse_share_modes: invalid number of share modes");
569 lck->share_modes = NULL;
571 if (lck->num_share_modes != 0) {
573 if (dbuf.dsize < (sizeof(struct locking_data) +
574 (lck->num_share_modes *
575 sizeof(struct share_mode_entry)))) {
576 smb_panic("parse_share_modes: buffer too short");
579 lck->share_modes = (struct share_mode_entry *)
580 TALLOC_MEMDUP(lck,
581 dbuf.dptr+sizeof(struct locking_data),
582 lck->num_share_modes *
583 sizeof(struct share_mode_entry));
585 if (lck->share_modes == NULL) {
586 smb_panic("parse_share_modes: talloc failed");
590 /* Get any delete token. */
591 if (data.u.s.delete_token_size) {
592 uint8 *p = dbuf.dptr + sizeof(struct locking_data) +
593 (lck->num_share_modes *
594 sizeof(struct share_mode_entry));
596 if ((data.u.s.delete_token_size < sizeof(uid_t) + sizeof(gid_t)) ||
597 ((data.u.s.delete_token_size - sizeof(uid_t)) % sizeof(gid_t)) != 0) {
598 DEBUG(0, ("parse_share_modes: invalid token size %d\n",
599 data.u.s.delete_token_size));
600 smb_panic("parse_share_modes: invalid token size");
603 lck->delete_token = TALLOC_P(lck, UNIX_USER_TOKEN);
604 if (!lck->delete_token) {
605 smb_panic("parse_share_modes: talloc failed");
608 /* Copy out the uid and gid. */
609 memcpy(&lck->delete_token->uid, p, sizeof(uid_t));
610 p += sizeof(uid_t);
611 memcpy(&lck->delete_token->gid, p, sizeof(gid_t));
612 p += sizeof(gid_t);
614 /* Any supplementary groups ? */
615 lck->delete_token->ngroups = (data.u.s.delete_token_size > (sizeof(uid_t) + sizeof(gid_t))) ?
616 ((data.u.s.delete_token_size -
617 (sizeof(uid_t) + sizeof(gid_t)))/sizeof(gid_t)) : 0;
619 if (lck->delete_token->ngroups) {
620 /* Make this a talloc child of lck->delete_token. */
621 lck->delete_token->groups = TALLOC_ARRAY(lck->delete_token, gid_t,
622 lck->delete_token->ngroups);
623 if (!lck->delete_token) {
624 smb_panic("parse_share_modes: talloc failed");
627 for (i = 0; i < lck->delete_token->ngroups; i++) {
628 memcpy(&lck->delete_token->groups[i], p, sizeof(gid_t));
629 p += sizeof(gid_t);
633 } else {
634 lck->delete_token = NULL;
637 /* Save off the associated service path and filename. */
638 lck->servicepath = (const char *)dbuf.dptr + sizeof(struct locking_data) +
639 (lck->num_share_modes * sizeof(struct share_mode_entry)) +
640 data.u.s.delete_token_size;
642 lck->base_name = (const char *)dbuf.dptr + sizeof(struct locking_data) +
643 (lck->num_share_modes * sizeof(struct share_mode_entry)) +
644 data.u.s.delete_token_size +
645 strlen(lck->servicepath) + 1;
647 lck->stream_name = (const char *)dbuf.dptr + sizeof(struct locking_data) +
648 (lck->num_share_modes * sizeof(struct share_mode_entry)) +
649 data.u.s.delete_token_size +
650 strlen(lck->servicepath) + 1 +
651 strlen(lck->base_name) + 1;
654 * Ensure that each entry has a real process attached.
657 for (i = 0; i < lck->num_share_modes; i++) {
658 struct share_mode_entry *entry_p = &lck->share_modes[i];
659 char *str = NULL;
660 if (DEBUGLEVEL >= 10) {
661 str = share_mode_str(NULL, i, entry_p);
663 DEBUG(10,("parse_share_modes: %s\n",
664 str ? str : ""));
665 if (!serverid_exists(&entry_p->pid)) {
666 DEBUG(10,("parse_share_modes: deleted %s\n",
667 str ? str : ""));
668 entry_p->op_type = UNUSED_SHARE_MODE_ENTRY;
669 lck->modified = True;
671 TALLOC_FREE(str);
674 return True;
677 static TDB_DATA unparse_share_modes(const struct share_mode_lock *lck)
679 TDB_DATA result;
680 int num_valid = 0;
681 int i;
682 struct locking_data *data;
683 ssize_t offset;
684 ssize_t sp_len, bn_len, sn_len;
685 uint32 delete_token_size;
687 result.dptr = NULL;
688 result.dsize = 0;
690 for (i=0; i<lck->num_share_modes; i++) {
691 if (!is_unused_share_mode_entry(&lck->share_modes[i])) {
692 num_valid += 1;
696 if (num_valid == 0) {
697 return result;
700 sp_len = strlen(lck->servicepath);
701 bn_len = strlen(lck->base_name);
702 sn_len = lck->stream_name != NULL ? strlen(lck->stream_name) : 0;
704 delete_token_size = (lck->delete_token ?
705 (sizeof(uid_t) + sizeof(gid_t) + (lck->delete_token->ngroups*sizeof(gid_t))) : 0);
707 result.dsize = sizeof(*data) +
708 lck->num_share_modes * sizeof(struct share_mode_entry) +
709 delete_token_size +
710 sp_len + 1 +
711 bn_len + 1 +
712 sn_len + 1;
713 result.dptr = TALLOC_ARRAY(lck, uint8, result.dsize);
715 if (result.dptr == NULL) {
716 smb_panic("talloc failed");
719 data = (struct locking_data *)result.dptr;
720 ZERO_STRUCTP(data);
721 data->u.s.num_share_mode_entries = lck->num_share_modes;
722 data->u.s.delete_on_close = lck->delete_on_close;
723 data->u.s.old_write_time = lck->old_write_time;
724 data->u.s.changed_write_time = lck->changed_write_time;
725 data->u.s.delete_token_size = delete_token_size;
727 DEBUG(10,("unparse_share_modes: del: %d, owrt: %s cwrt: %s, tok: %u, "
728 "num: %d\n", data->u.s.delete_on_close,
729 timestring(talloc_tos(),
730 convert_timespec_to_time_t(lck->old_write_time)),
731 timestring(talloc_tos(),
732 convert_timespec_to_time_t(
733 lck->changed_write_time)),
734 (unsigned int)data->u.s.delete_token_size,
735 data->u.s.num_share_mode_entries));
737 memcpy(result.dptr + sizeof(*data), lck->share_modes,
738 sizeof(struct share_mode_entry)*lck->num_share_modes);
739 offset = sizeof(*data) +
740 sizeof(struct share_mode_entry)*lck->num_share_modes;
742 /* Store any delete on close token. */
743 if (lck->delete_token) {
744 uint8 *p = result.dptr + offset;
746 memcpy(p, &lck->delete_token->uid, sizeof(uid_t));
747 p += sizeof(uid_t);
749 memcpy(p, &lck->delete_token->gid, sizeof(gid_t));
750 p += sizeof(gid_t);
752 for (i = 0; i < lck->delete_token->ngroups; i++) {
753 memcpy(p, &lck->delete_token->groups[i], sizeof(gid_t));
754 p += sizeof(gid_t);
756 offset = p - result.dptr;
759 safe_strcpy((char *)result.dptr + offset, lck->servicepath,
760 result.dsize - offset - 1);
761 offset += sp_len + 1;
762 safe_strcpy((char *)result.dptr + offset, lck->base_name,
763 result.dsize - offset - 1);
764 offset += bn_len + 1;
765 safe_strcpy((char *)result.dptr + offset, lck->stream_name,
766 result.dsize - offset - 1);
768 if (DEBUGLEVEL >= 10) {
769 print_share_mode_table(data);
772 return result;
775 static int share_mode_lock_destructor(struct share_mode_lock *lck)
777 NTSTATUS status;
778 TDB_DATA data;
780 if (!lck->modified) {
781 return 0;
784 data = unparse_share_modes(lck);
786 if (data.dptr == NULL) {
787 if (!lck->fresh) {
788 /* There has been an entry before, delete it */
790 status = lck->record->delete_rec(lck->record);
791 if (!NT_STATUS_IS_OK(status)) {
792 char *errmsg;
794 DEBUG(0, ("delete_rec returned %s\n",
795 nt_errstr(status)));
797 if (asprintf(&errmsg, "could not delete share "
798 "entry: %s\n",
799 nt_errstr(status)) == -1) {
800 smb_panic("could not delete share"
801 "entry");
803 smb_panic(errmsg);
806 goto done;
809 status = lck->record->store(lck->record, data, TDB_REPLACE);
810 if (!NT_STATUS_IS_OK(status)) {
811 char *errmsg;
813 DEBUG(0, ("store returned %s\n", nt_errstr(status)));
815 if (asprintf(&errmsg, "could not store share mode entry: %s",
816 nt_errstr(status)) == -1) {
817 smb_panic("could not store share mode entry");
819 smb_panic(errmsg);
822 done:
824 return 0;
827 static bool fill_share_mode_lock(struct share_mode_lock *lck,
828 struct file_id id,
829 const char *servicepath,
830 const struct smb_filename *smb_fname,
831 TDB_DATA share_mode_data,
832 const struct timespec *old_write_time)
834 /* Ensure we set every field here as the destructor must be
835 valid even if parse_share_modes fails. */
837 lck->servicepath = NULL;
838 lck->base_name = NULL;
839 lck->stream_name = NULL;
840 lck->id = id;
841 lck->num_share_modes = 0;
842 lck->share_modes = NULL;
843 lck->delete_token = NULL;
844 lck->delete_on_close = False;
845 ZERO_STRUCT(lck->old_write_time);
846 ZERO_STRUCT(lck->changed_write_time);
847 lck->fresh = False;
848 lck->modified = False;
850 lck->fresh = (share_mode_data.dptr == NULL);
852 if (lck->fresh) {
853 bool has_stream;
854 if (smb_fname == NULL || servicepath == NULL
855 || old_write_time == NULL) {
856 return False;
859 has_stream = smb_fname->stream_name != NULL;
861 lck->base_name = talloc_strdup(lck, smb_fname->base_name);
862 lck->stream_name = talloc_strdup(lck, smb_fname->stream_name);
863 lck->servicepath = talloc_strdup(lck, servicepath);
864 if (lck->base_name == NULL ||
865 (has_stream && lck->stream_name == NULL) ||
866 lck->servicepath == NULL) {
867 DEBUG(0, ("talloc failed\n"));
868 return False;
870 lck->old_write_time = *old_write_time;
871 } else {
872 if (!parse_share_modes(share_mode_data, lck)) {
873 DEBUG(0, ("Could not parse share modes\n"));
874 return False;
878 return True;
881 struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
882 const struct file_id id,
883 const char *servicepath,
884 const struct smb_filename *smb_fname,
885 const struct timespec *old_write_time)
887 struct share_mode_lock *lck;
888 struct file_id tmp;
889 TDB_DATA key = locking_key(&id, &tmp);
891 if (!(lck = TALLOC_P(mem_ctx, struct share_mode_lock))) {
892 DEBUG(0, ("talloc failed\n"));
893 return NULL;
896 if (!(lck->record = lock_db->fetch_locked(lock_db, lck, key))) {
897 DEBUG(3, ("Could not lock share entry\n"));
898 TALLOC_FREE(lck);
899 return NULL;
902 if (!fill_share_mode_lock(lck, id, servicepath, smb_fname,
903 lck->record->value, old_write_time)) {
904 DEBUG(3, ("fill_share_mode_lock failed\n"));
905 TALLOC_FREE(lck);
906 return NULL;
909 talloc_set_destructor(lck, share_mode_lock_destructor);
911 return lck;
914 struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx,
915 const struct file_id id)
917 struct share_mode_lock *lck;
918 struct file_id tmp;
919 TDB_DATA key = locking_key(&id, &tmp);
920 TDB_DATA data;
922 if (!(lck = TALLOC_P(mem_ctx, struct share_mode_lock))) {
923 DEBUG(0, ("talloc failed\n"));
924 return NULL;
927 if (lock_db->fetch(lock_db, lck, key, &data) == -1) {
928 DEBUG(3, ("Could not fetch share entry\n"));
929 TALLOC_FREE(lck);
930 return NULL;
933 if (!fill_share_mode_lock(lck, id, NULL, NULL, data, NULL)) {
934 DEBUG(10, ("fetch_share_mode_unlocked: no share_mode record "
935 "around (file not open)\n"));
936 TALLOC_FREE(lck);
937 return NULL;
940 return lck;
943 /*******************************************************************
944 Sets the service name and filename for rename.
945 At this point we emit "file renamed" messages to all
946 process id's that have this file open.
947 Based on an initial code idea from SATOH Fumiyasu <fumiya@samba.gr.jp>
948 ********************************************************************/
950 bool rename_share_filename(struct messaging_context *msg_ctx,
951 struct share_mode_lock *lck,
952 const char *servicepath,
953 const struct smb_filename *smb_fname_dst)
955 size_t sp_len;
956 size_t bn_len;
957 size_t sn_len;
958 size_t msg_len;
959 char *frm = NULL;
960 int i;
961 bool strip_two_chars = false;
962 bool has_stream = smb_fname_dst->stream_name != NULL;
964 DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n",
965 servicepath, smb_fname_dst->base_name));
968 * rename_internal_fsp() and rename_internals() add './' to
969 * head of newname if newname does not contain a '/'.
971 if (smb_fname_dst->base_name[0] &&
972 smb_fname_dst->base_name[1] &&
973 smb_fname_dst->base_name[0] == '.' &&
974 smb_fname_dst->base_name[1] == '/') {
975 strip_two_chars = true;
978 lck->servicepath = talloc_strdup(lck, servicepath);
979 lck->base_name = talloc_strdup(lck, smb_fname_dst->base_name +
980 (strip_two_chars ? 2 : 0));
981 lck->stream_name = talloc_strdup(lck, smb_fname_dst->stream_name);
982 if (lck->base_name == NULL ||
983 (has_stream && lck->stream_name == NULL) ||
984 lck->servicepath == NULL) {
985 DEBUG(0, ("rename_share_filename: talloc failed\n"));
986 return False;
988 lck->modified = True;
990 sp_len = strlen(lck->servicepath);
991 bn_len = strlen(lck->base_name);
992 sn_len = has_stream ? strlen(lck->stream_name) : 0;
994 msg_len = MSG_FILE_RENAMED_MIN_SIZE + sp_len + 1 + bn_len + 1 +
995 sn_len + 1;
997 /* Set up the name changed message. */
998 frm = TALLOC_ARRAY(lck, char, msg_len);
999 if (!frm) {
1000 return False;
1003 push_file_id_24(frm, &lck->id);
1005 DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len ));
1007 safe_strcpy(&frm[24], lck->servicepath, sp_len);
1008 safe_strcpy(&frm[24 + sp_len + 1], lck->base_name, bn_len);
1009 safe_strcpy(&frm[24 + sp_len + 1 + bn_len + 1], lck->stream_name,
1010 sn_len);
1012 /* Send the messages. */
1013 for (i=0; i<lck->num_share_modes; i++) {
1014 struct share_mode_entry *se = &lck->share_modes[i];
1015 if (!is_valid_share_mode_entry(se)) {
1016 continue;
1018 /* But not to ourselves... */
1019 if (procid_is_me(&se->pid)) {
1020 continue;
1023 DEBUG(10,("rename_share_filename: sending rename message to "
1024 "pid %s file_id %s sharepath %s base_name %s "
1025 "stream_name %s\n",
1026 procid_str_static(&se->pid),
1027 file_id_string_tos(&lck->id),
1028 lck->servicepath, lck->base_name,
1029 has_stream ? lck->stream_name : ""));
1031 messaging_send_buf(msg_ctx, se->pid, MSG_SMB_FILE_RENAME,
1032 (uint8 *)frm, msg_len);
1035 return True;
1038 void get_file_infos(struct file_id id,
1039 bool *delete_on_close,
1040 struct timespec *write_time)
1042 struct share_mode_lock *lck;
1044 if (delete_on_close) {
1045 *delete_on_close = false;
1048 if (write_time) {
1049 ZERO_STRUCTP(write_time);
1052 if (!(lck = fetch_share_mode_unlocked(talloc_tos(), id))) {
1053 return;
1056 if (delete_on_close) {
1057 *delete_on_close = lck->delete_on_close;
1060 if (write_time) {
1061 struct timespec wt;
1063 wt = lck->changed_write_time;
1064 if (null_timespec(wt)) {
1065 wt = lck->old_write_time;
1068 *write_time = wt;
1071 TALLOC_FREE(lck);
1074 bool is_valid_share_mode_entry(const struct share_mode_entry *e)
1076 int num_props = 0;
1078 if (e->op_type == UNUSED_SHARE_MODE_ENTRY) {
1079 /* cope with dead entries from the process not
1080 existing. These should not be considered valid,
1081 otherwise we end up doing zero timeout sharing
1082 violation */
1083 return False;
1086 num_props += ((e->op_type == NO_OPLOCK) ? 1 : 0);
1087 num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0);
1088 num_props += (LEVEL_II_OPLOCK_TYPE(e->op_type) ? 1 : 0);
1090 SMB_ASSERT(num_props <= 1);
1091 return (num_props != 0);
1094 bool is_deferred_open_entry(const struct share_mode_entry *e)
1096 return (e->op_type == DEFERRED_OPEN_ENTRY);
1099 bool is_unused_share_mode_entry(const struct share_mode_entry *e)
1101 return (e->op_type == UNUSED_SHARE_MODE_ENTRY);
1104 /*******************************************************************
1105 Fill a share mode entry.
1106 ********************************************************************/
1108 static void fill_share_mode_entry(struct share_mode_entry *e,
1109 files_struct *fsp,
1110 uid_t uid, uint64_t mid, uint16 op_type)
1112 ZERO_STRUCTP(e);
1113 e->pid = procid_self();
1114 e->share_access = fsp->share_access;
1115 e->private_options = fsp->fh->private_options;
1116 e->access_mask = fsp->access_mask;
1117 e->op_mid = mid;
1118 e->op_type = op_type;
1119 e->time.tv_sec = fsp->open_time.tv_sec;
1120 e->time.tv_usec = fsp->open_time.tv_usec;
1121 e->id = fsp->file_id;
1122 e->share_file_id = fsp->fh->gen_id;
1123 e->uid = (uint32)uid;
1124 e->flags = fsp->posix_open ? SHARE_MODE_FLAG_POSIX_OPEN : 0;
1127 static void fill_deferred_open_entry(struct share_mode_entry *e,
1128 const struct timeval request_time,
1129 struct file_id id, uint64_t mid)
1131 ZERO_STRUCTP(e);
1132 e->pid = procid_self();
1133 e->op_mid = mid;
1134 e->op_type = DEFERRED_OPEN_ENTRY;
1135 e->time.tv_sec = request_time.tv_sec;
1136 e->time.tv_usec = request_time.tv_usec;
1137 e->id = id;
1138 e->uid = (uint32)-1;
1139 e->flags = 0;
1142 static void add_share_mode_entry(struct share_mode_lock *lck,
1143 const struct share_mode_entry *entry)
1145 int i;
1147 for (i=0; i<lck->num_share_modes; i++) {
1148 struct share_mode_entry *e = &lck->share_modes[i];
1149 if (is_unused_share_mode_entry(e)) {
1150 *e = *entry;
1151 break;
1155 if (i == lck->num_share_modes) {
1156 /* No unused entry found */
1157 ADD_TO_ARRAY(lck, struct share_mode_entry, *entry,
1158 &lck->share_modes, &lck->num_share_modes);
1160 lck->modified = True;
1163 void set_share_mode(struct share_mode_lock *lck, files_struct *fsp,
1164 uid_t uid, uint64_t mid, uint16 op_type)
1166 struct share_mode_entry entry;
1167 fill_share_mode_entry(&entry, fsp, uid, mid, op_type);
1168 add_share_mode_entry(lck, &entry);
1171 void add_deferred_open(struct share_mode_lock *lck, uint64_t mid,
1172 struct timeval request_time,
1173 struct file_id id)
1175 struct share_mode_entry entry;
1176 fill_deferred_open_entry(&entry, request_time, id, mid);
1177 add_share_mode_entry(lck, &entry);
1180 /*******************************************************************
1181 Check if two share mode entries are identical, ignoring oplock
1182 and mid info and desired_access. (Removed paranoia test - it's
1183 not automatically a logic error if they are identical. JRA.)
1184 ********************************************************************/
1186 static bool share_modes_identical(struct share_mode_entry *e1,
1187 struct share_mode_entry *e2)
1189 /* We used to check for e1->share_access == e2->share_access here
1190 as well as the other fields but 2 different DOS or FCB opens
1191 sharing the same share mode entry may validly differ in
1192 fsp->share_access field. */
1194 return (procid_equal(&e1->pid, &e2->pid) &&
1195 file_id_equal(&e1->id, &e2->id) &&
1196 e1->share_file_id == e2->share_file_id );
1199 static bool deferred_open_identical(struct share_mode_entry *e1,
1200 struct share_mode_entry *e2)
1202 return (procid_equal(&e1->pid, &e2->pid) &&
1203 (e1->op_mid == e2->op_mid) &&
1204 file_id_equal(&e1->id, &e2->id));
1207 static struct share_mode_entry *find_share_mode_entry(struct share_mode_lock *lck,
1208 struct share_mode_entry *entry)
1210 int i;
1212 for (i=0; i<lck->num_share_modes; i++) {
1213 struct share_mode_entry *e = &lck->share_modes[i];
1214 if (is_valid_share_mode_entry(entry) &&
1215 is_valid_share_mode_entry(e) &&
1216 share_modes_identical(e, entry)) {
1217 return e;
1219 if (is_deferred_open_entry(entry) &&
1220 is_deferred_open_entry(e) &&
1221 deferred_open_identical(e, entry)) {
1222 return e;
1225 return NULL;
1228 /*******************************************************************
1229 Del the share mode of a file for this process. Return the number of
1230 entries left.
1231 ********************************************************************/
1233 bool del_share_mode(struct share_mode_lock *lck, files_struct *fsp)
1235 struct share_mode_entry entry, *e;
1237 /* Don't care about the pid owner being correct here - just a search. */
1238 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1240 e = find_share_mode_entry(lck, &entry);
1241 if (e == NULL) {
1242 return False;
1245 e->op_type = UNUSED_SHARE_MODE_ENTRY;
1246 lck->modified = True;
1247 return True;
1250 void del_deferred_open_entry(struct share_mode_lock *lck, uint64_t mid)
1252 struct share_mode_entry entry, *e;
1254 fill_deferred_open_entry(&entry, timeval_zero(),
1255 lck->id, mid);
1257 e = find_share_mode_entry(lck, &entry);
1258 if (e == NULL) {
1259 return;
1262 e->op_type = UNUSED_SHARE_MODE_ENTRY;
1263 lck->modified = True;
1266 /*******************************************************************
1267 Remove an oplock mid and mode entry from a share mode.
1268 ********************************************************************/
1270 bool remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
1272 struct share_mode_entry entry, *e;
1274 /* Don't care about the pid owner being correct here - just a search. */
1275 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1277 e = find_share_mode_entry(lck, &entry);
1278 if (e == NULL) {
1279 return False;
1282 e->op_mid = 0;
1283 if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1285 * Going from exclusive or batch,
1286 * we always go through FAKE_LEVEL_II
1287 * first.
1289 e->op_type = FAKE_LEVEL_II_OPLOCK;
1290 } else {
1291 e->op_type = NO_OPLOCK;
1293 lck->modified = True;
1294 return True;
1297 /*******************************************************************
1298 Downgrade a oplock type from exclusive to level II.
1299 ********************************************************************/
1301 bool downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
1303 struct share_mode_entry entry, *e;
1305 /* Don't care about the pid owner being correct here - just a search. */
1306 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1308 e = find_share_mode_entry(lck, &entry);
1309 if (e == NULL) {
1310 return False;
1313 e->op_type = LEVEL_II_OPLOCK;
1314 lck->modified = True;
1315 return True;
1318 /****************************************************************************
1319 Check if setting delete on close is allowed on this fsp.
1320 ****************************************************************************/
1322 NTSTATUS can_set_delete_on_close(files_struct *fsp, uint32 dosmode)
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 struct share_mode_lock *lck;
1441 DEBUG(10,("set_delete_on_close: %s delete on close flag for "
1442 "fnum = %d, file %s\n",
1443 delete_on_close ? "Adding" : "Removing", fsp->fnum,
1444 fsp_str_dbg(fsp)));
1446 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
1447 NULL);
1448 if (lck == NULL) {
1449 return False;
1452 set_delete_on_close_lck(lck, delete_on_close, tok);
1454 if (fsp->is_directory) {
1455 SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name));
1456 send_stat_cache_delete_message(fsp->fsp_name->base_name);
1459 TALLOC_FREE(lck);
1461 fsp->delete_on_close = delete_on_close;
1463 return True;
1466 bool set_sticky_write_time(struct file_id fileid, struct timespec write_time)
1468 struct share_mode_lock *lck;
1470 DEBUG(5,("set_sticky_write_time: %s id=%s\n",
1471 timestring(talloc_tos(),
1472 convert_timespec_to_time_t(write_time)),
1473 file_id_string_tos(&fileid)));
1475 lck = get_share_mode_lock(NULL, fileid, NULL, NULL, NULL);
1476 if (lck == NULL) {
1477 return False;
1480 if (timespec_compare(&lck->changed_write_time, &write_time) != 0) {
1481 lck->modified = True;
1482 lck->changed_write_time = write_time;
1485 TALLOC_FREE(lck);
1486 return True;
1489 bool set_write_time(struct file_id fileid, struct timespec write_time)
1491 struct share_mode_lock *lck;
1493 DEBUG(5,("set_write_time: %s id=%s\n",
1494 timestring(talloc_tos(),
1495 convert_timespec_to_time_t(write_time)),
1496 file_id_string_tos(&fileid)));
1498 lck = get_share_mode_lock(NULL, fileid, NULL, NULL, NULL);
1499 if (lck == NULL) {
1500 return False;
1503 if (timespec_compare(&lck->old_write_time, &write_time) != 0) {
1504 lck->modified = True;
1505 lck->old_write_time = write_time;
1508 TALLOC_FREE(lck);
1509 return True;
1513 struct forall_state {
1514 void (*fn)(const struct share_mode_entry *entry,
1515 const char *sharepath,
1516 const char *fname,
1517 void *private_data);
1518 void *private_data;
1521 static int traverse_fn(struct db_record *rec, void *_state)
1523 struct forall_state *state = (struct forall_state *)_state;
1524 struct locking_data *data;
1525 struct share_mode_entry *shares;
1526 const char *sharepath;
1527 const char *fname;
1528 int i;
1530 /* Ensure this is a locking_key record. */
1531 if (rec->key.dsize != sizeof(struct file_id))
1532 return 0;
1534 data = (struct locking_data *)rec->value.dptr;
1535 shares = (struct share_mode_entry *)(rec->value.dptr + sizeof(*data));
1536 sharepath = (const char *)rec->value.dptr + sizeof(*data) +
1537 data->u.s.num_share_mode_entries*sizeof(*shares) +
1538 data->u.s.delete_token_size;
1539 fname = (const char *)rec->value.dptr + sizeof(*data) +
1540 data->u.s.num_share_mode_entries*sizeof(*shares) +
1541 data->u.s.delete_token_size +
1542 strlen(sharepath) + 1;
1544 for (i=0;i<data->u.s.num_share_mode_entries;i++) {
1545 state->fn(&shares[i], sharepath, fname,
1546 state->private_data);
1548 return 0;
1551 /*******************************************************************
1552 Call the specified function on each entry under management by the
1553 share mode system.
1554 ********************************************************************/
1556 int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *,
1557 const char *, void *),
1558 void *private_data)
1560 struct forall_state state;
1562 if (lock_db == NULL)
1563 return 0;
1565 state.fn = fn;
1566 state.private_data = private_data;
1568 return lock_db->traverse_read(lock_db, traverse_fn, (void *)&state);