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 "librpc/gen_ndr/messaging.h"
40 #include "smbd/globals.h"
42 #include "../libcli/security/security.h"
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 /****************************************************************************
54 ****************************************************************************/
56 const char *lock_type_name(enum brl_type lock_type
)
63 case PENDING_READ_LOCK
:
64 return "PENDING_READ";
65 case PENDING_WRITE_LOCK
:
66 return "PENDING_WRITE";
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
,
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
);
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
);
106 if (plock
->size
== 0) {
110 if (!lp_locking(fsp
->conn
->params
) || !strict_locking
) {
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
)));
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
)));
123 struct byte_range_lock
*br_lck
;
125 br_lck
= brl_get_locks_readonly(fsp
);
129 ret
= brl_locktest(br_lck
,
130 plock
->context
.smblctx
,
138 struct byte_range_lock
*br_lck
;
140 br_lck
= brl_get_locks_readonly(fsp
);
144 ret
= brl_locktest(br_lck
,
145 plock
->context
.smblctx
,
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
)));
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
,
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
)) {
188 br_lck
= brl_get_locks_readonly(fsp
);
190 return NT_STATUS_NO_MEMORY
;
193 return brl_lockquery(br_lck
,
195 sconn_server_id(fsp
->conn
->sconn
),
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
++;
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
,
239 enum brl_type lock_type
,
240 enum brl_flavour lock_flav
,
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
;
254 if (!fsp
->can_lock
) {
255 *perr
= fsp
->is_directory
? NT_STATUS_INVALID_DEVICE_REQUEST
: NT_STATUS_INVALID_HANDLE
;
259 if (!lp_locking(fsp
->conn
->params
)) {
260 *perr
= NT_STATUS_OK
;
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
);
274 *perr
= NT_STATUS_NO_MEMORY
;
278 *perr
= brl_lock(msg_ctx
,
281 sconn_server_id(fsp
->conn
->sconn
),
290 DEBUG(10, ("do_lock: returning status=%s\n", nt_errstr(*perr
)));
292 increment_current_lock_count(fsp
, lock_flav
);
296 /****************************************************************************
297 Utility function called by unlocking requests.
298 ****************************************************************************/
300 NTSTATUS
do_unlock(struct messaging_context
*msg_ctx
,
305 enum brl_flavour lock_flav
)
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
)) {
318 DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for fnum %d file %s\n",
319 (double)offset
, (double)count
, fsp
->fnum
,
322 br_lck
= brl_get_locks(talloc_tos(), fsp
);
324 return NT_STATUS_NO_MEMORY
;
327 ok
= brl_unlock(msg_ctx
,
330 sconn_server_id(fsp
->conn
->sconn
),
338 DEBUG(10,("do_unlock: returning ERRlock.\n" ));
339 return NT_STATUS_RANGE_NOT_LOCKED
;
342 decrement_current_lock_count(fsp
, lock_flav
);
346 /****************************************************************************
347 Cancel any pending blocked locks.
348 ****************************************************************************/
350 NTSTATUS
do_lock_cancel(files_struct
*fsp
,
354 enum brl_flavour lock_flav
,
355 struct blocking_lock_record
*blr
)
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
,
373 br_lck
= brl_get_locks(talloc_tos(), fsp
);
375 return NT_STATUS_NO_MEMORY
;
378 ok
= brl_lock_cancel(br_lck
,
380 sconn_server_id(fsp
->conn
->sconn
),
389 DEBUG(10,("do_lock_cancel: returning ERRcancelviolation.\n" ));
390 return NT_STATUS_DOS(ERRDOS
, ERRcancelviolation
);
393 decrement_current_lock_count(fsp
, lock_flav
);
397 /****************************************************************************
398 Remove any locks on this fd. Called from file_close().
399 ****************************************************************************/
401 void locking_close_file(struct messaging_context
*msg_ctx
,
403 enum file_close_type close_type
)
405 struct byte_range_lock
*br_lck
;
407 if (!lp_locking(fsp
->conn
->params
)) {
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) {
419 br_lck
= brl_get_locks(talloc_tos(),fsp
);
422 cancel_pending_lock_requests_by_fid(fsp
, br_lck
, close_type
);
423 brl_close_fnum(msg_ctx
, br_lck
);
428 /****************************************************************************
429 Initialise the locking functions.
430 ****************************************************************************/
432 static bool locking_init_internal(bool read_only
)
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);
445 DEBUG(0,("ERROR: Failed to initialise locking database\n"));
449 if (!posix_locking_init(read_only
))
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)
472 TALLOC_FREE(lock_db
);
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
)
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, name_hash = 0x%x",
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
),
504 (unsigned int)e
->name_hash
);
507 /*******************************************************************
508 Print out a share mode table.
509 ********************************************************************/
511 static void print_share_mode_table(struct locking_data
*data
)
513 int num_share_modes
= data
->u
.s
.num_share_mode_entries
;
514 struct share_mode_entry
*shares
=
515 (struct share_mode_entry
*)(data
+ 1);
518 for (i
= 0; i
< num_share_modes
; i
++) {
519 struct share_mode_entry entry
;
523 * We need to memcpy the entry here due to alignment
524 * restrictions that are not met when directly accessing
528 memcpy(&entry
, &shares
[i
], sizeof(struct share_mode_entry
));
529 str
= share_mode_str(talloc_tos(), i
, &entry
);
531 DEBUG(10,("print_share_mode_table: %s\n", str
? str
: ""));
536 static int parse_delete_tokens_list(struct share_mode_lock
*lck
,
537 struct locking_data
*pdata
,
540 uint8_t *p
= dbuf
.dptr
+ sizeof(struct locking_data
) +
541 (lck
->num_share_modes
*
542 sizeof(struct share_mode_entry
));
543 uint8_t *end_ptr
= dbuf
.dptr
+ (dbuf
.dsize
- 2);
544 int delete_tokens_size
= 0;
547 lck
->delete_tokens
= NULL
;
549 for (i
= 0; i
< pdata
->u
.s
.num_delete_token_entries
; i
++) {
551 struct delete_token_list
*pdtl
;
553 if (end_ptr
- p
< (sizeof(uint32_t) + sizeof(uint32_t) +
554 sizeof(uid_t
) + sizeof(gid_t
))) {
555 DEBUG(0,("parse_delete_tokens_list: "
556 "corrupt token list (%u)",
557 (unsigned int)(end_ptr
- p
)));
558 smb_panic("corrupt token list");
562 memcpy(&token_len
, p
, sizeof(token_len
));
563 delete_tokens_size
+= token_len
;
565 if (p
+ token_len
> end_ptr
|| token_len
< sizeof(token_len
) +
566 sizeof(pdtl
->name_hash
) +
569 DEBUG(0,("parse_delete_tokens_list: "
570 "invalid token length (%u)\n",
571 (unsigned int)token_len
));
572 smb_panic("invalid token length");
576 p
+= sizeof(token_len
);
578 pdtl
= TALLOC_ZERO_P(lck
, struct delete_token_list
);
580 DEBUG(0,("parse_delete_tokens_list: talloc failed"));
583 /* Copy out the name_hash. */
584 memcpy(&pdtl
->name_hash
, p
, sizeof(pdtl
->name_hash
));
585 p
+= sizeof(pdtl
->name_hash
);
587 pdtl
->delete_token
= TALLOC_ZERO_P(pdtl
, struct security_unix_token
);
588 if (pdtl
->delete_token
== NULL
) {
589 DEBUG(0,("parse_delete_tokens_list: talloc failed"));
593 /* Copy out the uid and gid. */
594 memcpy(&pdtl
->delete_token
->uid
, p
, sizeof(uid_t
));
596 memcpy(&pdtl
->delete_token
->gid
, p
, sizeof(gid_t
));
599 token_len
-= (sizeof(token_len
) + sizeof(pdtl
->name_hash
) +
600 sizeof(uid_t
) + sizeof(gid_t
));
602 /* Any supplementary groups ? */
606 if (token_len
% sizeof(gid_t
) != 0) {
607 DEBUG(0,("parse_delete_tokens_list: "
608 "corrupt group list (%u)",
609 (unsigned int)(token_len
% sizeof(gid_t
)) ));
610 smb_panic("corrupt group list");
614 pdtl
->delete_token
->ngroups
= token_len
/ sizeof(gid_t
);
615 pdtl
->delete_token
->groups
= TALLOC_ARRAY(pdtl
->delete_token
, gid_t
,
616 pdtl
->delete_token
->ngroups
);
617 if (pdtl
->delete_token
->groups
== NULL
) {
618 DEBUG(0,("parse_delete_tokens_list: talloc failed"));
622 for (j
= 0; j
< pdtl
->delete_token
->ngroups
; j
++) {
623 memcpy(&pdtl
->delete_token
->groups
[j
], p
, sizeof(gid_t
));
627 /* Add to the list. */
628 DLIST_ADD(lck
->delete_tokens
, pdtl
);
631 return delete_tokens_size
;
634 /*******************************************************************
635 Get all share mode entries for a dev/inode pair.
636 ********************************************************************/
638 static bool parse_share_modes(const TDB_DATA dbuf
, struct share_mode_lock
*lck
)
640 struct locking_data data
;
641 int delete_tokens_size
;
644 if (dbuf
.dsize
< sizeof(struct locking_data
)) {
645 smb_panic("parse_share_modes: buffer too short");
648 memcpy(&data
, dbuf
.dptr
, sizeof(data
));
650 lck
->old_write_time
= data
.u
.s
.old_write_time
;
651 lck
->changed_write_time
= data
.u
.s
.changed_write_time
;
652 lck
->num_share_modes
= data
.u
.s
.num_share_mode_entries
;
654 DEBUG(10, ("parse_share_modes: owrt: %s, "
655 "cwrt: %s, ntok: %u, num_share_modes: %d\n",
656 timestring(talloc_tos(),
657 convert_timespec_to_time_t(lck
->old_write_time
)),
658 timestring(talloc_tos(),
659 convert_timespec_to_time_t(
660 lck
->changed_write_time
)),
661 (unsigned int)data
.u
.s
.num_delete_token_entries
,
662 lck
->num_share_modes
));
664 if ((lck
->num_share_modes
< 0) || (lck
->num_share_modes
> 1000000)) {
665 DEBUG(0, ("invalid number of share modes: %d\n",
666 lck
->num_share_modes
));
667 smb_panic("parse_share_modes: invalid number of share modes");
670 lck
->share_modes
= NULL
;
672 if (lck
->num_share_modes
!= 0) {
674 if (dbuf
.dsize
< (sizeof(struct locking_data
) +
675 (lck
->num_share_modes
*
676 sizeof(struct share_mode_entry
)))) {
677 smb_panic("parse_share_modes: buffer too short");
680 lck
->share_modes
= (struct share_mode_entry
*)
682 dbuf
.dptr
+sizeof(struct locking_data
),
683 lck
->num_share_modes
*
684 sizeof(struct share_mode_entry
));
686 if (lck
->share_modes
== NULL
) {
687 smb_panic("parse_share_modes: talloc failed");
691 /* Get any delete tokens. */
692 delete_tokens_size
= parse_delete_tokens_list(lck
, &data
, dbuf
);
693 if (delete_tokens_size
< 0) {
694 smb_panic("parse_share_modes: parse_delete_tokens_list failed");
697 /* Save off the associated service path and filename. */
698 lck
->servicepath
= (const char *)dbuf
.dptr
+ sizeof(struct locking_data
) +
699 (lck
->num_share_modes
* sizeof(struct share_mode_entry
)) +
702 lck
->base_name
= (const char *)dbuf
.dptr
+ sizeof(struct locking_data
) +
703 (lck
->num_share_modes
* sizeof(struct share_mode_entry
)) +
705 strlen(lck
->servicepath
) + 1;
707 lck
->stream_name
= (const char *)dbuf
.dptr
+ sizeof(struct locking_data
) +
708 (lck
->num_share_modes
* sizeof(struct share_mode_entry
)) +
710 strlen(lck
->servicepath
) + 1 +
711 strlen(lck
->base_name
) + 1;
714 * Ensure that each entry has a real process attached.
717 for (i
= 0; i
< lck
->num_share_modes
; i
++) {
718 struct share_mode_entry
*entry_p
= &lck
->share_modes
[i
];
720 if (DEBUGLEVEL
>= 10) {
721 str
= share_mode_str(NULL
, i
, entry_p
);
723 DEBUG(10,("parse_share_modes: %s\n",
725 if (!serverid_exists(&entry_p
->pid
)) {
726 DEBUG(10,("parse_share_modes: deleted %s\n",
728 entry_p
->op_type
= UNUSED_SHARE_MODE_ENTRY
;
729 lck
->modified
= True
;
737 static TDB_DATA
unparse_share_modes(const struct share_mode_lock
*lck
)
742 struct locking_data
*data
;
744 ssize_t sp_len
, bn_len
, sn_len
;
745 uint32_t delete_tokens_size
= 0;
746 struct delete_token_list
*pdtl
= NULL
;
747 uint32_t num_delete_token_entries
= 0;
752 for (i
=0; i
<lck
->num_share_modes
; i
++) {
753 if (!is_unused_share_mode_entry(&lck
->share_modes
[i
])) {
758 if (num_valid
== 0) {
762 sp_len
= strlen(lck
->servicepath
);
763 bn_len
= strlen(lck
->base_name
);
764 sn_len
= lck
->stream_name
!= NULL
? strlen(lck
->stream_name
) : 0;
766 for (pdtl
= lck
->delete_tokens
; pdtl
; pdtl
= pdtl
->next
) {
767 num_delete_token_entries
++;
768 delete_tokens_size
+= (sizeof(uint32_t) +
772 pdtl
->delete_token
->ngroups
*sizeof(gid_t
));
775 result
.dsize
= sizeof(*data
) +
776 lck
->num_share_modes
* sizeof(struct share_mode_entry
) +
781 result
.dptr
= TALLOC_ARRAY(lck
, uint8
, result
.dsize
);
783 if (result
.dptr
== NULL
) {
784 smb_panic("talloc failed");
787 data
= (struct locking_data
*)result
.dptr
;
789 data
->u
.s
.num_share_mode_entries
= lck
->num_share_modes
;
790 data
->u
.s
.old_write_time
= lck
->old_write_time
;
791 data
->u
.s
.changed_write_time
= lck
->changed_write_time
;
792 data
->u
.s
.num_delete_token_entries
= num_delete_token_entries
;
794 DEBUG(10,("unparse_share_modes: owrt: %s cwrt: %s, ntok: %u, "
796 timestring(talloc_tos(),
797 convert_timespec_to_time_t(lck
->old_write_time
)),
798 timestring(talloc_tos(),
799 convert_timespec_to_time_t(
800 lck
->changed_write_time
)),
801 (unsigned int)data
->u
.s
.num_delete_token_entries
,
802 data
->u
.s
.num_share_mode_entries
));
804 memcpy(result
.dptr
+ sizeof(*data
), lck
->share_modes
,
805 sizeof(struct share_mode_entry
)*lck
->num_share_modes
);
806 offset
= sizeof(*data
) +
807 sizeof(struct share_mode_entry
)*lck
->num_share_modes
;
809 /* Store any delete on close tokens. */
810 for (pdtl
= lck
->delete_tokens
; pdtl
; pdtl
= pdtl
->next
) {
811 struct security_unix_token
*pdt
= pdtl
->delete_token
;
812 uint32_t token_size
= sizeof(uint32_t) +
816 (pdt
->ngroups
* sizeof(gid_t
));
817 uint8_t *p
= result
.dptr
+ offset
;
819 memcpy(p
, &token_size
, sizeof(uint32_t));
820 p
+= sizeof(uint32_t);
822 memcpy(p
, &pdtl
->name_hash
, sizeof(uint32_t));
823 p
+= sizeof(uint32_t);
825 memcpy(p
, &pdt
->uid
, sizeof(uid_t
));
828 memcpy(p
, &pdt
->gid
, sizeof(gid_t
));
831 for (i
= 0; i
< pdt
->ngroups
; i
++) {
832 memcpy(p
, &pdt
->groups
[i
], sizeof(gid_t
));
835 offset
+= token_size
;
838 safe_strcpy((char *)result
.dptr
+ offset
, lck
->servicepath
,
839 result
.dsize
- offset
- 1);
840 offset
+= sp_len
+ 1;
841 safe_strcpy((char *)result
.dptr
+ offset
, lck
->base_name
,
842 result
.dsize
- offset
- 1);
843 offset
+= bn_len
+ 1;
844 safe_strcpy((char *)result
.dptr
+ offset
, lck
->stream_name
,
845 result
.dsize
- offset
- 1);
847 if (DEBUGLEVEL
>= 10) {
848 print_share_mode_table(data
);
854 static int share_mode_lock_destructor(struct share_mode_lock
*lck
)
859 if (!lck
->modified
) {
863 data
= unparse_share_modes(lck
);
865 if (data
.dptr
== NULL
) {
867 /* There has been an entry before, delete it */
869 status
= lck
->record
->delete_rec(lck
->record
);
870 if (!NT_STATUS_IS_OK(status
)) {
873 DEBUG(0, ("delete_rec returned %s\n",
876 if (asprintf(&errmsg
, "could not delete share "
878 nt_errstr(status
)) == -1) {
879 smb_panic("could not delete share"
888 status
= lck
->record
->store(lck
->record
, data
, TDB_REPLACE
);
889 if (!NT_STATUS_IS_OK(status
)) {
892 DEBUG(0, ("store returned %s\n", nt_errstr(status
)));
894 if (asprintf(&errmsg
, "could not store share mode entry: %s",
895 nt_errstr(status
)) == -1) {
896 smb_panic("could not store share mode entry");
906 static bool fill_share_mode_lock(struct share_mode_lock
*lck
,
908 const char *servicepath
,
909 const struct smb_filename
*smb_fname
,
910 TDB_DATA share_mode_data
,
911 const struct timespec
*old_write_time
)
913 /* Ensure we set every field here as the destructor must be
914 valid even if parse_share_modes fails. */
916 lck
->servicepath
= NULL
;
917 lck
->base_name
= NULL
;
918 lck
->stream_name
= NULL
;
920 lck
->num_share_modes
= 0;
921 lck
->share_modes
= NULL
;
922 lck
->delete_tokens
= NULL
;
923 ZERO_STRUCT(lck
->old_write_time
);
924 ZERO_STRUCT(lck
->changed_write_time
);
926 lck
->modified
= False
;
928 lck
->fresh
= (share_mode_data
.dptr
== NULL
);
932 if (smb_fname
== NULL
|| servicepath
== NULL
933 || old_write_time
== NULL
) {
937 has_stream
= smb_fname
->stream_name
!= NULL
;
939 lck
->base_name
= talloc_strdup(lck
, smb_fname
->base_name
);
940 lck
->stream_name
= talloc_strdup(lck
, smb_fname
->stream_name
);
941 lck
->servicepath
= talloc_strdup(lck
, servicepath
);
942 if (lck
->base_name
== NULL
||
943 (has_stream
&& lck
->stream_name
== NULL
) ||
944 lck
->servicepath
== NULL
) {
945 DEBUG(0, ("talloc failed\n"));
948 lck
->old_write_time
= *old_write_time
;
950 if (!parse_share_modes(share_mode_data
, lck
)) {
951 DEBUG(0, ("Could not parse share modes\n"));
959 struct share_mode_lock
*get_share_mode_lock(TALLOC_CTX
*mem_ctx
,
960 const struct file_id id
,
961 const char *servicepath
,
962 const struct smb_filename
*smb_fname
,
963 const struct timespec
*old_write_time
)
965 struct share_mode_lock
*lck
;
967 TDB_DATA key
= locking_key(&id
, &tmp
);
969 if (!(lck
= TALLOC_P(mem_ctx
, struct share_mode_lock
))) {
970 DEBUG(0, ("talloc failed\n"));
974 if (!(lck
->record
= lock_db
->fetch_locked(lock_db
, lck
, key
))) {
975 DEBUG(3, ("Could not lock share entry\n"));
980 if (!fill_share_mode_lock(lck
, id
, servicepath
, smb_fname
,
981 lck
->record
->value
, old_write_time
)) {
982 DEBUG(3, ("fill_share_mode_lock failed\n"));
987 talloc_set_destructor(lck
, share_mode_lock_destructor
);
992 struct share_mode_lock
*fetch_share_mode_unlocked(TALLOC_CTX
*mem_ctx
,
993 const struct file_id id
)
995 struct share_mode_lock
*lck
;
997 TDB_DATA key
= locking_key(&id
, &tmp
);
1000 if (!(lck
= TALLOC_P(mem_ctx
, struct share_mode_lock
))) {
1001 DEBUG(0, ("talloc failed\n"));
1005 if (lock_db
->fetch(lock_db
, lck
, key
, &data
) == -1) {
1006 DEBUG(3, ("Could not fetch share entry\n"));
1011 if (!fill_share_mode_lock(lck
, id
, NULL
, NULL
, data
, NULL
)) {
1012 DEBUG(10, ("fetch_share_mode_unlocked: no share_mode record "
1013 "around (file not open)\n"));
1021 /*******************************************************************
1022 Sets the service name and filename for rename.
1023 At this point we emit "file renamed" messages to all
1024 process id's that have this file open.
1025 Based on an initial code idea from SATOH Fumiyasu <fumiya@samba.gr.jp>
1026 ********************************************************************/
1028 bool rename_share_filename(struct messaging_context
*msg_ctx
,
1029 struct share_mode_lock
*lck
,
1030 const char *servicepath
,
1031 uint32_t orig_name_hash
,
1032 uint32_t new_name_hash
,
1033 const struct smb_filename
*smb_fname_dst
)
1041 bool strip_two_chars
= false;
1042 bool has_stream
= smb_fname_dst
->stream_name
!= NULL
;
1044 DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n",
1045 servicepath
, smb_fname_dst
->base_name
));
1048 * rename_internal_fsp() and rename_internals() add './' to
1049 * head of newname if newname does not contain a '/'.
1051 if (smb_fname_dst
->base_name
[0] &&
1052 smb_fname_dst
->base_name
[1] &&
1053 smb_fname_dst
->base_name
[0] == '.' &&
1054 smb_fname_dst
->base_name
[1] == '/') {
1055 strip_two_chars
= true;
1058 lck
->servicepath
= talloc_strdup(lck
, servicepath
);
1059 lck
->base_name
= talloc_strdup(lck
, smb_fname_dst
->base_name
+
1060 (strip_two_chars
? 2 : 0));
1061 lck
->stream_name
= talloc_strdup(lck
, smb_fname_dst
->stream_name
);
1062 if (lck
->base_name
== NULL
||
1063 (has_stream
&& lck
->stream_name
== NULL
) ||
1064 lck
->servicepath
== NULL
) {
1065 DEBUG(0, ("rename_share_filename: talloc failed\n"));
1068 lck
->modified
= True
;
1070 sp_len
= strlen(lck
->servicepath
);
1071 bn_len
= strlen(lck
->base_name
);
1072 sn_len
= has_stream
? strlen(lck
->stream_name
) : 0;
1074 msg_len
= MSG_FILE_RENAMED_MIN_SIZE
+ sp_len
+ 1 + bn_len
+ 1 +
1077 /* Set up the name changed message. */
1078 frm
= TALLOC_ARRAY(lck
, char, msg_len
);
1083 push_file_id_24(frm
, &lck
->id
);
1085 DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len
));
1087 safe_strcpy(&frm
[24], lck
->servicepath
, sp_len
);
1088 safe_strcpy(&frm
[24 + sp_len
+ 1], lck
->base_name
, bn_len
);
1089 safe_strcpy(&frm
[24 + sp_len
+ 1 + bn_len
+ 1], lck
->stream_name
,
1092 /* Send the messages. */
1093 for (i
=0; i
<lck
->num_share_modes
; i
++) {
1094 struct share_mode_entry
*se
= &lck
->share_modes
[i
];
1095 if (!is_valid_share_mode_entry(se
)) {
1099 /* If this is a hardlink to the inode
1100 with a different name, skip this. */
1101 if (se
->name_hash
!= orig_name_hash
) {
1105 se
->name_hash
= new_name_hash
;
1107 /* But not to ourselves... */
1108 if (procid_is_me(&se
->pid
)) {
1112 DEBUG(10,("rename_share_filename: sending rename message to "
1113 "pid %s file_id %s sharepath %s base_name %s "
1115 procid_str_static(&se
->pid
),
1116 file_id_string_tos(&lck
->id
),
1117 lck
->servicepath
, lck
->base_name
,
1118 has_stream
? lck
->stream_name
: ""));
1120 messaging_send_buf(msg_ctx
, se
->pid
, MSG_SMB_FILE_RENAME
,
1121 (uint8
*)frm
, msg_len
);
1127 void get_file_infos(struct file_id id
,
1129 bool *delete_on_close
,
1130 struct timespec
*write_time
)
1132 struct share_mode_lock
*lck
;
1134 if (delete_on_close
) {
1135 *delete_on_close
= false;
1139 ZERO_STRUCTP(write_time
);
1142 if (!(lck
= fetch_share_mode_unlocked(talloc_tos(), id
))) {
1146 if (delete_on_close
) {
1147 *delete_on_close
= is_delete_on_close_set(lck
, name_hash
);
1153 wt
= lck
->changed_write_time
;
1154 if (null_timespec(wt
)) {
1155 wt
= lck
->old_write_time
;
1164 bool is_valid_share_mode_entry(const struct share_mode_entry
*e
)
1168 if (e
->op_type
== UNUSED_SHARE_MODE_ENTRY
) {
1169 /* cope with dead entries from the process not
1170 existing. These should not be considered valid,
1171 otherwise we end up doing zero timeout sharing
1176 num_props
+= ((e
->op_type
== NO_OPLOCK
) ? 1 : 0);
1177 num_props
+= (EXCLUSIVE_OPLOCK_TYPE(e
->op_type
) ? 1 : 0);
1178 num_props
+= (LEVEL_II_OPLOCK_TYPE(e
->op_type
) ? 1 : 0);
1180 SMB_ASSERT(num_props
<= 1);
1181 return (num_props
!= 0);
1184 bool is_deferred_open_entry(const struct share_mode_entry
*e
)
1186 return (e
->op_type
== DEFERRED_OPEN_ENTRY
);
1189 bool is_unused_share_mode_entry(const struct share_mode_entry
*e
)
1191 return (e
->op_type
== UNUSED_SHARE_MODE_ENTRY
);
1194 /*******************************************************************
1195 Fill a share mode entry.
1196 ********************************************************************/
1198 static void fill_share_mode_entry(struct share_mode_entry
*e
,
1200 uid_t uid
, uint64_t mid
, uint16 op_type
)
1203 e
->pid
= sconn_server_id(fsp
->conn
->sconn
);
1204 e
->share_access
= fsp
->share_access
;
1205 e
->private_options
= fsp
->fh
->private_options
;
1206 e
->access_mask
= fsp
->access_mask
;
1208 e
->op_type
= op_type
;
1209 e
->time
.tv_sec
= fsp
->open_time
.tv_sec
;
1210 e
->time
.tv_usec
= fsp
->open_time
.tv_usec
;
1211 e
->id
= fsp
->file_id
;
1212 e
->share_file_id
= fsp
->fh
->gen_id
;
1213 e
->uid
= (uint32
)uid
;
1214 e
->flags
= fsp
->posix_open
? SHARE_MODE_FLAG_POSIX_OPEN
: 0;
1215 e
->name_hash
= fsp
->name_hash
;
1218 static void fill_deferred_open_entry(struct share_mode_entry
*e
,
1219 const struct timeval request_time
,
1221 struct server_id pid
,
1227 e
->op_type
= DEFERRED_OPEN_ENTRY
;
1228 e
->time
.tv_sec
= request_time
.tv_sec
;
1229 e
->time
.tv_usec
= request_time
.tv_usec
;
1231 e
->uid
= (uint32
)-1;
1235 static void add_share_mode_entry(struct share_mode_lock
*lck
,
1236 const struct share_mode_entry
*entry
)
1240 for (i
=0; i
<lck
->num_share_modes
; i
++) {
1241 struct share_mode_entry
*e
= &lck
->share_modes
[i
];
1242 if (is_unused_share_mode_entry(e
)) {
1248 if (i
== lck
->num_share_modes
) {
1249 /* No unused entry found */
1250 ADD_TO_ARRAY(lck
, struct share_mode_entry
, *entry
,
1251 &lck
->share_modes
, &lck
->num_share_modes
);
1253 lck
->modified
= True
;
1256 void set_share_mode(struct share_mode_lock
*lck
, files_struct
*fsp
,
1257 uid_t uid
, uint64_t mid
, uint16 op_type
)
1259 struct share_mode_entry entry
;
1260 fill_share_mode_entry(&entry
, fsp
, uid
, mid
, op_type
);
1261 add_share_mode_entry(lck
, &entry
);
1264 void add_deferred_open(struct share_mode_lock
*lck
, uint64_t mid
,
1265 struct timeval request_time
,
1266 struct server_id pid
, struct file_id id
)
1268 struct share_mode_entry entry
;
1269 fill_deferred_open_entry(&entry
, request_time
, id
, pid
, mid
);
1270 add_share_mode_entry(lck
, &entry
);
1273 /*******************************************************************
1274 Check if two share mode entries are identical, ignoring oplock
1275 and mid info and desired_access. (Removed paranoia test - it's
1276 not automatically a logic error if they are identical. JRA.)
1277 ********************************************************************/
1279 static bool share_modes_identical(struct share_mode_entry
*e1
,
1280 struct share_mode_entry
*e2
)
1282 /* We used to check for e1->share_access == e2->share_access here
1283 as well as the other fields but 2 different DOS or FCB opens
1284 sharing the same share mode entry may validly differ in
1285 fsp->share_access field. */
1287 return (procid_equal(&e1
->pid
, &e2
->pid
) &&
1288 file_id_equal(&e1
->id
, &e2
->id
) &&
1289 e1
->share_file_id
== e2
->share_file_id
);
1292 static bool deferred_open_identical(struct share_mode_entry
*e1
,
1293 struct share_mode_entry
*e2
)
1295 return (procid_equal(&e1
->pid
, &e2
->pid
) &&
1296 (e1
->op_mid
== e2
->op_mid
) &&
1297 file_id_equal(&e1
->id
, &e2
->id
));
1300 static struct share_mode_entry
*find_share_mode_entry(struct share_mode_lock
*lck
,
1301 struct share_mode_entry
*entry
)
1305 for (i
=0; i
<lck
->num_share_modes
; i
++) {
1306 struct share_mode_entry
*e
= &lck
->share_modes
[i
];
1307 if (is_valid_share_mode_entry(entry
) &&
1308 is_valid_share_mode_entry(e
) &&
1309 share_modes_identical(e
, entry
)) {
1312 if (is_deferred_open_entry(entry
) &&
1313 is_deferred_open_entry(e
) &&
1314 deferred_open_identical(e
, entry
)) {
1321 /*******************************************************************
1322 Del the share mode of a file for this process. Return the number of
1324 ********************************************************************/
1326 bool del_share_mode(struct share_mode_lock
*lck
, files_struct
*fsp
)
1328 struct share_mode_entry entry
, *e
;
1330 /* Don't care about the pid owner being correct here - just a search. */
1331 fill_share_mode_entry(&entry
, fsp
, (uid_t
)-1, 0, NO_OPLOCK
);
1333 e
= find_share_mode_entry(lck
, &entry
);
1338 e
->op_type
= UNUSED_SHARE_MODE_ENTRY
;
1339 lck
->modified
= True
;
1343 void del_deferred_open_entry(struct share_mode_lock
*lck
, uint64_t mid
,
1344 struct server_id pid
)
1346 struct share_mode_entry entry
, *e
;
1348 fill_deferred_open_entry(&entry
, timeval_zero(),
1351 e
= find_share_mode_entry(lck
, &entry
);
1356 e
->op_type
= UNUSED_SHARE_MODE_ENTRY
;
1357 lck
->modified
= True
;
1360 /*******************************************************************
1361 Remove an oplock mid and mode entry from a share mode.
1362 ********************************************************************/
1364 bool remove_share_oplock(struct share_mode_lock
*lck
, files_struct
*fsp
)
1366 struct share_mode_entry entry
, *e
;
1368 /* Don't care about the pid owner being correct here - just a search. */
1369 fill_share_mode_entry(&entry
, fsp
, (uid_t
)-1, 0, NO_OPLOCK
);
1371 e
= find_share_mode_entry(lck
, &entry
);
1377 if (EXCLUSIVE_OPLOCK_TYPE(fsp
->oplock_type
)) {
1379 * Going from exclusive or batch,
1380 * we always go through FAKE_LEVEL_II
1383 e
->op_type
= FAKE_LEVEL_II_OPLOCK
;
1385 e
->op_type
= NO_OPLOCK
;
1387 lck
->modified
= True
;
1391 /*******************************************************************
1392 Downgrade a oplock type from exclusive to level II.
1393 ********************************************************************/
1395 bool downgrade_share_oplock(struct share_mode_lock
*lck
, files_struct
*fsp
)
1397 struct share_mode_entry entry
, *e
;
1399 /* Don't care about the pid owner being correct here - just a search. */
1400 fill_share_mode_entry(&entry
, fsp
, (uid_t
)-1, 0, NO_OPLOCK
);
1402 e
= find_share_mode_entry(lck
, &entry
);
1407 e
->op_type
= LEVEL_II_OPLOCK
;
1408 lck
->modified
= True
;
1412 /****************************************************************************
1413 Check if setting delete on close is allowed on this fsp.
1414 ****************************************************************************/
1416 NTSTATUS
can_set_delete_on_close(files_struct
*fsp
, uint32 dosmode
)
1419 * Only allow delete on close for writable files.
1422 if ((dosmode
& aRONLY
) &&
1423 !lp_delete_readonly(SNUM(fsp
->conn
))) {
1424 DEBUG(10,("can_set_delete_on_close: file %s delete on close "
1425 "flag set but file attribute is readonly.\n",
1427 return NT_STATUS_CANNOT_DELETE
;
1431 * Only allow delete on close for writable shares.
1434 if (!CAN_WRITE(fsp
->conn
)) {
1435 DEBUG(10,("can_set_delete_on_close: file %s delete on "
1436 "close flag set but write access denied on share.\n",
1438 return NT_STATUS_ACCESS_DENIED
;
1442 * Only allow delete on close for files/directories opened with delete
1446 if (!(fsp
->access_mask
& DELETE_ACCESS
)) {
1447 DEBUG(10,("can_set_delete_on_close: file %s delete on "
1448 "close flag set but delete access denied.\n",
1450 return NT_STATUS_ACCESS_DENIED
;
1453 /* Don't allow delete on close for non-empty directories. */
1454 if (fsp
->is_directory
) {
1455 SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp
->fsp_name
));
1456 return can_delete_directory(fsp
->conn
,
1457 fsp
->fsp_name
->base_name
);
1460 return NT_STATUS_OK
;
1463 /*************************************************************************
1464 Return a talloced copy of a struct security_unix_token. NULL on fail.
1465 (Should this be in locking.c.... ?).
1466 *************************************************************************/
1468 static struct security_unix_token
*copy_unix_token(TALLOC_CTX
*ctx
, const struct security_unix_token
*tok
)
1470 struct security_unix_token
*cpy
;
1472 cpy
= TALLOC_P(ctx
, struct security_unix_token
);
1477 cpy
->uid
= tok
->uid
;
1478 cpy
->gid
= tok
->gid
;
1479 cpy
->ngroups
= tok
->ngroups
;
1481 /* Make this a talloc child of cpy. */
1482 cpy
->groups
= TALLOC_ARRAY(cpy
, gid_t
, tok
->ngroups
);
1486 memcpy(cpy
->groups
, tok
->groups
, tok
->ngroups
* sizeof(gid_t
));
1491 /****************************************************************************
1492 Adds a delete on close token.
1493 ****************************************************************************/
1495 static bool add_delete_on_close_token(struct share_mode_lock
*lck
,
1497 const struct security_unix_token
*tok
)
1499 struct delete_token_list
*dtl
;
1501 dtl
= TALLOC_ZERO_P(lck
, struct delete_token_list
);
1506 dtl
->name_hash
= name_hash
;
1507 dtl
->delete_token
= copy_unix_token(lck
, tok
);
1508 if (dtl
->delete_token
== NULL
) {
1512 DLIST_ADD(lck
->delete_tokens
, dtl
);
1513 lck
->modified
= true;
1517 /****************************************************************************
1518 Sets the delete on close flag over all share modes on this file.
1519 Modify the share mode entry for all files open
1520 on this device and inode to tell other smbds we have
1521 changed the delete on close flag. This will be noticed
1522 in the close code, the last closer will delete the file
1524 This makes a copy of any struct security_unix_token into the
1525 lck entry. This function is used when the lock is already granted.
1526 ****************************************************************************/
1528 void set_delete_on_close_lck(files_struct
*fsp
,
1529 struct share_mode_lock
*lck
,
1530 bool delete_on_close
,
1531 const struct security_unix_token
*tok
)
1533 struct delete_token_list
*dtl
;
1536 if (delete_on_close
) {
1537 SMB_ASSERT(tok
!= NULL
);
1539 SMB_ASSERT(tok
== NULL
);
1542 for (dtl
= lck
->delete_tokens
; dtl
; dtl
= dtl
->next
) {
1543 if (dtl
->name_hash
== fsp
->name_hash
) {
1544 lck
->modified
= true;
1545 if (delete_on_close
== false) {
1546 /* Delete this entry. */
1547 DLIST_REMOVE(lck
->delete_tokens
, dtl
);
1551 /* Replace this token with the
1553 TALLOC_FREE(dtl
->delete_token
);
1554 dtl
->delete_token
= copy_unix_token(dtl
, tok
);
1555 SMB_ASSERT(dtl
->delete_token
!= NULL
);
1559 if (!delete_on_close
) {
1560 /* Nothing to delete - not found. */
1564 ret
= add_delete_on_close_token(lck
, fsp
->name_hash
, tok
);
1568 bool set_delete_on_close(files_struct
*fsp
, bool delete_on_close
, const struct security_unix_token
*tok
)
1570 struct share_mode_lock
*lck
;
1572 DEBUG(10,("set_delete_on_close: %s delete on close flag for "
1573 "fnum = %d, file %s\n",
1574 delete_on_close
? "Adding" : "Removing", fsp
->fnum
,
1577 lck
= get_share_mode_lock(talloc_tos(), fsp
->file_id
, NULL
, NULL
,
1583 set_delete_on_close_lck(fsp
, lck
, delete_on_close
,
1584 delete_on_close
? tok
: NULL
);
1586 if (fsp
->is_directory
) {
1587 SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp
->fsp_name
));
1588 send_stat_cache_delete_message(fsp
->conn
->sconn
->msg_ctx
,
1589 fsp
->fsp_name
->base_name
);
1594 fsp
->delete_on_close
= delete_on_close
;
1599 const struct security_unix_token
*get_delete_on_close_token(struct share_mode_lock
*lck
, uint32_t name_hash
)
1601 struct delete_token_list
*dtl
;
1603 DEBUG(10,("get_delete_on_close_token: name_hash = 0x%x\n",
1604 (unsigned int)name_hash
));
1606 for (dtl
= lck
->delete_tokens
; dtl
; dtl
= dtl
->next
) {
1607 DEBUG(10,("get_delete_on_close_token: dtl->name_hash = 0x%x\n",
1608 (unsigned int)dtl
->name_hash
));
1609 if (dtl
->name_hash
== name_hash
) {
1610 return dtl
->delete_token
;
1616 bool is_delete_on_close_set(struct share_mode_lock
*lck
, uint32_t name_hash
)
1618 return (get_delete_on_close_token(lck
, name_hash
) != NULL
);
1621 bool set_sticky_write_time(struct file_id fileid
, struct timespec write_time
)
1623 struct share_mode_lock
*lck
;
1625 DEBUG(5,("set_sticky_write_time: %s id=%s\n",
1626 timestring(talloc_tos(),
1627 convert_timespec_to_time_t(write_time
)),
1628 file_id_string_tos(&fileid
)));
1630 lck
= get_share_mode_lock(NULL
, fileid
, NULL
, NULL
, NULL
);
1635 if (timespec_compare(&lck
->changed_write_time
, &write_time
) != 0) {
1636 lck
->modified
= True
;
1637 lck
->changed_write_time
= write_time
;
1644 bool set_write_time(struct file_id fileid
, struct timespec write_time
)
1646 struct share_mode_lock
*lck
;
1648 DEBUG(5,("set_write_time: %s id=%s\n",
1649 timestring(talloc_tos(),
1650 convert_timespec_to_time_t(write_time
)),
1651 file_id_string_tos(&fileid
)));
1653 lck
= get_share_mode_lock(NULL
, fileid
, NULL
, NULL
, NULL
);
1658 if (timespec_compare(&lck
->old_write_time
, &write_time
) != 0) {
1659 lck
->modified
= True
;
1660 lck
->old_write_time
= write_time
;
1668 struct forall_state
{
1669 void (*fn
)(const struct share_mode_entry
*entry
,
1670 const char *sharepath
,
1672 void *private_data
);
1676 static int traverse_fn(struct db_record
*rec
, void *_state
)
1678 struct forall_state
*state
= (struct forall_state
*)_state
;
1679 struct locking_data
*data
;
1680 struct share_mode_entry
*shares
;
1681 const char *sharepath
;
1683 const char *del_tokens
;
1684 uint32_t total_del_token_size
= 0;
1687 /* Ensure this is a locking_key record. */
1688 if (rec
->key
.dsize
!= sizeof(struct file_id
))
1691 data
= (struct locking_data
*)rec
->value
.dptr
;
1692 shares
= (struct share_mode_entry
*)(rec
->value
.dptr
+ sizeof(*data
));
1693 del_tokens
= (const char *)rec
->value
.dptr
+ sizeof(*data
) +
1694 data
->u
.s
.num_share_mode_entries
*sizeof(*shares
);
1696 for (i
= 0; i
< data
->u
.s
.num_delete_token_entries
; i
++) {
1697 uint32_t del_token_size
;
1698 memcpy(&del_token_size
, del_tokens
, sizeof(uint32_t));
1699 total_del_token_size
+= del_token_size
;
1700 del_tokens
+= del_token_size
;
1703 sharepath
= (const char *)rec
->value
.dptr
+ sizeof(*data
) +
1704 data
->u
.s
.num_share_mode_entries
*sizeof(*shares
) +
1705 total_del_token_size
;
1706 fname
= (const char *)rec
->value
.dptr
+ sizeof(*data
) +
1707 data
->u
.s
.num_share_mode_entries
*sizeof(*shares
) +
1708 total_del_token_size
+
1709 strlen(sharepath
) + 1;
1711 for (i
=0;i
<data
->u
.s
.num_share_mode_entries
;i
++) {
1712 state
->fn(&shares
[i
], sharepath
, fname
,
1713 state
->private_data
);
1718 /*******************************************************************
1719 Call the specified function on each entry under management by the
1721 ********************************************************************/
1723 int share_mode_forall(void (*fn
)(const struct share_mode_entry
*, const char *,
1724 const char *, void *),
1727 struct forall_state state
;
1729 if (lock_db
== NULL
)
1733 state
.private_data
= private_data
;
1735 return lock_db
->traverse_read(lock_db
, traverse_fn
, (void *)&state
);