s3-smbclient: Fix cli_errstr() usage (part of bug #7864)
[Samba/gebeck_regimport.git] / source3 / locking / locking.c
blob4a619531769357164c2c80e913aae57e894ab221
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"
41 #include "dbwrap.h"
42 #include "../libcli/security/security.h"
44 #undef DBGC_CLASS
45 #define DBGC_CLASS DBGC_LOCKING
47 #define NO_LOCKING_COUNT (-1)
49 /* the locking database handle */
50 static struct db_context *lock_db;
52 /****************************************************************************
53 Debugging aids :-).
54 ****************************************************************************/
56 const char *lock_type_name(enum brl_type lock_type)
58 switch (lock_type) {
59 case READ_LOCK:
60 return "READ";
61 case WRITE_LOCK:
62 return "WRITE";
63 case PENDING_READ_LOCK:
64 return "PENDING_READ";
65 case PENDING_WRITE_LOCK:
66 return "PENDING_WRITE";
67 default:
68 return "other";
72 const char *lock_flav_name(enum brl_flavour lock_flav)
74 return (lock_flav == WINDOWS_LOCK) ? "WINDOWS_LOCK" : "POSIX_LOCK";
77 /****************************************************************************
78 Utility function called to see if a file region is locked.
79 Called in the read/write codepath.
80 ****************************************************************************/
82 void init_strict_lock_struct(files_struct *fsp,
83 uint64_t smblctx,
84 br_off start,
85 br_off size,
86 enum brl_type lock_type,
87 struct lock_struct *plock)
89 SMB_ASSERT(lock_type == READ_LOCK || lock_type == WRITE_LOCK);
91 plock->context.smblctx = smblctx;
92 plock->context.tid = fsp->conn->cnum;
93 plock->context.pid = sconn_server_id(fsp->conn->sconn);
94 plock->start = start;
95 plock->size = size;
96 plock->fnum = fsp->fnum;
97 plock->lock_type = lock_type;
98 plock->lock_flav = lp_posix_cifsu_locktype(fsp);
101 bool strict_lock_default(files_struct *fsp, struct lock_struct *plock)
103 int strict_locking = lp_strict_locking(fsp->conn->params);
104 bool ret = False;
106 if (plock->size == 0) {
107 return True;
110 if (!lp_locking(fsp->conn->params) || !strict_locking) {
111 return True;
114 if (strict_locking == Auto) {
115 if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (plock->lock_type == READ_LOCK || plock->lock_type == WRITE_LOCK)) {
116 DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp_str_dbg(fsp)));
117 ret = True;
118 } else if ((fsp->oplock_type == LEVEL_II_OPLOCK) &&
119 (plock->lock_type == READ_LOCK)) {
120 DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp_str_dbg(fsp)));
121 ret = True;
122 } else {
123 struct byte_range_lock *br_lck;
125 br_lck = brl_get_locks_readonly(fsp);
126 if (!br_lck) {
127 return True;
129 ret = brl_locktest(br_lck,
130 plock->context.smblctx,
131 plock->context.pid,
132 plock->start,
133 plock->size,
134 plock->lock_type,
135 plock->lock_flav);
137 } else {
138 struct byte_range_lock *br_lck;
140 br_lck = brl_get_locks_readonly(fsp);
141 if (!br_lck) {
142 return True;
144 ret = brl_locktest(br_lck,
145 plock->context.smblctx,
146 plock->context.pid,
147 plock->start,
148 plock->size,
149 plock->lock_type,
150 plock->lock_flav);
153 DEBUG(10,("strict_lock_default: flavour = %s brl start=%.0f "
154 "len=%.0f %s for fnum %d file %s\n",
155 lock_flav_name(plock->lock_flav),
156 (double)plock->start, (double)plock->size,
157 ret ? "unlocked" : "locked",
158 plock->fnum, fsp_str_dbg(fsp)));
160 return ret;
163 void strict_unlock_default(files_struct *fsp, struct lock_struct *plock)
167 /****************************************************************************
168 Find out if a lock could be granted - return who is blocking us if we can't.
169 ****************************************************************************/
171 NTSTATUS query_lock(files_struct *fsp,
172 uint64_t *psmblctx,
173 uint64_t *pcount,
174 uint64_t *poffset,
175 enum brl_type *plock_type,
176 enum brl_flavour lock_flav)
178 struct byte_range_lock *br_lck = NULL;
180 if (!fsp->can_lock) {
181 return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
184 if (!lp_locking(fsp->conn->params)) {
185 return NT_STATUS_OK;
188 br_lck = brl_get_locks_readonly(fsp);
189 if (!br_lck) {
190 return NT_STATUS_NO_MEMORY;
193 return brl_lockquery(br_lck,
194 psmblctx,
195 sconn_server_id(fsp->conn->sconn),
196 poffset,
197 pcount,
198 plock_type,
199 lock_flav);
202 static void increment_current_lock_count(files_struct *fsp,
203 enum brl_flavour lock_flav)
205 if (lock_flav == WINDOWS_LOCK &&
206 fsp->current_lock_count != NO_LOCKING_COUNT) {
207 /* blocking ie. pending, locks also count here,
208 * as this is an efficiency counter to avoid checking
209 * the lock db. on close. JRA. */
211 fsp->current_lock_count++;
212 } else {
213 /* Notice that this has had a POSIX lock request.
214 * We can't count locks after this so forget them.
216 fsp->current_lock_count = NO_LOCKING_COUNT;
220 static void decrement_current_lock_count(files_struct *fsp,
221 enum brl_flavour lock_flav)
223 if (lock_flav == WINDOWS_LOCK &&
224 fsp->current_lock_count != NO_LOCKING_COUNT) {
225 SMB_ASSERT(fsp->current_lock_count > 0);
226 fsp->current_lock_count--;
230 /****************************************************************************
231 Utility function called by locking requests.
232 ****************************************************************************/
234 struct byte_range_lock *do_lock(struct messaging_context *msg_ctx,
235 files_struct *fsp,
236 uint64_t smblctx,
237 uint64_t count,
238 uint64_t offset,
239 enum brl_type lock_type,
240 enum brl_flavour lock_flav,
241 bool blocking_lock,
242 NTSTATUS *perr,
243 uint64_t *psmblctx,
244 struct blocking_lock_record *blr)
246 struct byte_range_lock *br_lck = NULL;
248 /* silently return ok on print files as we don't do locking there */
249 if (fsp->print_file) {
250 *perr = NT_STATUS_OK;
251 return NULL;
254 if (!fsp->can_lock) {
255 *perr = fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
256 return NULL;
259 if (!lp_locking(fsp->conn->params)) {
260 *perr = NT_STATUS_OK;
261 return NULL;
264 /* NOTE! 0 byte long ranges ARE allowed and should be stored */
266 DEBUG(10,("do_lock: lock flavour %s lock type %s start=%.0f len=%.0f "
267 "blocking_lock=%s requested for fnum %d file %s\n",
268 lock_flav_name(lock_flav), lock_type_name(lock_type),
269 (double)offset, (double)count, blocking_lock ? "true" :
270 "false", fsp->fnum, fsp_str_dbg(fsp)));
272 br_lck = brl_get_locks(talloc_tos(), fsp);
273 if (!br_lck) {
274 *perr = NT_STATUS_NO_MEMORY;
275 return NULL;
278 *perr = brl_lock(msg_ctx,
279 br_lck,
280 smblctx,
281 sconn_server_id(fsp->conn->sconn),
282 offset,
283 count,
284 lock_type,
285 lock_flav,
286 blocking_lock,
287 psmblctx,
288 blr);
290 DEBUG(10, ("do_lock: returning status=%s\n", nt_errstr(*perr)));
292 increment_current_lock_count(fsp, lock_flav);
293 return br_lck;
296 /****************************************************************************
297 Utility function called by unlocking requests.
298 ****************************************************************************/
300 NTSTATUS do_unlock(struct messaging_context *msg_ctx,
301 files_struct *fsp,
302 uint64_t smblctx,
303 uint64_t count,
304 uint64_t offset,
305 enum brl_flavour lock_flav)
307 bool ok = False;
308 struct byte_range_lock *br_lck = NULL;
310 if (!fsp->can_lock) {
311 return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
314 if (!lp_locking(fsp->conn->params)) {
315 return NT_STATUS_OK;
318 DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for fnum %d file %s\n",
319 (double)offset, (double)count, fsp->fnum,
320 fsp_str_dbg(fsp)));
322 br_lck = brl_get_locks(talloc_tos(), fsp);
323 if (!br_lck) {
324 return NT_STATUS_NO_MEMORY;
327 ok = brl_unlock(msg_ctx,
328 br_lck,
329 smblctx,
330 sconn_server_id(fsp->conn->sconn),
331 offset,
332 count,
333 lock_flav);
335 TALLOC_FREE(br_lck);
337 if (!ok) {
338 DEBUG(10,("do_unlock: returning ERRlock.\n" ));
339 return NT_STATUS_RANGE_NOT_LOCKED;
342 decrement_current_lock_count(fsp, lock_flav);
343 return NT_STATUS_OK;
346 /****************************************************************************
347 Cancel any pending blocked locks.
348 ****************************************************************************/
350 NTSTATUS do_lock_cancel(files_struct *fsp,
351 uint64 smblctx,
352 uint64_t count,
353 uint64_t offset,
354 enum brl_flavour lock_flav,
355 struct blocking_lock_record *blr)
357 bool ok = False;
358 struct byte_range_lock *br_lck = NULL;
360 if (!fsp->can_lock) {
361 return fsp->is_directory ?
362 NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
365 if (!lp_locking(fsp->conn->params)) {
366 return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
369 DEBUG(10,("do_lock_cancel: cancel start=%.0f len=%.0f requested for fnum %d file %s\n",
370 (double)offset, (double)count, fsp->fnum,
371 fsp_str_dbg(fsp)));
373 br_lck = brl_get_locks(talloc_tos(), fsp);
374 if (!br_lck) {
375 return NT_STATUS_NO_MEMORY;
378 ok = brl_lock_cancel(br_lck,
379 smblctx,
380 sconn_server_id(fsp->conn->sconn),
381 offset,
382 count,
383 lock_flav,
384 blr);
386 TALLOC_FREE(br_lck);
388 if (!ok) {
389 DEBUG(10,("do_lock_cancel: returning ERRcancelviolation.\n" ));
390 return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
393 decrement_current_lock_count(fsp, lock_flav);
394 return NT_STATUS_OK;
397 /****************************************************************************
398 Remove any locks on this fd. Called from file_close().
399 ****************************************************************************/
401 void locking_close_file(struct messaging_context *msg_ctx,
402 files_struct *fsp,
403 enum file_close_type close_type)
405 struct byte_range_lock *br_lck;
407 if (!lp_locking(fsp->conn->params)) {
408 return;
411 /* If we have not outstanding locks or pending
412 * locks then we don't need to look in the lock db.
415 if (fsp->current_lock_count == 0) {
416 return;
419 br_lck = brl_get_locks(talloc_tos(),fsp);
421 if (br_lck) {
422 cancel_pending_lock_requests_by_fid(fsp, br_lck, close_type);
423 brl_close_fnum(msg_ctx, br_lck);
424 TALLOC_FREE(br_lck);
428 /****************************************************************************
429 Initialise the locking functions.
430 ****************************************************************************/
432 static bool locking_init_internal(bool read_only)
434 brl_init(read_only);
436 if (lock_db)
437 return True;
439 lock_db = db_open(NULL, lock_path("locking.tdb"),
440 lp_open_files_db_hash_size(),
441 TDB_DEFAULT|TDB_VOLATILE|TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH,
442 read_only?O_RDONLY:O_RDWR|O_CREAT, 0644);
444 if (!lock_db) {
445 DEBUG(0,("ERROR: Failed to initialise locking database\n"));
446 return False;
449 if (!posix_locking_init(read_only))
450 return False;
452 return True;
455 bool locking_init(void)
457 return locking_init_internal(false);
460 bool locking_init_readonly(void)
462 return locking_init_internal(true);
465 /*******************************************************************
466 Deinitialize the share_mode management.
467 ******************************************************************/
469 bool locking_end(void)
471 brl_shutdown();
472 TALLOC_FREE(lock_db);
473 return true;
476 /*******************************************************************
477 Form a static locking key for a dev/inode pair.
478 ******************************************************************/
480 static TDB_DATA locking_key(const struct file_id *id, struct file_id *tmp)
482 *tmp = *id;
483 return make_tdb_data((const uint8_t *)tmp, sizeof(*tmp));
486 /*******************************************************************
487 Print out a share mode.
488 ********************************************************************/
490 char *share_mode_str(TALLOC_CTX *ctx, int num, const struct share_mode_entry *e)
492 return talloc_asprintf(ctx, "share_mode_entry[%d]: %s "
493 "pid = %s, share_access = 0x%x, private_options = 0x%x, "
494 "access_mask = 0x%x, mid = 0x%llx, type= 0x%x, gen_id = %lu, "
495 "uid = %u, flags = %u, file_id %s",
496 num,
497 e->op_type == UNUSED_SHARE_MODE_ENTRY ? "UNUSED" : "",
498 procid_str_static(&e->pid),
499 e->share_access, e->private_options,
500 e->access_mask, (unsigned long long)e->op_mid,
501 e->op_type, e->share_file_id,
502 (unsigned int)e->uid, (unsigned int)e->flags,
503 file_id_string_tos(&e->id));
506 /*******************************************************************
507 Print out a share mode table.
508 ********************************************************************/
510 static void print_share_mode_table(struct locking_data *data)
512 int num_share_modes = data->u.s.num_share_mode_entries;
513 struct share_mode_entry *shares =
514 (struct share_mode_entry *)(data + 1);
515 int i;
517 for (i = 0; i < num_share_modes; i++) {
518 struct share_mode_entry entry;
519 char *str;
522 * We need to memcpy the entry here due to alignment
523 * restrictions that are not met when directly accessing
524 * shares[i]
527 memcpy(&entry, &shares[i], sizeof(struct share_mode_entry));
528 str = share_mode_str(talloc_tos(), i, &entry);
530 DEBUG(10,("print_share_mode_table: %s\n", str ? str : ""));
531 TALLOC_FREE(str);
535 /*******************************************************************
536 Get all share mode entries for a dev/inode pair.
537 ********************************************************************/
539 static bool parse_share_modes(const TDB_DATA dbuf, struct share_mode_lock *lck)
541 struct locking_data data;
542 int i;
544 if (dbuf.dsize < sizeof(struct locking_data)) {
545 smb_panic("parse_share_modes: buffer too short");
548 memcpy(&data, dbuf.dptr, sizeof(data));
550 lck->delete_on_close = data.u.s.delete_on_close;
551 lck->old_write_time = data.u.s.old_write_time;
552 lck->changed_write_time = data.u.s.changed_write_time;
553 lck->num_share_modes = data.u.s.num_share_mode_entries;
555 DEBUG(10, ("parse_share_modes: delete_on_close: %d, owrt: %s, "
556 "cwrt: %s, tok: %u, num_share_modes: %d\n",
557 lck->delete_on_close,
558 timestring(talloc_tos(),
559 convert_timespec_to_time_t(lck->old_write_time)),
560 timestring(talloc_tos(),
561 convert_timespec_to_time_t(
562 lck->changed_write_time)),
563 (unsigned int)data.u.s.delete_token_size,
564 lck->num_share_modes));
566 if ((lck->num_share_modes < 0) || (lck->num_share_modes > 1000000)) {
567 DEBUG(0, ("invalid number of share modes: %d\n",
568 lck->num_share_modes));
569 smb_panic("parse_share_modes: invalid number of share modes");
572 lck->share_modes = NULL;
574 if (lck->num_share_modes != 0) {
576 if (dbuf.dsize < (sizeof(struct locking_data) +
577 (lck->num_share_modes *
578 sizeof(struct share_mode_entry)))) {
579 smb_panic("parse_share_modes: buffer too short");
582 lck->share_modes = (struct share_mode_entry *)
583 TALLOC_MEMDUP(lck,
584 dbuf.dptr+sizeof(struct locking_data),
585 lck->num_share_modes *
586 sizeof(struct share_mode_entry));
588 if (lck->share_modes == NULL) {
589 smb_panic("parse_share_modes: talloc failed");
593 /* Get any delete token. */
594 if (data.u.s.delete_token_size) {
595 uint8 *p = dbuf.dptr + sizeof(struct locking_data) +
596 (lck->num_share_modes *
597 sizeof(struct share_mode_entry));
599 if ((data.u.s.delete_token_size < sizeof(uid_t) + sizeof(gid_t)) ||
600 ((data.u.s.delete_token_size - sizeof(uid_t)) % sizeof(gid_t)) != 0) {
601 DEBUG(0, ("parse_share_modes: invalid token size %d\n",
602 data.u.s.delete_token_size));
603 smb_panic("parse_share_modes: invalid token size");
606 lck->delete_token = TALLOC_P(lck, UNIX_USER_TOKEN);
607 if (!lck->delete_token) {
608 smb_panic("parse_share_modes: talloc failed");
611 /* Copy out the uid and gid. */
612 memcpy(&lck->delete_token->uid, p, sizeof(uid_t));
613 p += sizeof(uid_t);
614 memcpy(&lck->delete_token->gid, p, sizeof(gid_t));
615 p += sizeof(gid_t);
617 /* Any supplementary groups ? */
618 lck->delete_token->ngroups = (data.u.s.delete_token_size > (sizeof(uid_t) + sizeof(gid_t))) ?
619 ((data.u.s.delete_token_size -
620 (sizeof(uid_t) + sizeof(gid_t)))/sizeof(gid_t)) : 0;
622 if (lck->delete_token->ngroups) {
623 /* Make this a talloc child of lck->delete_token. */
624 lck->delete_token->groups = TALLOC_ARRAY(lck->delete_token, gid_t,
625 lck->delete_token->ngroups);
626 if (!lck->delete_token) {
627 smb_panic("parse_share_modes: talloc failed");
630 for (i = 0; i < lck->delete_token->ngroups; i++) {
631 memcpy(&lck->delete_token->groups[i], p, sizeof(gid_t));
632 p += sizeof(gid_t);
636 } else {
637 lck->delete_token = NULL;
640 /* Save off the associated service path and filename. */
641 lck->servicepath = (const char *)dbuf.dptr + sizeof(struct locking_data) +
642 (lck->num_share_modes * sizeof(struct share_mode_entry)) +
643 data.u.s.delete_token_size;
645 lck->base_name = (const char *)dbuf.dptr + sizeof(struct locking_data) +
646 (lck->num_share_modes * sizeof(struct share_mode_entry)) +
647 data.u.s.delete_token_size +
648 strlen(lck->servicepath) + 1;
650 lck->stream_name = (const char *)dbuf.dptr + sizeof(struct locking_data) +
651 (lck->num_share_modes * sizeof(struct share_mode_entry)) +
652 data.u.s.delete_token_size +
653 strlen(lck->servicepath) + 1 +
654 strlen(lck->base_name) + 1;
657 * Ensure that each entry has a real process attached.
660 for (i = 0; i < lck->num_share_modes; i++) {
661 struct share_mode_entry *entry_p = &lck->share_modes[i];
662 char *str = NULL;
663 if (DEBUGLEVEL >= 10) {
664 str = share_mode_str(NULL, i, entry_p);
666 DEBUG(10,("parse_share_modes: %s\n",
667 str ? str : ""));
668 if (!serverid_exists(&entry_p->pid)) {
669 DEBUG(10,("parse_share_modes: deleted %s\n",
670 str ? str : ""));
671 entry_p->op_type = UNUSED_SHARE_MODE_ENTRY;
672 lck->modified = True;
674 TALLOC_FREE(str);
677 return True;
680 static TDB_DATA unparse_share_modes(const struct share_mode_lock *lck)
682 TDB_DATA result;
683 int num_valid = 0;
684 int i;
685 struct locking_data *data;
686 ssize_t offset;
687 ssize_t sp_len, bn_len, sn_len;
688 uint32 delete_token_size;
690 result.dptr = NULL;
691 result.dsize = 0;
693 for (i=0; i<lck->num_share_modes; i++) {
694 if (!is_unused_share_mode_entry(&lck->share_modes[i])) {
695 num_valid += 1;
699 if (num_valid == 0) {
700 return result;
703 sp_len = strlen(lck->servicepath);
704 bn_len = strlen(lck->base_name);
705 sn_len = lck->stream_name != NULL ? strlen(lck->stream_name) : 0;
707 delete_token_size = (lck->delete_token ?
708 (sizeof(uid_t) + sizeof(gid_t) + (lck->delete_token->ngroups*sizeof(gid_t))) : 0);
710 result.dsize = sizeof(*data) +
711 lck->num_share_modes * sizeof(struct share_mode_entry) +
712 delete_token_size +
713 sp_len + 1 +
714 bn_len + 1 +
715 sn_len + 1;
716 result.dptr = TALLOC_ARRAY(lck, uint8, result.dsize);
718 if (result.dptr == NULL) {
719 smb_panic("talloc failed");
722 data = (struct locking_data *)result.dptr;
723 ZERO_STRUCTP(data);
724 data->u.s.num_share_mode_entries = lck->num_share_modes;
725 data->u.s.delete_on_close = lck->delete_on_close;
726 data->u.s.old_write_time = lck->old_write_time;
727 data->u.s.changed_write_time = lck->changed_write_time;
728 data->u.s.delete_token_size = delete_token_size;
730 DEBUG(10,("unparse_share_modes: del: %d, owrt: %s cwrt: %s, tok: %u, "
731 "num: %d\n", data->u.s.delete_on_close,
732 timestring(talloc_tos(),
733 convert_timespec_to_time_t(lck->old_write_time)),
734 timestring(talloc_tos(),
735 convert_timespec_to_time_t(
736 lck->changed_write_time)),
737 (unsigned int)data->u.s.delete_token_size,
738 data->u.s.num_share_mode_entries));
740 memcpy(result.dptr + sizeof(*data), lck->share_modes,
741 sizeof(struct share_mode_entry)*lck->num_share_modes);
742 offset = sizeof(*data) +
743 sizeof(struct share_mode_entry)*lck->num_share_modes;
745 /* Store any delete on close token. */
746 if (lck->delete_token) {
747 uint8 *p = result.dptr + offset;
749 memcpy(p, &lck->delete_token->uid, sizeof(uid_t));
750 p += sizeof(uid_t);
752 memcpy(p, &lck->delete_token->gid, sizeof(gid_t));
753 p += sizeof(gid_t);
755 for (i = 0; i < lck->delete_token->ngroups; i++) {
756 memcpy(p, &lck->delete_token->groups[i], sizeof(gid_t));
757 p += sizeof(gid_t);
759 offset = p - result.dptr;
762 safe_strcpy((char *)result.dptr + offset, lck->servicepath,
763 result.dsize - offset - 1);
764 offset += sp_len + 1;
765 safe_strcpy((char *)result.dptr + offset, lck->base_name,
766 result.dsize - offset - 1);
767 offset += bn_len + 1;
768 safe_strcpy((char *)result.dptr + offset, lck->stream_name,
769 result.dsize - offset - 1);
771 if (DEBUGLEVEL >= 10) {
772 print_share_mode_table(data);
775 return result;
778 static int share_mode_lock_destructor(struct share_mode_lock *lck)
780 NTSTATUS status;
781 TDB_DATA data;
783 if (!lck->modified) {
784 return 0;
787 data = unparse_share_modes(lck);
789 if (data.dptr == NULL) {
790 if (!lck->fresh) {
791 /* There has been an entry before, delete it */
793 status = lck->record->delete_rec(lck->record);
794 if (!NT_STATUS_IS_OK(status)) {
795 char *errmsg;
797 DEBUG(0, ("delete_rec returned %s\n",
798 nt_errstr(status)));
800 if (asprintf(&errmsg, "could not delete share "
801 "entry: %s\n",
802 nt_errstr(status)) == -1) {
803 smb_panic("could not delete share"
804 "entry");
806 smb_panic(errmsg);
809 goto done;
812 status = lck->record->store(lck->record, data, TDB_REPLACE);
813 if (!NT_STATUS_IS_OK(status)) {
814 char *errmsg;
816 DEBUG(0, ("store returned %s\n", nt_errstr(status)));
818 if (asprintf(&errmsg, "could not store share mode entry: %s",
819 nt_errstr(status)) == -1) {
820 smb_panic("could not store share mode entry");
822 smb_panic(errmsg);
825 done:
827 return 0;
830 static bool fill_share_mode_lock(struct share_mode_lock *lck,
831 struct file_id id,
832 const char *servicepath,
833 const struct smb_filename *smb_fname,
834 TDB_DATA share_mode_data,
835 const struct timespec *old_write_time)
837 /* Ensure we set every field here as the destructor must be
838 valid even if parse_share_modes fails. */
840 lck->servicepath = NULL;
841 lck->base_name = NULL;
842 lck->stream_name = NULL;
843 lck->id = id;
844 lck->num_share_modes = 0;
845 lck->share_modes = NULL;
846 lck->delete_token = NULL;
847 lck->delete_on_close = False;
848 ZERO_STRUCT(lck->old_write_time);
849 ZERO_STRUCT(lck->changed_write_time);
850 lck->fresh = False;
851 lck->modified = False;
853 lck->fresh = (share_mode_data.dptr == NULL);
855 if (lck->fresh) {
856 bool has_stream;
857 if (smb_fname == NULL || servicepath == NULL
858 || old_write_time == NULL) {
859 return False;
862 has_stream = smb_fname->stream_name != NULL;
864 lck->base_name = talloc_strdup(lck, smb_fname->base_name);
865 lck->stream_name = talloc_strdup(lck, smb_fname->stream_name);
866 lck->servicepath = talloc_strdup(lck, servicepath);
867 if (lck->base_name == NULL ||
868 (has_stream && lck->stream_name == NULL) ||
869 lck->servicepath == NULL) {
870 DEBUG(0, ("talloc failed\n"));
871 return False;
873 lck->old_write_time = *old_write_time;
874 } else {
875 if (!parse_share_modes(share_mode_data, lck)) {
876 DEBUG(0, ("Could not parse share modes\n"));
877 return False;
881 return True;
884 struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
885 const struct file_id id,
886 const char *servicepath,
887 const struct smb_filename *smb_fname,
888 const struct timespec *old_write_time)
890 struct share_mode_lock *lck;
891 struct file_id tmp;
892 TDB_DATA key = locking_key(&id, &tmp);
894 if (!(lck = TALLOC_P(mem_ctx, struct share_mode_lock))) {
895 DEBUG(0, ("talloc failed\n"));
896 return NULL;
899 if (!(lck->record = lock_db->fetch_locked(lock_db, lck, key))) {
900 DEBUG(3, ("Could not lock share entry\n"));
901 TALLOC_FREE(lck);
902 return NULL;
905 if (!fill_share_mode_lock(lck, id, servicepath, smb_fname,
906 lck->record->value, old_write_time)) {
907 DEBUG(3, ("fill_share_mode_lock failed\n"));
908 TALLOC_FREE(lck);
909 return NULL;
912 talloc_set_destructor(lck, share_mode_lock_destructor);
914 return lck;
917 struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx,
918 const struct file_id id)
920 struct share_mode_lock *lck;
921 struct file_id tmp;
922 TDB_DATA key = locking_key(&id, &tmp);
923 TDB_DATA data;
925 if (!(lck = TALLOC_P(mem_ctx, struct share_mode_lock))) {
926 DEBUG(0, ("talloc failed\n"));
927 return NULL;
930 if (lock_db->fetch(lock_db, lck, key, &data) == -1) {
931 DEBUG(3, ("Could not fetch share entry\n"));
932 TALLOC_FREE(lck);
933 return NULL;
936 if (!fill_share_mode_lock(lck, id, NULL, NULL, data, NULL)) {
937 DEBUG(10, ("fetch_share_mode_unlocked: no share_mode record "
938 "around (file not open)\n"));
939 TALLOC_FREE(lck);
940 return NULL;
943 return lck;
946 /*******************************************************************
947 Sets the service name and filename for rename.
948 At this point we emit "file renamed" messages to all
949 process id's that have this file open.
950 Based on an initial code idea from SATOH Fumiyasu <fumiya@samba.gr.jp>
951 ********************************************************************/
953 bool rename_share_filename(struct messaging_context *msg_ctx,
954 struct share_mode_lock *lck,
955 const char *servicepath,
956 const struct smb_filename *smb_fname_dst)
958 size_t sp_len;
959 size_t bn_len;
960 size_t sn_len;
961 size_t msg_len;
962 char *frm = NULL;
963 int i;
964 bool strip_two_chars = false;
965 bool has_stream = smb_fname_dst->stream_name != NULL;
967 DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n",
968 servicepath, smb_fname_dst->base_name));
971 * rename_internal_fsp() and rename_internals() add './' to
972 * head of newname if newname does not contain a '/'.
974 if (smb_fname_dst->base_name[0] &&
975 smb_fname_dst->base_name[1] &&
976 smb_fname_dst->base_name[0] == '.' &&
977 smb_fname_dst->base_name[1] == '/') {
978 strip_two_chars = true;
981 lck->servicepath = talloc_strdup(lck, servicepath);
982 lck->base_name = talloc_strdup(lck, smb_fname_dst->base_name +
983 (strip_two_chars ? 2 : 0));
984 lck->stream_name = talloc_strdup(lck, smb_fname_dst->stream_name);
985 if (lck->base_name == NULL ||
986 (has_stream && lck->stream_name == NULL) ||
987 lck->servicepath == NULL) {
988 DEBUG(0, ("rename_share_filename: talloc failed\n"));
989 return False;
991 lck->modified = True;
993 sp_len = strlen(lck->servicepath);
994 bn_len = strlen(lck->base_name);
995 sn_len = has_stream ? strlen(lck->stream_name) : 0;
997 msg_len = MSG_FILE_RENAMED_MIN_SIZE + sp_len + 1 + bn_len + 1 +
998 sn_len + 1;
1000 /* Set up the name changed message. */
1001 frm = TALLOC_ARRAY(lck, char, msg_len);
1002 if (!frm) {
1003 return False;
1006 push_file_id_24(frm, &lck->id);
1008 DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len ));
1010 safe_strcpy(&frm[24], lck->servicepath, sp_len);
1011 safe_strcpy(&frm[24 + sp_len + 1], lck->base_name, bn_len);
1012 safe_strcpy(&frm[24 + sp_len + 1 + bn_len + 1], lck->stream_name,
1013 sn_len);
1015 /* Send the messages. */
1016 for (i=0; i<lck->num_share_modes; i++) {
1017 struct share_mode_entry *se = &lck->share_modes[i];
1018 if (!is_valid_share_mode_entry(se)) {
1019 continue;
1021 /* But not to ourselves... */
1022 if (procid_is_me(&se->pid)) {
1023 continue;
1026 DEBUG(10,("rename_share_filename: sending rename message to "
1027 "pid %s file_id %s sharepath %s base_name %s "
1028 "stream_name %s\n",
1029 procid_str_static(&se->pid),
1030 file_id_string_tos(&lck->id),
1031 lck->servicepath, lck->base_name,
1032 has_stream ? lck->stream_name : ""));
1034 messaging_send_buf(msg_ctx, se->pid, MSG_SMB_FILE_RENAME,
1035 (uint8 *)frm, msg_len);
1038 return True;
1041 void get_file_infos(struct file_id id,
1042 bool *delete_on_close,
1043 struct timespec *write_time)
1045 struct share_mode_lock *lck;
1047 if (delete_on_close) {
1048 *delete_on_close = false;
1051 if (write_time) {
1052 ZERO_STRUCTP(write_time);
1055 if (!(lck = fetch_share_mode_unlocked(talloc_tos(), id))) {
1056 return;
1059 if (delete_on_close) {
1060 *delete_on_close = lck->delete_on_close;
1063 if (write_time) {
1064 struct timespec wt;
1066 wt = lck->changed_write_time;
1067 if (null_timespec(wt)) {
1068 wt = lck->old_write_time;
1071 *write_time = wt;
1074 TALLOC_FREE(lck);
1077 bool is_valid_share_mode_entry(const struct share_mode_entry *e)
1079 int num_props = 0;
1081 if (e->op_type == UNUSED_SHARE_MODE_ENTRY) {
1082 /* cope with dead entries from the process not
1083 existing. These should not be considered valid,
1084 otherwise we end up doing zero timeout sharing
1085 violation */
1086 return False;
1089 num_props += ((e->op_type == NO_OPLOCK) ? 1 : 0);
1090 num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0);
1091 num_props += (LEVEL_II_OPLOCK_TYPE(e->op_type) ? 1 : 0);
1093 SMB_ASSERT(num_props <= 1);
1094 return (num_props != 0);
1097 bool is_deferred_open_entry(const struct share_mode_entry *e)
1099 return (e->op_type == DEFERRED_OPEN_ENTRY);
1102 bool is_unused_share_mode_entry(const struct share_mode_entry *e)
1104 return (e->op_type == UNUSED_SHARE_MODE_ENTRY);
1107 /*******************************************************************
1108 Fill a share mode entry.
1109 ********************************************************************/
1111 static void fill_share_mode_entry(struct share_mode_entry *e,
1112 files_struct *fsp,
1113 uid_t uid, uint64_t mid, uint16 op_type)
1115 ZERO_STRUCTP(e);
1116 e->pid = sconn_server_id(fsp->conn->sconn);
1117 e->share_access = fsp->share_access;
1118 e->private_options = fsp->fh->private_options;
1119 e->access_mask = fsp->access_mask;
1120 e->op_mid = mid;
1121 e->op_type = op_type;
1122 e->time.tv_sec = fsp->open_time.tv_sec;
1123 e->time.tv_usec = fsp->open_time.tv_usec;
1124 e->id = fsp->file_id;
1125 e->share_file_id = fsp->fh->gen_id;
1126 e->uid = (uint32)uid;
1127 e->flags = fsp->posix_open ? SHARE_MODE_FLAG_POSIX_OPEN : 0;
1130 static void fill_deferred_open_entry(struct share_mode_entry *e,
1131 const struct timeval request_time,
1132 struct file_id id,
1133 struct server_id pid,
1134 uint64_t mid)
1136 ZERO_STRUCTP(e);
1137 e->pid = pid;
1138 e->op_mid = mid;
1139 e->op_type = DEFERRED_OPEN_ENTRY;
1140 e->time.tv_sec = request_time.tv_sec;
1141 e->time.tv_usec = request_time.tv_usec;
1142 e->id = id;
1143 e->uid = (uint32)-1;
1144 e->flags = 0;
1147 static void add_share_mode_entry(struct share_mode_lock *lck,
1148 const struct share_mode_entry *entry)
1150 int i;
1152 for (i=0; i<lck->num_share_modes; i++) {
1153 struct share_mode_entry *e = &lck->share_modes[i];
1154 if (is_unused_share_mode_entry(e)) {
1155 *e = *entry;
1156 break;
1160 if (i == lck->num_share_modes) {
1161 /* No unused entry found */
1162 ADD_TO_ARRAY(lck, struct share_mode_entry, *entry,
1163 &lck->share_modes, &lck->num_share_modes);
1165 lck->modified = True;
1168 void set_share_mode(struct share_mode_lock *lck, files_struct *fsp,
1169 uid_t uid, uint64_t mid, uint16 op_type)
1171 struct share_mode_entry entry;
1172 fill_share_mode_entry(&entry, fsp, uid, mid, op_type);
1173 add_share_mode_entry(lck, &entry);
1176 void add_deferred_open(struct share_mode_lock *lck, uint64_t mid,
1177 struct timeval request_time,
1178 struct server_id pid, struct file_id id)
1180 struct share_mode_entry entry;
1181 fill_deferred_open_entry(&entry, request_time, id, pid, mid);
1182 add_share_mode_entry(lck, &entry);
1185 /*******************************************************************
1186 Check if two share mode entries are identical, ignoring oplock
1187 and mid info and desired_access. (Removed paranoia test - it's
1188 not automatically a logic error if they are identical. JRA.)
1189 ********************************************************************/
1191 static bool share_modes_identical(struct share_mode_entry *e1,
1192 struct share_mode_entry *e2)
1194 /* We used to check for e1->share_access == e2->share_access here
1195 as well as the other fields but 2 different DOS or FCB opens
1196 sharing the same share mode entry may validly differ in
1197 fsp->share_access field. */
1199 return (procid_equal(&e1->pid, &e2->pid) &&
1200 file_id_equal(&e1->id, &e2->id) &&
1201 e1->share_file_id == e2->share_file_id );
1204 static bool deferred_open_identical(struct share_mode_entry *e1,
1205 struct share_mode_entry *e2)
1207 return (procid_equal(&e1->pid, &e2->pid) &&
1208 (e1->op_mid == e2->op_mid) &&
1209 file_id_equal(&e1->id, &e2->id));
1212 static struct share_mode_entry *find_share_mode_entry(struct share_mode_lock *lck,
1213 struct share_mode_entry *entry)
1215 int i;
1217 for (i=0; i<lck->num_share_modes; i++) {
1218 struct share_mode_entry *e = &lck->share_modes[i];
1219 if (is_valid_share_mode_entry(entry) &&
1220 is_valid_share_mode_entry(e) &&
1221 share_modes_identical(e, entry)) {
1222 return e;
1224 if (is_deferred_open_entry(entry) &&
1225 is_deferred_open_entry(e) &&
1226 deferred_open_identical(e, entry)) {
1227 return e;
1230 return NULL;
1233 /*******************************************************************
1234 Del the share mode of a file for this process. Return the number of
1235 entries left.
1236 ********************************************************************/
1238 bool del_share_mode(struct share_mode_lock *lck, files_struct *fsp)
1240 struct share_mode_entry entry, *e;
1242 /* Don't care about the pid owner being correct here - just a search. */
1243 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1245 e = find_share_mode_entry(lck, &entry);
1246 if (e == NULL) {
1247 return False;
1250 e->op_type = UNUSED_SHARE_MODE_ENTRY;
1251 lck->modified = True;
1252 return True;
1255 void del_deferred_open_entry(struct share_mode_lock *lck, uint64_t mid,
1256 struct server_id pid)
1258 struct share_mode_entry entry, *e;
1260 fill_deferred_open_entry(&entry, timeval_zero(),
1261 lck->id, pid, mid);
1263 e = find_share_mode_entry(lck, &entry);
1264 if (e == NULL) {
1265 return;
1268 e->op_type = UNUSED_SHARE_MODE_ENTRY;
1269 lck->modified = True;
1272 /*******************************************************************
1273 Remove an oplock mid and mode entry from a share mode.
1274 ********************************************************************/
1276 bool remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
1278 struct share_mode_entry entry, *e;
1280 /* Don't care about the pid owner being correct here - just a search. */
1281 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1283 e = find_share_mode_entry(lck, &entry);
1284 if (e == NULL) {
1285 return False;
1288 e->op_mid = 0;
1289 if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1291 * Going from exclusive or batch,
1292 * we always go through FAKE_LEVEL_II
1293 * first.
1295 e->op_type = FAKE_LEVEL_II_OPLOCK;
1296 } else {
1297 e->op_type = NO_OPLOCK;
1299 lck->modified = True;
1300 return True;
1303 /*******************************************************************
1304 Downgrade a oplock type from exclusive to level II.
1305 ********************************************************************/
1307 bool downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
1309 struct share_mode_entry entry, *e;
1311 /* Don't care about the pid owner being correct here - just a search. */
1312 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1314 e = find_share_mode_entry(lck, &entry);
1315 if (e == NULL) {
1316 return False;
1319 e->op_type = LEVEL_II_OPLOCK;
1320 lck->modified = True;
1321 return True;
1324 /****************************************************************************
1325 Check if setting delete on close is allowed on this fsp.
1326 ****************************************************************************/
1328 NTSTATUS can_set_delete_on_close(files_struct *fsp, uint32 dosmode)
1331 * Only allow delete on close for writable files.
1334 if ((dosmode & aRONLY) &&
1335 !lp_delete_readonly(SNUM(fsp->conn))) {
1336 DEBUG(10,("can_set_delete_on_close: file %s delete on close "
1337 "flag set but file attribute is readonly.\n",
1338 fsp_str_dbg(fsp)));
1339 return NT_STATUS_CANNOT_DELETE;
1343 * Only allow delete on close for writable shares.
1346 if (!CAN_WRITE(fsp->conn)) {
1347 DEBUG(10,("can_set_delete_on_close: file %s delete on "
1348 "close flag set but write access denied on share.\n",
1349 fsp_str_dbg(fsp)));
1350 return NT_STATUS_ACCESS_DENIED;
1354 * Only allow delete on close for files/directories opened with delete
1355 * intent.
1358 if (!(fsp->access_mask & DELETE_ACCESS)) {
1359 DEBUG(10,("can_set_delete_on_close: file %s delete on "
1360 "close flag set but delete access denied.\n",
1361 fsp_str_dbg(fsp)));
1362 return NT_STATUS_ACCESS_DENIED;
1365 /* Don't allow delete on close for non-empty directories. */
1366 if (fsp->is_directory) {
1367 SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name));
1368 return can_delete_directory(fsp->conn,
1369 fsp->fsp_name->base_name);
1372 return NT_STATUS_OK;
1375 /*************************************************************************
1376 Return a talloced copy of a UNIX_USER_TOKEN. NULL on fail.
1377 (Should this be in locking.c.... ?).
1378 *************************************************************************/
1380 static UNIX_USER_TOKEN *copy_unix_token(TALLOC_CTX *ctx, const UNIX_USER_TOKEN *tok)
1382 UNIX_USER_TOKEN *cpy;
1384 if (tok == NULL) {
1385 return NULL;
1388 cpy = TALLOC_P(ctx, UNIX_USER_TOKEN);
1389 if (!cpy) {
1390 return NULL;
1393 cpy->uid = tok->uid;
1394 cpy->gid = tok->gid;
1395 cpy->ngroups = tok->ngroups;
1396 if (tok->ngroups) {
1397 /* Make this a talloc child of cpy. */
1398 cpy->groups = TALLOC_ARRAY(cpy, gid_t, tok->ngroups);
1399 if (!cpy->groups) {
1400 return NULL;
1402 memcpy(cpy->groups, tok->groups, tok->ngroups * sizeof(gid_t));
1404 return cpy;
1407 /****************************************************************************
1408 Replace the delete on close token.
1409 ****************************************************************************/
1411 void set_delete_on_close_token(struct share_mode_lock *lck, const UNIX_USER_TOKEN *tok)
1413 TALLOC_FREE(lck->delete_token); /* Also deletes groups... */
1415 /* Copy the new token (can be NULL). */
1416 lck->delete_token = copy_unix_token(lck, tok);
1417 lck->modified = True;
1420 /****************************************************************************
1421 Sets the delete on close flag over all share modes on this file.
1422 Modify the share mode entry for all files open
1423 on this device and inode to tell other smbds we have
1424 changed the delete on close flag. This will be noticed
1425 in the close code, the last closer will delete the file
1426 if flag is set.
1427 This makes a copy of any UNIX_USER_TOKEN into the
1428 lck entry. This function is used when the lock is already granted.
1429 ****************************************************************************/
1431 void set_delete_on_close_lck(struct share_mode_lock *lck, bool delete_on_close, const UNIX_USER_TOKEN *tok)
1433 if (lck->delete_on_close != delete_on_close) {
1434 set_delete_on_close_token(lck, tok);
1435 lck->delete_on_close = delete_on_close;
1436 if (delete_on_close) {
1437 SMB_ASSERT(lck->delete_token != NULL);
1439 lck->modified = True;
1443 bool set_delete_on_close(files_struct *fsp, bool delete_on_close, const UNIX_USER_TOKEN *tok)
1445 struct share_mode_lock *lck;
1447 DEBUG(10,("set_delete_on_close: %s delete on close flag for "
1448 "fnum = %d, file %s\n",
1449 delete_on_close ? "Adding" : "Removing", fsp->fnum,
1450 fsp_str_dbg(fsp)));
1452 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
1453 NULL);
1454 if (lck == NULL) {
1455 return False;
1458 set_delete_on_close_lck(lck, delete_on_close, tok);
1460 if (fsp->is_directory) {
1461 SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name));
1462 send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
1463 fsp->fsp_name->base_name);
1466 TALLOC_FREE(lck);
1468 fsp->delete_on_close = delete_on_close;
1470 return True;
1473 bool set_sticky_write_time(struct file_id fileid, struct timespec write_time)
1475 struct share_mode_lock *lck;
1477 DEBUG(5,("set_sticky_write_time: %s id=%s\n",
1478 timestring(talloc_tos(),
1479 convert_timespec_to_time_t(write_time)),
1480 file_id_string_tos(&fileid)));
1482 lck = get_share_mode_lock(NULL, fileid, NULL, NULL, NULL);
1483 if (lck == NULL) {
1484 return False;
1487 if (timespec_compare(&lck->changed_write_time, &write_time) != 0) {
1488 lck->modified = True;
1489 lck->changed_write_time = write_time;
1492 TALLOC_FREE(lck);
1493 return True;
1496 bool set_write_time(struct file_id fileid, struct timespec write_time)
1498 struct share_mode_lock *lck;
1500 DEBUG(5,("set_write_time: %s id=%s\n",
1501 timestring(talloc_tos(),
1502 convert_timespec_to_time_t(write_time)),
1503 file_id_string_tos(&fileid)));
1505 lck = get_share_mode_lock(NULL, fileid, NULL, NULL, NULL);
1506 if (lck == NULL) {
1507 return False;
1510 if (timespec_compare(&lck->old_write_time, &write_time) != 0) {
1511 lck->modified = True;
1512 lck->old_write_time = write_time;
1515 TALLOC_FREE(lck);
1516 return True;
1520 struct forall_state {
1521 void (*fn)(const struct share_mode_entry *entry,
1522 const char *sharepath,
1523 const char *fname,
1524 void *private_data);
1525 void *private_data;
1528 static int traverse_fn(struct db_record *rec, void *_state)
1530 struct forall_state *state = (struct forall_state *)_state;
1531 struct locking_data *data;
1532 struct share_mode_entry *shares;
1533 const char *sharepath;
1534 const char *fname;
1535 int i;
1537 /* Ensure this is a locking_key record. */
1538 if (rec->key.dsize != sizeof(struct file_id))
1539 return 0;
1541 data = (struct locking_data *)rec->value.dptr;
1542 shares = (struct share_mode_entry *)(rec->value.dptr + sizeof(*data));
1543 sharepath = (const char *)rec->value.dptr + sizeof(*data) +
1544 data->u.s.num_share_mode_entries*sizeof(*shares) +
1545 data->u.s.delete_token_size;
1546 fname = (const char *)rec->value.dptr + sizeof(*data) +
1547 data->u.s.num_share_mode_entries*sizeof(*shares) +
1548 data->u.s.delete_token_size +
1549 strlen(sharepath) + 1;
1551 for (i=0;i<data->u.s.num_share_mode_entries;i++) {
1552 state->fn(&shares[i], sharepath, fname,
1553 state->private_data);
1555 return 0;
1558 /*******************************************************************
1559 Call the specified function on each entry under management by the
1560 share mode system.
1561 ********************************************************************/
1563 int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *,
1564 const char *, void *),
1565 void *private_data)
1567 struct forall_state state;
1569 if (lock_db == NULL)
1570 return 0;
1572 state.fn = fn;
1573 state.private_data = private_data;
1575 return lock_db->traverse_read(lock_db, traverse_fn, (void *)&state);