2 Unix SMB/CIFS implementation.
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/>.
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
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.
39 #include "system/filesys.h"
40 #include "locking/proto.h"
41 #include "smbd/globals.h"
42 #include "dbwrap/dbwrap.h"
43 #include "dbwrap/dbwrap_open.h"
44 #include "../libcli/security/security.h"
50 #define DBGC_CLASS DBGC_LOCKING
52 #define NO_LOCKING_COUNT (-1)
54 /* the locking database handle */
55 static struct db_context
*lock_db
;
57 /****************************************************************************
59 ****************************************************************************/
61 const char *lock_type_name(enum brl_type lock_type
)
68 case PENDING_READ_LOCK
:
69 return "PENDING_READ";
70 case PENDING_WRITE_LOCK
:
71 return "PENDING_WRITE";
77 const char *lock_flav_name(enum brl_flavour lock_flav
)
79 return (lock_flav
== WINDOWS_LOCK
) ? "WINDOWS_LOCK" : "POSIX_LOCK";
82 /****************************************************************************
83 Utility function called to see if a file region is locked.
84 Called in the read/write codepath.
85 ****************************************************************************/
87 void init_strict_lock_struct(files_struct
*fsp
,
91 enum brl_type lock_type
,
92 struct lock_struct
*plock
)
94 SMB_ASSERT(lock_type
== READ_LOCK
|| lock_type
== WRITE_LOCK
);
96 plock
->context
.smblctx
= smblctx
;
97 plock
->context
.tid
= fsp
->conn
->cnum
;
98 plock
->context
.pid
= sconn_server_id(fsp
->conn
->sconn
);
101 plock
->fnum
= fsp
->fnum
;
102 plock
->lock_type
= lock_type
;
103 plock
->lock_flav
= lp_posix_cifsu_locktype(fsp
);
106 bool strict_lock_default(files_struct
*fsp
, struct lock_struct
*plock
)
108 int strict_locking
= lp_strict_locking(fsp
->conn
->params
);
111 if (plock
->size
== 0) {
115 if (!lp_locking(fsp
->conn
->params
) || !strict_locking
) {
119 if (strict_locking
== Auto
) {
120 if (EXCLUSIVE_OPLOCK_TYPE(fsp
->oplock_type
) && (plock
->lock_type
== READ_LOCK
|| plock
->lock_type
== WRITE_LOCK
)) {
121 DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp_str_dbg(fsp
)));
123 } else if ((fsp
->oplock_type
== LEVEL_II_OPLOCK
) &&
124 (plock
->lock_type
== READ_LOCK
)) {
125 DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp_str_dbg(fsp
)));
128 struct byte_range_lock
*br_lck
;
130 br_lck
= brl_get_locks_readonly(fsp
);
134 ret
= brl_locktest(br_lck
,
135 plock
->context
.smblctx
,
143 struct byte_range_lock
*br_lck
;
145 br_lck
= brl_get_locks_readonly(fsp
);
149 ret
= brl_locktest(br_lck
,
150 plock
->context
.smblctx
,
158 DEBUG(10,("strict_lock_default: flavour = %s brl start=%.0f "
159 "len=%.0f %s for fnum %d file %s\n",
160 lock_flav_name(plock
->lock_flav
),
161 (double)plock
->start
, (double)plock
->size
,
162 ret
? "unlocked" : "locked",
163 plock
->fnum
, fsp_str_dbg(fsp
)));
168 void strict_unlock_default(files_struct
*fsp
, struct lock_struct
*plock
)
172 /****************************************************************************
173 Find out if a lock could be granted - return who is blocking us if we can't.
174 ****************************************************************************/
176 NTSTATUS
query_lock(files_struct
*fsp
,
180 enum brl_type
*plock_type
,
181 enum brl_flavour lock_flav
)
183 struct byte_range_lock
*br_lck
= NULL
;
185 if (!fsp
->can_lock
) {
186 return fsp
->is_directory
? NT_STATUS_INVALID_DEVICE_REQUEST
: NT_STATUS_INVALID_HANDLE
;
189 if (!lp_locking(fsp
->conn
->params
)) {
193 br_lck
= brl_get_locks_readonly(fsp
);
195 return NT_STATUS_NO_MEMORY
;
198 return brl_lockquery(br_lck
,
200 sconn_server_id(fsp
->conn
->sconn
),
207 static void increment_current_lock_count(files_struct
*fsp
,
208 enum brl_flavour lock_flav
)
210 if (lock_flav
== WINDOWS_LOCK
&&
211 fsp
->current_lock_count
!= NO_LOCKING_COUNT
) {
212 /* blocking ie. pending, locks also count here,
213 * as this is an efficiency counter to avoid checking
214 * the lock db. on close. JRA. */
216 fsp
->current_lock_count
++;
218 /* Notice that this has had a POSIX lock request.
219 * We can't count locks after this so forget them.
221 fsp
->current_lock_count
= NO_LOCKING_COUNT
;
225 static void decrement_current_lock_count(files_struct
*fsp
,
226 enum brl_flavour lock_flav
)
228 if (lock_flav
== WINDOWS_LOCK
&&
229 fsp
->current_lock_count
!= NO_LOCKING_COUNT
) {
230 SMB_ASSERT(fsp
->current_lock_count
> 0);
231 fsp
->current_lock_count
--;
235 /****************************************************************************
236 Utility function called by locking requests.
237 ****************************************************************************/
239 struct byte_range_lock
*do_lock(struct messaging_context
*msg_ctx
,
244 enum brl_type lock_type
,
245 enum brl_flavour lock_flav
,
249 struct blocking_lock_record
*blr
)
251 struct byte_range_lock
*br_lck
= NULL
;
253 /* silently return ok on print files as we don't do locking there */
254 if (fsp
->print_file
) {
255 *perr
= NT_STATUS_OK
;
259 if (!fsp
->can_lock
) {
260 *perr
= fsp
->is_directory
? NT_STATUS_INVALID_DEVICE_REQUEST
: NT_STATUS_INVALID_HANDLE
;
264 if (!lp_locking(fsp
->conn
->params
)) {
265 *perr
= NT_STATUS_OK
;
269 /* NOTE! 0 byte long ranges ARE allowed and should be stored */
271 DEBUG(10,("do_lock: lock flavour %s lock type %s start=%.0f len=%.0f "
272 "blocking_lock=%s requested for fnum %d file %s\n",
273 lock_flav_name(lock_flav
), lock_type_name(lock_type
),
274 (double)offset
, (double)count
, blocking_lock
? "true" :
275 "false", fsp
->fnum
, fsp_str_dbg(fsp
)));
277 br_lck
= brl_get_locks(talloc_tos(), fsp
);
279 *perr
= NT_STATUS_NO_MEMORY
;
283 *perr
= brl_lock(msg_ctx
,
286 sconn_server_id(fsp
->conn
->sconn
),
295 DEBUG(10, ("do_lock: returning status=%s\n", nt_errstr(*perr
)));
297 increment_current_lock_count(fsp
, lock_flav
);
301 /****************************************************************************
302 Utility function called by unlocking requests.
303 ****************************************************************************/
305 NTSTATUS
do_unlock(struct messaging_context
*msg_ctx
,
310 enum brl_flavour lock_flav
)
313 struct byte_range_lock
*br_lck
= NULL
;
315 if (!fsp
->can_lock
) {
316 return fsp
->is_directory
? NT_STATUS_INVALID_DEVICE_REQUEST
: NT_STATUS_INVALID_HANDLE
;
319 if (!lp_locking(fsp
->conn
->params
)) {
323 DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for fnum %d file %s\n",
324 (double)offset
, (double)count
, fsp
->fnum
,
327 br_lck
= brl_get_locks(talloc_tos(), fsp
);
329 return NT_STATUS_NO_MEMORY
;
332 ok
= brl_unlock(msg_ctx
,
335 sconn_server_id(fsp
->conn
->sconn
),
343 DEBUG(10,("do_unlock: returning ERRlock.\n" ));
344 return NT_STATUS_RANGE_NOT_LOCKED
;
347 decrement_current_lock_count(fsp
, lock_flav
);
351 /****************************************************************************
352 Cancel any pending blocked locks.
353 ****************************************************************************/
355 NTSTATUS
do_lock_cancel(files_struct
*fsp
,
359 enum brl_flavour lock_flav
,
360 struct blocking_lock_record
*blr
)
363 struct byte_range_lock
*br_lck
= NULL
;
365 if (!fsp
->can_lock
) {
366 return fsp
->is_directory
?
367 NT_STATUS_INVALID_DEVICE_REQUEST
: NT_STATUS_INVALID_HANDLE
;
370 if (!lp_locking(fsp
->conn
->params
)) {
371 return NT_STATUS_DOS(ERRDOS
, ERRcancelviolation
);
374 DEBUG(10,("do_lock_cancel: cancel start=%.0f len=%.0f requested for fnum %d file %s\n",
375 (double)offset
, (double)count
, fsp
->fnum
,
378 br_lck
= brl_get_locks(talloc_tos(), fsp
);
380 return NT_STATUS_NO_MEMORY
;
383 ok
= brl_lock_cancel(br_lck
,
385 sconn_server_id(fsp
->conn
->sconn
),
394 DEBUG(10,("do_lock_cancel: returning ERRcancelviolation.\n" ));
395 return NT_STATUS_DOS(ERRDOS
, ERRcancelviolation
);
398 decrement_current_lock_count(fsp
, lock_flav
);
402 /****************************************************************************
403 Remove any locks on this fd. Called from file_close().
404 ****************************************************************************/
406 void locking_close_file(struct messaging_context
*msg_ctx
,
408 enum file_close_type close_type
)
410 struct byte_range_lock
*br_lck
;
412 if (!lp_locking(fsp
->conn
->params
)) {
416 /* If we have not outstanding locks or pending
417 * locks then we don't need to look in the lock db.
420 if (fsp
->current_lock_count
== 0) {
424 br_lck
= brl_get_locks(talloc_tos(),fsp
);
427 cancel_pending_lock_requests_by_fid(fsp
, br_lck
, close_type
);
428 brl_close_fnum(msg_ctx
, br_lck
);
433 /****************************************************************************
434 Initialise the locking functions.
435 ****************************************************************************/
437 static bool locking_init_internal(bool read_only
)
444 lock_db
= db_open(NULL
, lock_path("locking.tdb"),
445 lp_open_files_db_hash_size(),
446 TDB_DEFAULT
|TDB_VOLATILE
|TDB_CLEAR_IF_FIRST
|TDB_INCOMPATIBLE_HASH
,
447 read_only
?O_RDONLY
:O_RDWR
|O_CREAT
, 0644);
450 DEBUG(0,("ERROR: Failed to initialise locking database\n"));
454 if (!posix_locking_init(read_only
))
460 bool locking_init(void)
462 return locking_init_internal(false);
465 bool locking_init_readonly(void)
467 return locking_init_internal(true);
470 /*******************************************************************
471 Deinitialize the share_mode management.
472 ******************************************************************/
474 bool locking_end(void)
477 TALLOC_FREE(lock_db
);
481 /*******************************************************************
482 Form a static locking key for a dev/inode pair.
483 ******************************************************************/
485 static TDB_DATA
locking_key(const struct file_id
*id
, struct file_id
*tmp
)
488 return make_tdb_data((const uint8_t *)tmp
, sizeof(*tmp
));
491 /*******************************************************************
492 Print out a share mode.
493 ********************************************************************/
495 char *share_mode_str(TALLOC_CTX
*ctx
, int num
, const struct share_mode_entry
*e
)
497 return talloc_asprintf(ctx
, "share_mode_entry[%d]: %s "
498 "pid = %s, share_access = 0x%x, private_options = 0x%x, "
499 "access_mask = 0x%x, mid = 0x%llx, type= 0x%x, gen_id = %lu, "
500 "uid = %u, flags = %u, file_id %s, name_hash = 0x%x",
502 e
->op_type
== UNUSED_SHARE_MODE_ENTRY
? "UNUSED" : "",
503 procid_str_static(&e
->pid
),
504 e
->share_access
, e
->private_options
,
505 e
->access_mask
, (unsigned long long)e
->op_mid
,
506 e
->op_type
, e
->share_file_id
,
507 (unsigned int)e
->uid
, (unsigned int)e
->flags
,
508 file_id_string_tos(&e
->id
),
509 (unsigned int)e
->name_hash
);
512 /*******************************************************************
513 Print out a share mode table.
514 ********************************************************************/
516 static void print_share_mode_table(struct locking_data
*data
)
518 int num_share_modes
= data
->u
.s
.num_share_mode_entries
;
519 struct share_mode_entry
*shares
=
520 (struct share_mode_entry
*)(data
+ 1);
523 for (i
= 0; i
< num_share_modes
; i
++) {
524 struct share_mode_entry entry
;
528 * We need to memcpy the entry here due to alignment
529 * restrictions that are not met when directly accessing
533 memcpy(&entry
, &shares
[i
], sizeof(struct share_mode_entry
));
534 str
= share_mode_str(talloc_tos(), i
, &entry
);
536 DEBUG(10,("print_share_mode_table: %s\n", str
? str
: ""));
541 static int parse_delete_tokens_list(struct share_mode_lock
*lck
,
542 struct locking_data
*pdata
,
545 uint8_t *p
= dbuf
.dptr
+ sizeof(struct locking_data
) +
546 (lck
->num_share_modes
*
547 sizeof(struct share_mode_entry
));
548 uint8_t *end_ptr
= dbuf
.dptr
+ (dbuf
.dsize
- 2);
549 int delete_tokens_size
= 0;
552 lck
->delete_tokens
= NULL
;
554 for (i
= 0; i
< pdata
->u
.s
.num_delete_token_entries
; i
++) {
556 struct delete_token_list
*pdtl
;
558 if (end_ptr
- p
< (sizeof(uint32_t) + sizeof(uint32_t) +
559 sizeof(uid_t
) + sizeof(gid_t
))) {
560 DEBUG(0,("parse_delete_tokens_list: "
561 "corrupt token list (%u)",
562 (unsigned int)(end_ptr
- p
)));
563 smb_panic("corrupt token list");
567 memcpy(&token_len
, p
, sizeof(token_len
));
568 delete_tokens_size
+= token_len
;
570 if (p
+ token_len
> end_ptr
|| token_len
< sizeof(token_len
) +
571 sizeof(pdtl
->name_hash
) +
574 DEBUG(0,("parse_delete_tokens_list: "
575 "invalid token length (%u)\n",
576 (unsigned int)token_len
));
577 smb_panic("invalid token length");
581 p
+= sizeof(token_len
);
583 pdtl
= talloc_zero(lck
, struct delete_token_list
);
585 DEBUG(0,("parse_delete_tokens_list: talloc failed"));
588 /* Copy out the name_hash. */
589 memcpy(&pdtl
->name_hash
, p
, sizeof(pdtl
->name_hash
));
590 p
+= sizeof(pdtl
->name_hash
);
592 pdtl
->delete_token
= talloc_zero(pdtl
, struct security_unix_token
);
593 if (pdtl
->delete_token
== NULL
) {
594 DEBUG(0,("parse_delete_tokens_list: talloc failed"));
598 /* Copy out the uid and gid. */
599 memcpy(&pdtl
->delete_token
->uid
, p
, sizeof(uid_t
));
601 memcpy(&pdtl
->delete_token
->gid
, p
, sizeof(gid_t
));
604 token_len
-= (sizeof(token_len
) + sizeof(pdtl
->name_hash
) +
605 sizeof(uid_t
) + sizeof(gid_t
));
607 /* Any supplementary groups ? */
611 if (token_len
% sizeof(gid_t
) != 0) {
612 DEBUG(0,("parse_delete_tokens_list: "
613 "corrupt group list (%u)",
614 (unsigned int)(token_len
% sizeof(gid_t
)) ));
615 smb_panic("corrupt group list");
619 pdtl
->delete_token
->ngroups
= token_len
/ sizeof(gid_t
);
620 pdtl
->delete_token
->groups
= talloc_array(pdtl
->delete_token
, gid_t
,
621 pdtl
->delete_token
->ngroups
);
622 if (pdtl
->delete_token
->groups
== NULL
) {
623 DEBUG(0,("parse_delete_tokens_list: talloc failed"));
627 for (j
= 0; j
< pdtl
->delete_token
->ngroups
; j
++) {
628 memcpy(&pdtl
->delete_token
->groups
[j
], p
, sizeof(gid_t
));
632 /* Add to the list. */
633 DLIST_ADD(lck
->delete_tokens
, pdtl
);
636 return delete_tokens_size
;
639 /*******************************************************************
640 Get all share mode entries for a dev/inode pair.
641 ********************************************************************/
643 static bool parse_share_modes(const TDB_DATA dbuf
, struct share_mode_lock
*lck
)
645 struct locking_data data
;
646 int delete_tokens_size
;
649 if (dbuf
.dsize
< sizeof(struct locking_data
)) {
650 smb_panic("parse_share_modes: buffer too short");
653 memcpy(&data
, dbuf
.dptr
, sizeof(data
));
655 lck
->old_write_time
= data
.u
.s
.old_write_time
;
656 lck
->changed_write_time
= data
.u
.s
.changed_write_time
;
657 lck
->num_share_modes
= data
.u
.s
.num_share_mode_entries
;
659 DEBUG(10, ("parse_share_modes: owrt: %s, "
660 "cwrt: %s, ntok: %u, num_share_modes: %d\n",
661 timestring(talloc_tos(),
662 convert_timespec_to_time_t(lck
->old_write_time
)),
663 timestring(talloc_tos(),
664 convert_timespec_to_time_t(
665 lck
->changed_write_time
)),
666 (unsigned int)data
.u
.s
.num_delete_token_entries
,
667 lck
->num_share_modes
));
669 if ((lck
->num_share_modes
< 0) || (lck
->num_share_modes
> 1000000)) {
670 DEBUG(0, ("invalid number of share modes: %d\n",
671 lck
->num_share_modes
));
672 smb_panic("parse_share_modes: invalid number of share modes");
675 lck
->share_modes
= NULL
;
677 if (lck
->num_share_modes
!= 0) {
679 if (dbuf
.dsize
< (sizeof(struct locking_data
) +
680 (lck
->num_share_modes
*
681 sizeof(struct share_mode_entry
)))) {
682 smb_panic("parse_share_modes: buffer too short");
685 lck
->share_modes
= (struct share_mode_entry
*)
687 dbuf
.dptr
+sizeof(struct locking_data
),
688 lck
->num_share_modes
*
689 sizeof(struct share_mode_entry
));
691 if (lck
->share_modes
== NULL
) {
692 smb_panic("parse_share_modes: talloc failed");
696 /* Get any delete tokens. */
697 delete_tokens_size
= parse_delete_tokens_list(lck
, &data
, dbuf
);
698 if (delete_tokens_size
< 0) {
699 smb_panic("parse_share_modes: parse_delete_tokens_list failed");
702 /* Save off the associated service path and filename. */
703 lck
->servicepath
= (const char *)dbuf
.dptr
+ sizeof(struct locking_data
) +
704 (lck
->num_share_modes
* sizeof(struct share_mode_entry
)) +
707 lck
->base_name
= (const char *)dbuf
.dptr
+ sizeof(struct locking_data
) +
708 (lck
->num_share_modes
* sizeof(struct share_mode_entry
)) +
710 strlen(lck
->servicepath
) + 1;
712 lck
->stream_name
= (const char *)dbuf
.dptr
+ sizeof(struct locking_data
) +
713 (lck
->num_share_modes
* sizeof(struct share_mode_entry
)) +
715 strlen(lck
->servicepath
) + 1 +
716 strlen(lck
->base_name
) + 1;
719 * Ensure that each entry has a real process attached.
722 for (i
= 0; i
< lck
->num_share_modes
; i
++) {
723 struct share_mode_entry
*entry_p
= &lck
->share_modes
[i
];
725 if (DEBUGLEVEL
>= 10) {
726 str
= share_mode_str(NULL
, i
, entry_p
);
728 DEBUG(10,("parse_share_modes: %s\n",
730 if (!serverid_exists(&entry_p
->pid
)) {
731 DEBUG(10,("parse_share_modes: deleted %s\n",
733 entry_p
->op_type
= UNUSED_SHARE_MODE_ENTRY
;
734 lck
->modified
= True
;
742 static TDB_DATA
unparse_share_modes(const struct share_mode_lock
*lck
)
747 struct locking_data
*data
;
749 ssize_t sp_len
, bn_len
, sn_len
;
750 uint32_t delete_tokens_size
= 0;
751 struct delete_token_list
*pdtl
= NULL
;
752 uint32_t num_delete_token_entries
= 0;
757 for (i
=0; i
<lck
->num_share_modes
; i
++) {
758 if (!is_unused_share_mode_entry(&lck
->share_modes
[i
])) {
763 if (num_valid
== 0) {
767 sp_len
= strlen(lck
->servicepath
);
768 bn_len
= strlen(lck
->base_name
);
769 sn_len
= lck
->stream_name
!= NULL
? strlen(lck
->stream_name
) : 0;
771 for (pdtl
= lck
->delete_tokens
; pdtl
; pdtl
= pdtl
->next
) {
772 num_delete_token_entries
++;
773 delete_tokens_size
+= (sizeof(uint32_t) +
777 pdtl
->delete_token
->ngroups
*sizeof(gid_t
));
780 result
.dsize
= sizeof(*data
) +
781 lck
->num_share_modes
* sizeof(struct share_mode_entry
) +
786 result
.dptr
= talloc_array(lck
, uint8
, result
.dsize
);
788 if (result
.dptr
== NULL
) {
789 smb_panic("talloc failed");
792 data
= (struct locking_data
*)result
.dptr
;
794 data
->u
.s
.num_share_mode_entries
= lck
->num_share_modes
;
795 data
->u
.s
.old_write_time
= lck
->old_write_time
;
796 data
->u
.s
.changed_write_time
= lck
->changed_write_time
;
797 data
->u
.s
.num_delete_token_entries
= num_delete_token_entries
;
799 DEBUG(10,("unparse_share_modes: owrt: %s cwrt: %s, ntok: %u, "
801 timestring(talloc_tos(),
802 convert_timespec_to_time_t(lck
->old_write_time
)),
803 timestring(talloc_tos(),
804 convert_timespec_to_time_t(
805 lck
->changed_write_time
)),
806 (unsigned int)data
->u
.s
.num_delete_token_entries
,
807 data
->u
.s
.num_share_mode_entries
));
809 memcpy(result
.dptr
+ sizeof(*data
), lck
->share_modes
,
810 sizeof(struct share_mode_entry
)*lck
->num_share_modes
);
811 offset
= sizeof(*data
) +
812 sizeof(struct share_mode_entry
)*lck
->num_share_modes
;
814 /* Store any delete on close tokens. */
815 for (pdtl
= lck
->delete_tokens
; pdtl
; pdtl
= pdtl
->next
) {
816 struct security_unix_token
*pdt
= pdtl
->delete_token
;
817 uint32_t token_size
= sizeof(uint32_t) +
821 (pdt
->ngroups
* sizeof(gid_t
));
822 uint8_t *p
= result
.dptr
+ offset
;
824 memcpy(p
, &token_size
, sizeof(uint32_t));
825 p
+= sizeof(uint32_t);
827 memcpy(p
, &pdtl
->name_hash
, sizeof(uint32_t));
828 p
+= sizeof(uint32_t);
830 memcpy(p
, &pdt
->uid
, sizeof(uid_t
));
833 memcpy(p
, &pdt
->gid
, sizeof(gid_t
));
836 for (i
= 0; i
< pdt
->ngroups
; i
++) {
837 memcpy(p
, &pdt
->groups
[i
], sizeof(gid_t
));
840 offset
+= token_size
;
843 strlcpy((char *)result
.dptr
+ offset
,
844 lck
->servicepath
? lck
->servicepath
: "",
845 result
.dsize
- offset
);
846 offset
+= sp_len
+ 1;
847 strlcpy((char *)result
.dptr
+ offset
,
848 lck
->base_name
? lck
->base_name
: "",
849 result
.dsize
- offset
);
850 offset
+= bn_len
+ 1;
851 strlcpy((char *)result
.dptr
+ offset
,
852 lck
->stream_name
? lck
->stream_name
: "",
853 result
.dsize
- offset
);
855 if (DEBUGLEVEL
>= 10) {
856 print_share_mode_table(data
);
862 static int share_mode_lock_destructor(struct share_mode_lock
*lck
)
867 if (!lck
->modified
) {
871 data
= unparse_share_modes(lck
);
873 if (data
.dptr
== NULL
) {
875 /* There has been an entry before, delete it */
877 status
= lck
->record
->delete_rec(lck
->record
);
878 if (!NT_STATUS_IS_OK(status
)) {
881 DEBUG(0, ("delete_rec returned %s\n",
884 if (asprintf(&errmsg
, "could not delete share "
886 nt_errstr(status
)) == -1) {
887 smb_panic("could not delete share"
896 status
= lck
->record
->store(lck
->record
, data
, TDB_REPLACE
);
897 if (!NT_STATUS_IS_OK(status
)) {
900 DEBUG(0, ("store returned %s\n", nt_errstr(status
)));
902 if (asprintf(&errmsg
, "could not store share mode entry: %s",
903 nt_errstr(status
)) == -1) {
904 smb_panic("could not store share mode entry");
914 static bool fill_share_mode_lock(struct share_mode_lock
*lck
,
916 const char *servicepath
,
917 const struct smb_filename
*smb_fname
,
918 TDB_DATA share_mode_data
,
919 const struct timespec
*old_write_time
)
921 /* Ensure we set every field here as the destructor must be
922 valid even if parse_share_modes fails. */
924 lck
->servicepath
= NULL
;
925 lck
->base_name
= NULL
;
926 lck
->stream_name
= NULL
;
928 lck
->num_share_modes
= 0;
929 lck
->share_modes
= NULL
;
930 lck
->delete_tokens
= NULL
;
931 ZERO_STRUCT(lck
->old_write_time
);
932 ZERO_STRUCT(lck
->changed_write_time
);
934 lck
->modified
= False
;
936 lck
->fresh
= (share_mode_data
.dptr
== NULL
);
940 if (smb_fname
== NULL
|| servicepath
== NULL
941 || old_write_time
== NULL
) {
945 has_stream
= smb_fname
->stream_name
!= NULL
;
947 lck
->base_name
= talloc_strdup(lck
, smb_fname
->base_name
);
948 lck
->stream_name
= talloc_strdup(lck
, smb_fname
->stream_name
);
949 lck
->servicepath
= talloc_strdup(lck
, servicepath
);
950 if (lck
->base_name
== NULL
||
951 (has_stream
&& lck
->stream_name
== NULL
) ||
952 lck
->servicepath
== NULL
) {
953 DEBUG(0, ("talloc failed\n"));
956 lck
->old_write_time
= *old_write_time
;
958 if (!parse_share_modes(share_mode_data
, lck
)) {
959 DEBUG(0, ("Could not parse share modes\n"));
967 struct share_mode_lock
*get_share_mode_lock(TALLOC_CTX
*mem_ctx
,
968 const struct file_id id
,
969 const char *servicepath
,
970 const struct smb_filename
*smb_fname
,
971 const struct timespec
*old_write_time
)
973 struct share_mode_lock
*lck
;
975 TDB_DATA key
= locking_key(&id
, &tmp
);
977 if (!(lck
= talloc(mem_ctx
, struct share_mode_lock
))) {
978 DEBUG(0, ("talloc failed\n"));
982 if (!(lck
->record
= lock_db
->fetch_locked(lock_db
, lck
, key
))) {
983 DEBUG(3, ("Could not lock share entry\n"));
988 if (!fill_share_mode_lock(lck
, id
, servicepath
, smb_fname
,
989 lck
->record
->value
, old_write_time
)) {
990 DEBUG(3, ("fill_share_mode_lock failed\n"));
995 talloc_set_destructor(lck
, share_mode_lock_destructor
);
1000 struct share_mode_lock
*fetch_share_mode_unlocked(TALLOC_CTX
*mem_ctx
,
1001 const struct file_id id
)
1003 struct share_mode_lock
*lck
;
1005 TDB_DATA key
= locking_key(&id
, &tmp
);
1008 if (!(lck
= talloc(mem_ctx
, struct share_mode_lock
))) {
1009 DEBUG(0, ("talloc failed\n"));
1013 if (lock_db
->fetch(lock_db
, lck
, key
, &data
) != 0) {
1014 DEBUG(3, ("Could not fetch share entry\n"));
1019 if (!fill_share_mode_lock(lck
, id
, NULL
, NULL
, data
, NULL
)) {
1020 DEBUG(10, ("fetch_share_mode_unlocked: no share_mode record "
1021 "around (file not open)\n"));
1029 /*******************************************************************
1030 Sets the service name and filename for rename.
1031 At this point we emit "file renamed" messages to all
1032 process id's that have this file open.
1033 Based on an initial code idea from SATOH Fumiyasu <fumiya@samba.gr.jp>
1034 ********************************************************************/
1036 bool rename_share_filename(struct messaging_context
*msg_ctx
,
1037 struct share_mode_lock
*lck
,
1038 const char *servicepath
,
1039 uint32_t orig_name_hash
,
1040 uint32_t new_name_hash
,
1041 const struct smb_filename
*smb_fname_dst
)
1049 bool strip_two_chars
= false;
1050 bool has_stream
= smb_fname_dst
->stream_name
!= NULL
;
1052 DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n",
1053 servicepath
, smb_fname_dst
->base_name
));
1056 * rename_internal_fsp() and rename_internals() add './' to
1057 * head of newname if newname does not contain a '/'.
1059 if (smb_fname_dst
->base_name
[0] &&
1060 smb_fname_dst
->base_name
[1] &&
1061 smb_fname_dst
->base_name
[0] == '.' &&
1062 smb_fname_dst
->base_name
[1] == '/') {
1063 strip_two_chars
= true;
1066 lck
->servicepath
= talloc_strdup(lck
, servicepath
);
1067 lck
->base_name
= talloc_strdup(lck
, smb_fname_dst
->base_name
+
1068 (strip_two_chars
? 2 : 0));
1069 lck
->stream_name
= talloc_strdup(lck
, smb_fname_dst
->stream_name
);
1070 if (lck
->base_name
== NULL
||
1071 (has_stream
&& lck
->stream_name
== NULL
) ||
1072 lck
->servicepath
== NULL
) {
1073 DEBUG(0, ("rename_share_filename: talloc failed\n"));
1076 lck
->modified
= True
;
1078 sp_len
= strlen(lck
->servicepath
);
1079 bn_len
= strlen(lck
->base_name
);
1080 sn_len
= has_stream
? strlen(lck
->stream_name
) : 0;
1082 msg_len
= MSG_FILE_RENAMED_MIN_SIZE
+ sp_len
+ 1 + bn_len
+ 1 +
1085 /* Set up the name changed message. */
1086 frm
= talloc_array(lck
, char, msg_len
);
1091 push_file_id_24(frm
, &lck
->id
);
1093 DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len
));
1096 lck
->servicepath
? lck
->servicepath
: "",
1098 strlcpy(&frm
[24 + sp_len
+ 1],
1099 lck
->base_name
? lck
->base_name
: "",
1101 strlcpy(&frm
[24 + sp_len
+ 1 + bn_len
+ 1],
1102 lck
->stream_name
? lck
->stream_name
: "",
1105 /* Send the messages. */
1106 for (i
=0; i
<lck
->num_share_modes
; i
++) {
1107 struct share_mode_entry
*se
= &lck
->share_modes
[i
];
1108 if (!is_valid_share_mode_entry(se
)) {
1112 /* If this is a hardlink to the inode
1113 with a different name, skip this. */
1114 if (se
->name_hash
!= orig_name_hash
) {
1118 se
->name_hash
= new_name_hash
;
1120 /* But not to ourselves... */
1121 if (procid_is_me(&se
->pid
)) {
1125 DEBUG(10,("rename_share_filename: sending rename message to "
1126 "pid %s file_id %s sharepath %s base_name %s "
1128 procid_str_static(&se
->pid
),
1129 file_id_string_tos(&lck
->id
),
1130 lck
->servicepath
, lck
->base_name
,
1131 has_stream
? lck
->stream_name
: ""));
1133 messaging_send_buf(msg_ctx
, se
->pid
, MSG_SMB_FILE_RENAME
,
1134 (uint8
*)frm
, msg_len
);
1140 void get_file_infos(struct file_id id
,
1142 bool *delete_on_close
,
1143 struct timespec
*write_time
)
1145 struct share_mode_lock
*lck
;
1147 if (delete_on_close
) {
1148 *delete_on_close
= false;
1152 ZERO_STRUCTP(write_time
);
1155 if (!(lck
= fetch_share_mode_unlocked(talloc_tos(), id
))) {
1159 if (delete_on_close
) {
1160 *delete_on_close
= is_delete_on_close_set(lck
, name_hash
);
1166 wt
= lck
->changed_write_time
;
1167 if (null_timespec(wt
)) {
1168 wt
= lck
->old_write_time
;
1177 bool is_valid_share_mode_entry(const struct share_mode_entry
*e
)
1181 if (e
->op_type
== UNUSED_SHARE_MODE_ENTRY
) {
1182 /* cope with dead entries from the process not
1183 existing. These should not be considered valid,
1184 otherwise we end up doing zero timeout sharing
1189 num_props
+= ((e
->op_type
== NO_OPLOCK
) ? 1 : 0);
1190 num_props
+= (EXCLUSIVE_OPLOCK_TYPE(e
->op_type
) ? 1 : 0);
1191 num_props
+= (LEVEL_II_OPLOCK_TYPE(e
->op_type
) ? 1 : 0);
1193 SMB_ASSERT(num_props
<= 1);
1194 return (num_props
!= 0);
1197 bool is_deferred_open_entry(const struct share_mode_entry
*e
)
1199 return (e
->op_type
== DEFERRED_OPEN_ENTRY
);
1202 bool is_unused_share_mode_entry(const struct share_mode_entry
*e
)
1204 return (e
->op_type
== UNUSED_SHARE_MODE_ENTRY
);
1207 /*******************************************************************
1208 Fill a share mode entry.
1209 ********************************************************************/
1211 static void fill_share_mode_entry(struct share_mode_entry
*e
,
1213 uid_t uid
, uint64_t mid
, uint16 op_type
)
1216 e
->pid
= sconn_server_id(fsp
->conn
->sconn
);
1217 e
->share_access
= fsp
->share_access
;
1218 e
->private_options
= fsp
->fh
->private_options
;
1219 e
->access_mask
= fsp
->access_mask
;
1221 e
->op_type
= op_type
;
1222 e
->time
.tv_sec
= fsp
->open_time
.tv_sec
;
1223 e
->time
.tv_usec
= fsp
->open_time
.tv_usec
;
1224 e
->id
= fsp
->file_id
;
1225 e
->share_file_id
= fsp
->fh
->gen_id
;
1226 e
->uid
= (uint32
)uid
;
1227 e
->flags
= fsp
->posix_open
? SHARE_MODE_FLAG_POSIX_OPEN
: 0;
1228 e
->name_hash
= fsp
->name_hash
;
1231 static void fill_deferred_open_entry(struct share_mode_entry
*e
,
1232 const struct timeval request_time
,
1234 struct server_id pid
,
1240 e
->op_type
= DEFERRED_OPEN_ENTRY
;
1241 e
->time
.tv_sec
= request_time
.tv_sec
;
1242 e
->time
.tv_usec
= request_time
.tv_usec
;
1244 e
->uid
= (uint32
)-1;
1248 static void add_share_mode_entry(struct share_mode_lock
*lck
,
1249 const struct share_mode_entry
*entry
)
1253 for (i
=0; i
<lck
->num_share_modes
; i
++) {
1254 struct share_mode_entry
*e
= &lck
->share_modes
[i
];
1255 if (is_unused_share_mode_entry(e
)) {
1261 if (i
== lck
->num_share_modes
) {
1262 /* No unused entry found */
1263 ADD_TO_ARRAY(lck
, struct share_mode_entry
, *entry
,
1264 &lck
->share_modes
, &lck
->num_share_modes
);
1266 lck
->modified
= True
;
1269 void set_share_mode(struct share_mode_lock
*lck
, files_struct
*fsp
,
1270 uid_t uid
, uint64_t mid
, uint16 op_type
)
1272 struct share_mode_entry entry
;
1273 fill_share_mode_entry(&entry
, fsp
, uid
, mid
, op_type
);
1274 add_share_mode_entry(lck
, &entry
);
1277 void add_deferred_open(struct share_mode_lock
*lck
, uint64_t mid
,
1278 struct timeval request_time
,
1279 struct server_id pid
, struct file_id id
)
1281 struct share_mode_entry entry
;
1282 fill_deferred_open_entry(&entry
, request_time
, id
, pid
, mid
);
1283 add_share_mode_entry(lck
, &entry
);
1286 /*******************************************************************
1287 Check if two share mode entries are identical, ignoring oplock
1288 and mid info and desired_access. (Removed paranoia test - it's
1289 not automatically a logic error if they are identical. JRA.)
1290 ********************************************************************/
1292 static bool share_modes_identical(struct share_mode_entry
*e1
,
1293 struct share_mode_entry
*e2
)
1295 /* We used to check for e1->share_access == e2->share_access here
1296 as well as the other fields but 2 different DOS or FCB opens
1297 sharing the same share mode entry may validly differ in
1298 fsp->share_access field. */
1300 return (procid_equal(&e1
->pid
, &e2
->pid
) &&
1301 file_id_equal(&e1
->id
, &e2
->id
) &&
1302 e1
->share_file_id
== e2
->share_file_id
);
1305 static bool deferred_open_identical(struct share_mode_entry
*e1
,
1306 struct share_mode_entry
*e2
)
1308 return (procid_equal(&e1
->pid
, &e2
->pid
) &&
1309 (e1
->op_mid
== e2
->op_mid
) &&
1310 file_id_equal(&e1
->id
, &e2
->id
));
1313 static struct share_mode_entry
*find_share_mode_entry(struct share_mode_lock
*lck
,
1314 struct share_mode_entry
*entry
)
1318 for (i
=0; i
<lck
->num_share_modes
; i
++) {
1319 struct share_mode_entry
*e
= &lck
->share_modes
[i
];
1320 if (is_valid_share_mode_entry(entry
) &&
1321 is_valid_share_mode_entry(e
) &&
1322 share_modes_identical(e
, entry
)) {
1325 if (is_deferred_open_entry(entry
) &&
1326 is_deferred_open_entry(e
) &&
1327 deferred_open_identical(e
, entry
)) {
1334 /*******************************************************************
1335 Del the share mode of a file for this process. Return the number of
1337 ********************************************************************/
1339 bool del_share_mode(struct share_mode_lock
*lck
, files_struct
*fsp
)
1341 struct share_mode_entry entry
, *e
;
1343 /* Don't care about the pid owner being correct here - just a search. */
1344 fill_share_mode_entry(&entry
, fsp
, (uid_t
)-1, 0, NO_OPLOCK
);
1346 e
= find_share_mode_entry(lck
, &entry
);
1351 e
->op_type
= UNUSED_SHARE_MODE_ENTRY
;
1352 lck
->modified
= True
;
1356 void del_deferred_open_entry(struct share_mode_lock
*lck
, uint64_t mid
,
1357 struct server_id pid
)
1359 struct share_mode_entry entry
, *e
;
1361 fill_deferred_open_entry(&entry
, timeval_zero(),
1364 e
= find_share_mode_entry(lck
, &entry
);
1369 e
->op_type
= UNUSED_SHARE_MODE_ENTRY
;
1370 lck
->modified
= True
;
1373 /*******************************************************************
1374 Remove an oplock mid and mode entry from a share mode.
1375 ********************************************************************/
1377 bool remove_share_oplock(struct share_mode_lock
*lck
, files_struct
*fsp
)
1379 struct share_mode_entry entry
, *e
;
1381 /* Don't care about the pid owner being correct here - just a search. */
1382 fill_share_mode_entry(&entry
, fsp
, (uid_t
)-1, 0, NO_OPLOCK
);
1384 e
= find_share_mode_entry(lck
, &entry
);
1389 if (EXCLUSIVE_OPLOCK_TYPE(e
->op_type
)) {
1391 * Going from exclusive or batch,
1392 * we always go through FAKE_LEVEL_II
1395 if (!EXCLUSIVE_OPLOCK_TYPE(fsp
->oplock_type
)) {
1396 smb_panic("remove_share_oplock: logic error");
1398 e
->op_type
= FAKE_LEVEL_II_OPLOCK
;
1400 e
->op_type
= NO_OPLOCK
;
1402 lck
->modified
= True
;
1406 /*******************************************************************
1407 Downgrade a oplock type from exclusive to level II.
1408 ********************************************************************/
1410 bool downgrade_share_oplock(struct share_mode_lock
*lck
, files_struct
*fsp
)
1412 struct share_mode_entry entry
, *e
;
1414 /* Don't care about the pid owner being correct here - just a search. */
1415 fill_share_mode_entry(&entry
, fsp
, (uid_t
)-1, 0, NO_OPLOCK
);
1417 e
= find_share_mode_entry(lck
, &entry
);
1422 e
->op_type
= LEVEL_II_OPLOCK
;
1423 lck
->modified
= True
;
1427 /****************************************************************************
1428 Check if setting delete on close is allowed on this fsp.
1429 ****************************************************************************/
1431 NTSTATUS
can_set_delete_on_close(files_struct
*fsp
, uint32 dosmode
)
1434 * Only allow delete on close for writable files.
1437 if ((dosmode
& FILE_ATTRIBUTE_READONLY
) &&
1438 !lp_delete_readonly(SNUM(fsp
->conn
))) {
1439 DEBUG(10,("can_set_delete_on_close: file %s delete on close "
1440 "flag set but file attribute is readonly.\n",
1442 return NT_STATUS_CANNOT_DELETE
;
1446 * Only allow delete on close for writable shares.
1449 if (!CAN_WRITE(fsp
->conn
)) {
1450 DEBUG(10,("can_set_delete_on_close: file %s delete on "
1451 "close flag set but write access denied on share.\n",
1453 return NT_STATUS_ACCESS_DENIED
;
1457 * Only allow delete on close for files/directories opened with delete
1461 if (!(fsp
->access_mask
& DELETE_ACCESS
)) {
1462 DEBUG(10,("can_set_delete_on_close: file %s delete on "
1463 "close flag set but delete access denied.\n",
1465 return NT_STATUS_ACCESS_DENIED
;
1468 /* Don't allow delete on close for non-empty directories. */
1469 if (fsp
->is_directory
) {
1470 SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp
->fsp_name
));
1471 return can_delete_directory(fsp
->conn
,
1472 fsp
->fsp_name
->base_name
);
1475 return NT_STATUS_OK
;
1478 /*************************************************************************
1479 Return a talloced copy of a struct security_unix_token. NULL on fail.
1480 (Should this be in locking.c.... ?).
1481 *************************************************************************/
1483 static struct security_unix_token
*copy_unix_token(TALLOC_CTX
*ctx
, const struct security_unix_token
*tok
)
1485 struct security_unix_token
*cpy
;
1487 cpy
= talloc(ctx
, struct security_unix_token
);
1492 cpy
->uid
= tok
->uid
;
1493 cpy
->gid
= tok
->gid
;
1494 cpy
->ngroups
= tok
->ngroups
;
1496 /* Make this a talloc child of cpy. */
1497 cpy
->groups
= (gid_t
*)talloc_memdup(
1498 cpy
, tok
->groups
, tok
->ngroups
* sizeof(gid_t
));
1507 /****************************************************************************
1508 Adds a delete on close token.
1509 ****************************************************************************/
1511 static bool add_delete_on_close_token(struct share_mode_lock
*lck
,
1513 const struct security_unix_token
*tok
)
1515 struct delete_token_list
*dtl
;
1517 dtl
= talloc_zero(lck
, struct delete_token_list
);
1522 dtl
->name_hash
= name_hash
;
1523 dtl
->delete_token
= copy_unix_token(lck
, tok
);
1524 if (dtl
->delete_token
== NULL
) {
1528 DLIST_ADD(lck
->delete_tokens
, dtl
);
1529 lck
->modified
= true;
1533 /****************************************************************************
1534 Sets the delete on close flag over all share modes on this file.
1535 Modify the share mode entry for all files open
1536 on this device and inode to tell other smbds we have
1537 changed the delete on close flag. This will be noticed
1538 in the close code, the last closer will delete the file
1540 This makes a copy of any struct security_unix_token into the
1541 lck entry. This function is used when the lock is already granted.
1542 ****************************************************************************/
1544 void set_delete_on_close_lck(files_struct
*fsp
,
1545 struct share_mode_lock
*lck
,
1546 bool delete_on_close
,
1547 const struct security_unix_token
*tok
)
1549 struct delete_token_list
*dtl
;
1552 if (delete_on_close
) {
1553 SMB_ASSERT(tok
!= NULL
);
1555 SMB_ASSERT(tok
== NULL
);
1558 for (dtl
= lck
->delete_tokens
; dtl
; dtl
= dtl
->next
) {
1559 if (dtl
->name_hash
== fsp
->name_hash
) {
1560 lck
->modified
= true;
1561 if (delete_on_close
== false) {
1562 /* Delete this entry. */
1563 DLIST_REMOVE(lck
->delete_tokens
, dtl
);
1567 /* Replace this token with the
1569 TALLOC_FREE(dtl
->delete_token
);
1570 dtl
->delete_token
= copy_unix_token(dtl
, tok
);
1571 SMB_ASSERT(dtl
->delete_token
!= NULL
);
1575 if (!delete_on_close
) {
1576 /* Nothing to delete - not found. */
1580 ret
= add_delete_on_close_token(lck
, fsp
->name_hash
, tok
);
1584 bool set_delete_on_close(files_struct
*fsp
, bool delete_on_close
, const struct security_unix_token
*tok
)
1586 struct share_mode_lock
*lck
;
1588 DEBUG(10,("set_delete_on_close: %s delete on close flag for "
1589 "fnum = %d, file %s\n",
1590 delete_on_close
? "Adding" : "Removing", fsp
->fnum
,
1593 lck
= get_share_mode_lock(talloc_tos(), fsp
->file_id
, NULL
, NULL
,
1599 set_delete_on_close_lck(fsp
, lck
, delete_on_close
,
1600 delete_on_close
? tok
: NULL
);
1602 if (fsp
->is_directory
) {
1603 SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp
->fsp_name
));
1604 send_stat_cache_delete_message(fsp
->conn
->sconn
->msg_ctx
,
1605 fsp
->fsp_name
->base_name
);
1610 fsp
->delete_on_close
= delete_on_close
;
1615 const struct security_unix_token
*get_delete_on_close_token(struct share_mode_lock
*lck
, uint32_t name_hash
)
1617 struct delete_token_list
*dtl
;
1619 DEBUG(10,("get_delete_on_close_token: name_hash = 0x%x\n",
1620 (unsigned int)name_hash
));
1622 for (dtl
= lck
->delete_tokens
; dtl
; dtl
= dtl
->next
) {
1623 DEBUG(10,("get_delete_on_close_token: dtl->name_hash = 0x%x\n",
1624 (unsigned int)dtl
->name_hash
));
1625 if (dtl
->name_hash
== name_hash
) {
1626 return dtl
->delete_token
;
1632 bool is_delete_on_close_set(struct share_mode_lock
*lck
, uint32_t name_hash
)
1634 return (get_delete_on_close_token(lck
, name_hash
) != NULL
);
1637 bool set_sticky_write_time(struct file_id fileid
, struct timespec write_time
)
1639 struct share_mode_lock
*lck
;
1641 DEBUG(5,("set_sticky_write_time: %s id=%s\n",
1642 timestring(talloc_tos(),
1643 convert_timespec_to_time_t(write_time
)),
1644 file_id_string_tos(&fileid
)));
1646 lck
= get_share_mode_lock(NULL
, fileid
, NULL
, NULL
, NULL
);
1651 if (timespec_compare(&lck
->changed_write_time
, &write_time
) != 0) {
1652 lck
->modified
= True
;
1653 lck
->changed_write_time
= write_time
;
1660 bool set_write_time(struct file_id fileid
, struct timespec write_time
)
1662 struct share_mode_lock
*lck
;
1664 DEBUG(5,("set_write_time: %s id=%s\n",
1665 timestring(talloc_tos(),
1666 convert_timespec_to_time_t(write_time
)),
1667 file_id_string_tos(&fileid
)));
1669 lck
= get_share_mode_lock(NULL
, fileid
, NULL
, NULL
, NULL
);
1674 if (timespec_compare(&lck
->old_write_time
, &write_time
) != 0) {
1675 lck
->modified
= True
;
1676 lck
->old_write_time
= write_time
;
1684 struct forall_state
{
1685 void (*fn
)(const struct share_mode_entry
*entry
,
1686 const char *sharepath
,
1688 void *private_data
);
1692 static int traverse_fn(struct db_record
*rec
, void *_state
)
1694 struct forall_state
*state
= (struct forall_state
*)_state
;
1695 struct locking_data
*data
;
1696 struct share_mode_entry
*shares
;
1697 const char *sharepath
;
1699 const char *del_tokens
;
1700 uint32_t total_del_token_size
= 0;
1703 /* Ensure this is a locking_key record. */
1704 if (rec
->key
.dsize
!= sizeof(struct file_id
))
1707 data
= (struct locking_data
*)rec
->value
.dptr
;
1708 shares
= (struct share_mode_entry
*)(rec
->value
.dptr
+ sizeof(*data
));
1709 del_tokens
= (const char *)rec
->value
.dptr
+ sizeof(*data
) +
1710 data
->u
.s
.num_share_mode_entries
*sizeof(*shares
);
1712 for (i
= 0; i
< data
->u
.s
.num_delete_token_entries
; i
++) {
1713 uint32_t del_token_size
;
1714 memcpy(&del_token_size
, del_tokens
, sizeof(uint32_t));
1715 total_del_token_size
+= del_token_size
;
1716 del_tokens
+= del_token_size
;
1719 sharepath
= (const char *)rec
->value
.dptr
+ sizeof(*data
) +
1720 data
->u
.s
.num_share_mode_entries
*sizeof(*shares
) +
1721 total_del_token_size
;
1722 fname
= (const char *)rec
->value
.dptr
+ sizeof(*data
) +
1723 data
->u
.s
.num_share_mode_entries
*sizeof(*shares
) +
1724 total_del_token_size
+
1725 strlen(sharepath
) + 1;
1727 for (i
=0;i
<data
->u
.s
.num_share_mode_entries
;i
++) {
1728 state
->fn(&shares
[i
], sharepath
, fname
,
1729 state
->private_data
);
1734 /*******************************************************************
1735 Call the specified function on each entry under management by the
1737 ********************************************************************/
1739 int share_mode_forall(void (*fn
)(const struct share_mode_entry
*, const char *,
1740 const char *, void *),
1743 struct forall_state state
;
1745 if (lock_db
== NULL
)
1749 state
.private_data
= private_data
;
1751 return lock_db
->traverse_read(lock_db
, traverse_fn
, (void *)&state
);