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 rewritten 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"
48 #include "../librpc/gen_ndr/ndr_open_files.h"
51 #define DBGC_CLASS DBGC_LOCKING
53 #define NO_LOCKING_COUNT (-1)
55 /****************************************************************************
57 ****************************************************************************/
59 const char *lock_type_name(enum brl_type lock_type
)
66 case PENDING_READ_LOCK
:
67 return "PENDING_READ";
68 case PENDING_WRITE_LOCK
:
69 return "PENDING_WRITE";
75 const char *lock_flav_name(enum brl_flavour lock_flav
)
77 return (lock_flav
== WINDOWS_LOCK
) ? "WINDOWS_LOCK" : "POSIX_LOCK";
80 /****************************************************************************
81 Utility function called to see if a file region is locked.
82 Called in the read/write codepath.
83 ****************************************************************************/
85 void init_strict_lock_struct(files_struct
*fsp
,
89 enum brl_type lock_type
,
90 struct lock_struct
*plock
)
92 SMB_ASSERT(lock_type
== READ_LOCK
|| lock_type
== WRITE_LOCK
);
94 plock
->context
.smblctx
= smblctx
;
95 plock
->context
.tid
= fsp
->conn
->cnum
;
96 plock
->context
.pid
= messaging_server_id(fsp
->conn
->sconn
->msg_ctx
);
99 plock
->fnum
= fsp
->fnum
;
100 plock
->lock_type
= lock_type
;
101 plock
->lock_flav
= lp_posix_cifsu_locktype(fsp
);
104 bool strict_lock_default(files_struct
*fsp
, struct lock_struct
*plock
)
106 struct byte_range_lock
*br_lck
;
107 int strict_locking
= lp_strict_locking(fsp
->conn
->params
);
110 if (plock
->size
== 0) {
114 if (!lp_locking(fsp
->conn
->params
) || !strict_locking
) {
118 if (strict_locking
== Auto
) {
119 if (EXCLUSIVE_OPLOCK_TYPE(fsp
->oplock_type
) &&
120 (plock
->lock_type
== READ_LOCK
||
121 plock
->lock_type
== WRITE_LOCK
)) {
122 DEBUG(10, ("is_locked: optimisation - exclusive oplock "
123 "on file %s\n", fsp_str_dbg(fsp
)));
126 if ((fsp
->oplock_type
== LEVEL_II_OPLOCK
) &&
127 (plock
->lock_type
== READ_LOCK
)) {
128 DEBUG(10, ("is_locked: optimisation - level II oplock "
129 "on file %s\n", fsp_str_dbg(fsp
)));
134 br_lck
= brl_get_locks_readonly(fsp
);
138 ret
= brl_locktest(br_lck
, plock
);
140 DEBUG(10, ("strict_lock_default: flavour = %s brl start=%ju "
141 "len=%ju %s for fnum %ju file %s\n",
142 lock_flav_name(plock
->lock_flav
),
143 (uintmax_t)plock
->start
, (uintmax_t)plock
->size
,
144 ret
? "unlocked" : "locked",
145 (uintmax_t)plock
->fnum
, fsp_str_dbg(fsp
)));
150 void strict_unlock_default(files_struct
*fsp
, struct lock_struct
*plock
)
154 /****************************************************************************
155 Find out if a lock could be granted - return who is blocking us if we can't.
156 ****************************************************************************/
158 NTSTATUS
query_lock(files_struct
*fsp
,
162 enum brl_type
*plock_type
,
163 enum brl_flavour lock_flav
)
165 struct byte_range_lock
*br_lck
= NULL
;
167 if (!fsp
->can_lock
) {
168 return fsp
->is_directory
? NT_STATUS_INVALID_DEVICE_REQUEST
: NT_STATUS_INVALID_HANDLE
;
171 if (!lp_locking(fsp
->conn
->params
)) {
175 br_lck
= brl_get_locks_readonly(fsp
);
177 return NT_STATUS_NO_MEMORY
;
180 return brl_lockquery(br_lck
,
182 messaging_server_id(fsp
->conn
->sconn
->msg_ctx
),
189 static void increment_current_lock_count(files_struct
*fsp
,
190 enum brl_flavour lock_flav
)
192 if (lock_flav
== WINDOWS_LOCK
&&
193 fsp
->current_lock_count
!= NO_LOCKING_COUNT
) {
194 /* blocking ie. pending, locks also count here,
195 * as this is an efficiency counter to avoid checking
196 * the lock db. on close. JRA. */
198 fsp
->current_lock_count
++;
200 /* Notice that this has had a POSIX lock request.
201 * We can't count locks after this so forget them.
203 fsp
->current_lock_count
= NO_LOCKING_COUNT
;
207 static void decrement_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 SMB_ASSERT(fsp
->current_lock_count
> 0);
213 fsp
->current_lock_count
--;
217 /****************************************************************************
218 Utility function called by locking requests.
219 ****************************************************************************/
221 struct byte_range_lock
*do_lock(struct messaging_context
*msg_ctx
,
226 enum brl_type lock_type
,
227 enum brl_flavour lock_flav
,
232 struct byte_range_lock
*br_lck
= NULL
;
234 /* silently return ok on print files as we don't do locking there */
235 if (fsp
->print_file
) {
236 *perr
= NT_STATUS_OK
;
240 if (!fsp
->can_lock
) {
241 *perr
= fsp
->is_directory
? NT_STATUS_INVALID_DEVICE_REQUEST
: NT_STATUS_INVALID_HANDLE
;
245 if (!lp_locking(fsp
->conn
->params
)) {
246 *perr
= NT_STATUS_OK
;
250 /* NOTE! 0 byte long ranges ARE allowed and should be stored */
252 DEBUG(10,("do_lock: lock flavour %s lock type %s start=%ju len=%ju "
253 "blocking_lock=%s requested for %s file %s\n",
254 lock_flav_name(lock_flav
), lock_type_name(lock_type
),
255 (uintmax_t)offset
, (uintmax_t)count
, blocking_lock
? "true" :
256 "false", fsp_fnum_dbg(fsp
), fsp_str_dbg(fsp
)));
258 br_lck
= brl_get_locks(talloc_tos(), fsp
);
260 *perr
= NT_STATUS_NO_MEMORY
;
264 *perr
= brl_lock(msg_ctx
,
267 messaging_server_id(fsp
->conn
->sconn
->msg_ctx
),
275 DEBUG(10, ("do_lock: returning status=%s\n", nt_errstr(*perr
)));
277 increment_current_lock_count(fsp
, lock_flav
);
281 /****************************************************************************
282 Utility function called by unlocking requests.
283 ****************************************************************************/
285 NTSTATUS
do_unlock(struct messaging_context
*msg_ctx
,
290 enum brl_flavour lock_flav
)
293 struct byte_range_lock
*br_lck
= NULL
;
295 if (!fsp
->can_lock
) {
296 return fsp
->is_directory
? NT_STATUS_INVALID_DEVICE_REQUEST
: NT_STATUS_INVALID_HANDLE
;
299 if (!lp_locking(fsp
->conn
->params
)) {
303 DEBUG(10, ("do_unlock: unlock start=%ju len=%ju requested for %s file "
304 "%s\n", (uintmax_t)offset
, (uintmax_t)count
,
305 fsp_fnum_dbg(fsp
), fsp_str_dbg(fsp
)));
307 br_lck
= brl_get_locks(talloc_tos(), fsp
);
309 return NT_STATUS_NO_MEMORY
;
312 ok
= brl_unlock(msg_ctx
,
315 messaging_server_id(fsp
->conn
->sconn
->msg_ctx
),
323 DEBUG(10,("do_unlock: returning ERRlock.\n" ));
324 return NT_STATUS_RANGE_NOT_LOCKED
;
327 decrement_current_lock_count(fsp
, lock_flav
);
331 /****************************************************************************
332 Cancel any pending blocked locks.
333 ****************************************************************************/
335 NTSTATUS
do_lock_cancel(files_struct
*fsp
,
339 enum brl_flavour lock_flav
)
342 struct byte_range_lock
*br_lck
= NULL
;
344 if (!fsp
->can_lock
) {
345 return fsp
->is_directory
?
346 NT_STATUS_INVALID_DEVICE_REQUEST
: NT_STATUS_INVALID_HANDLE
;
349 if (!lp_locking(fsp
->conn
->params
)) {
350 return NT_STATUS_DOS(ERRDOS
, ERRcancelviolation
);
353 DEBUG(10, ("do_lock_cancel: cancel start=%ju len=%ju requested for "
354 "%s file %s\n", (uintmax_t)offset
, (uintmax_t)count
,
355 fsp_fnum_dbg(fsp
), fsp_str_dbg(fsp
)));
357 br_lck
= brl_get_locks(talloc_tos(), fsp
);
359 return NT_STATUS_NO_MEMORY
;
362 ok
= brl_lock_cancel(br_lck
,
364 messaging_server_id(fsp
->conn
->sconn
->msg_ctx
),
372 DEBUG(10,("do_lock_cancel: returning ERRcancelviolation.\n" ));
373 return NT_STATUS_DOS(ERRDOS
, ERRcancelviolation
);
376 decrement_current_lock_count(fsp
, lock_flav
);
380 /****************************************************************************
381 Remove any locks on this fd. Called from file_close().
382 ****************************************************************************/
384 void locking_close_file(struct messaging_context
*msg_ctx
,
386 enum file_close_type close_type
)
388 struct byte_range_lock
*br_lck
;
390 if (!lp_locking(fsp
->conn
->params
)) {
394 /* If we have no outstanding locks or pending
395 * locks then we don't need to look in the lock db.
398 if (fsp
->current_lock_count
== 0) {
402 br_lck
= brl_get_locks(talloc_tos(),fsp
);
405 cancel_pending_lock_requests_by_fid(fsp
, br_lck
, close_type
);
406 brl_close_fnum(msg_ctx
, br_lck
);
411 /*******************************************************************
412 Print out a share mode.
413 ********************************************************************/
415 char *share_mode_str(TALLOC_CTX
*ctx
, int num
, const struct share_mode_entry
*e
)
417 return talloc_asprintf(ctx
, "share_mode_entry[%d]: "
418 "pid = %s, share_access = 0x%x, private_options = 0x%x, "
419 "access_mask = 0x%x, mid = 0x%llx, type= 0x%x, gen_id = %llu, "
420 "uid = %u, flags = %u, file_id %s, name_hash = 0x%x",
422 procid_str_static(&e
->pid
),
423 e
->share_access
, e
->private_options
,
424 e
->access_mask
, (unsigned long long)e
->op_mid
,
425 e
->op_type
, (unsigned long long)e
->share_file_id
,
426 (unsigned int)e
->uid
, (unsigned int)e
->flags
,
427 file_id_string_tos(&e
->id
),
428 (unsigned int)e
->name_hash
);
431 /*******************************************************************
432 Fetch a share mode where we know one MUST exist. This call reference
433 counts it internally to allow for nested lock fetches.
434 ********************************************************************/
436 struct share_mode_lock
*get_existing_share_mode_lock(TALLOC_CTX
*mem_ctx
,
437 const struct file_id id
)
439 return get_share_mode_lock(mem_ctx
, id
, NULL
, NULL
, NULL
);
442 /*******************************************************************
443 Sets the service name and filename for rename.
444 At this point we emit "file renamed" messages to all
445 process id's that have this file open.
446 Based on an initial code idea from SATOH Fumiyasu <fumiya@samba.gr.jp>
447 ********************************************************************/
449 bool rename_share_filename(struct messaging_context
*msg_ctx
,
450 struct share_mode_lock
*lck
,
452 const char *servicepath
,
453 uint32_t orig_name_hash
,
454 uint32_t new_name_hash
,
455 const struct smb_filename
*smb_fname_dst
)
457 struct share_mode_data
*d
= lck
->data
;
464 bool strip_two_chars
= false;
465 bool has_stream
= smb_fname_dst
->stream_name
!= NULL
;
466 struct server_id self_pid
= messaging_server_id(msg_ctx
);
468 DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n",
469 servicepath
, smb_fname_dst
->base_name
));
472 * rename_internal_fsp() and rename_internals() add './' to
473 * head of newname if newname does not contain a '/'.
475 if (smb_fname_dst
->base_name
[0] &&
476 smb_fname_dst
->base_name
[1] &&
477 smb_fname_dst
->base_name
[0] == '.' &&
478 smb_fname_dst
->base_name
[1] == '/') {
479 strip_two_chars
= true;
482 d
->servicepath
= talloc_strdup(d
, servicepath
);
483 d
->base_name
= talloc_strdup(d
, smb_fname_dst
->base_name
+
484 (strip_two_chars
? 2 : 0));
485 d
->stream_name
= talloc_strdup(d
, smb_fname_dst
->stream_name
);
486 if (d
->base_name
== NULL
||
487 (has_stream
&& d
->stream_name
== NULL
) ||
488 d
->servicepath
== NULL
) {
489 DEBUG(0, ("rename_share_filename: talloc failed\n"));
494 sp_len
= strlen(d
->servicepath
);
495 bn_len
= strlen(d
->base_name
);
496 sn_len
= has_stream
? strlen(d
->stream_name
) : 0;
498 msg_len
= MSG_FILE_RENAMED_MIN_SIZE
+ sp_len
+ 1 + bn_len
+ 1 +
501 /* Set up the name changed message. */
502 frm
= talloc_array(d
, char, msg_len
);
507 push_file_id_24(frm
, &id
);
509 DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len
));
512 d
->servicepath
? d
->servicepath
: "",
514 strlcpy(&frm
[24 + sp_len
+ 1],
515 d
->base_name
? d
->base_name
: "",
517 strlcpy(&frm
[24 + sp_len
+ 1 + bn_len
+ 1],
518 d
->stream_name
? d
->stream_name
: "",
521 /* Send the messages. */
522 for (i
=0; i
<d
->num_share_modes
; i
++) {
523 struct share_mode_entry
*se
= &d
->share_modes
[i
];
524 if (!is_valid_share_mode_entry(se
)) {
528 /* If this is a hardlink to the inode
529 with a different name, skip this. */
530 if (se
->name_hash
!= orig_name_hash
) {
534 se
->name_hash
= new_name_hash
;
536 /* But not to ourselves... */
537 if (serverid_equal(&se
->pid
, &self_pid
)) {
541 if (share_mode_stale_pid(d
, i
)) {
545 DEBUG(10,("rename_share_filename: sending rename message to "
546 "pid %s file_id %s sharepath %s base_name %s "
548 procid_str_static(&se
->pid
),
549 file_id_string_tos(&id
),
550 d
->servicepath
, d
->base_name
,
551 has_stream
? d
->stream_name
: ""));
553 messaging_send_buf(msg_ctx
, se
->pid
, MSG_SMB_FILE_RENAME
,
554 (uint8
*)frm
, msg_len
);
560 void get_file_infos(struct file_id id
,
562 bool *delete_on_close
,
563 struct timespec
*write_time
)
565 struct share_mode_lock
*lck
;
567 if (delete_on_close
) {
568 *delete_on_close
= false;
572 ZERO_STRUCTP(write_time
);
575 if (!(lck
= fetch_share_mode_unlocked(talloc_tos(), id
))) {
579 if (delete_on_close
) {
580 *delete_on_close
= is_delete_on_close_set(lck
, name_hash
);
584 *write_time
= get_share_mode_write_time(lck
);
590 bool is_valid_share_mode_entry(const struct share_mode_entry
*e
)
598 num_props
+= ((e
->op_type
== NO_OPLOCK
) ? 1 : 0);
599 num_props
+= (EXCLUSIVE_OPLOCK_TYPE(e
->op_type
) ? 1 : 0);
600 num_props
+= (LEVEL_II_OPLOCK_TYPE(e
->op_type
) ? 1 : 0);
602 if ((num_props
> 1) && serverid_exists(&e
->pid
)) {
603 smb_panic("Invalid share mode entry");
605 return (num_props
!= 0);
609 * In case d->share_modes[i] conflicts with something or otherwise is
610 * being used, we need to make sure the corresponding process still
613 bool share_mode_stale_pid(struct share_mode_data
*d
, uint32_t idx
)
615 struct share_mode_entry
*e
;
617 if (idx
> d
->num_share_modes
) {
618 DEBUG(1, ("Asking for index %u, only %u around\n",
619 idx
, (unsigned)d
->num_share_modes
));
622 e
= &d
->share_modes
[idx
];
629 if (serverid_exists(&e
->pid
)) {
630 DEBUG(10, ("PID %s (index %u out of %u) still exists\n",
631 procid_str_static(&e
->pid
), idx
,
632 (unsigned)d
->num_share_modes
));
635 DEBUG(10, ("PID %s (index %u out of %u) does not exist anymore\n",
636 procid_str_static(&e
->pid
), idx
,
637 (unsigned)d
->num_share_modes
));
641 if (d
->num_delete_tokens
!= 0) {
642 uint32_t i
, num_stale
;
645 * We cannot have any delete tokens
646 * if there are no valid share modes.
651 for (i
=0; i
<d
->num_share_modes
; i
++) {
652 if (d
->share_modes
[i
].stale
) {
657 if (num_stale
== d
->num_share_modes
) {
659 * No non-stale share mode found
661 TALLOC_FREE(d
->delete_tokens
);
662 d
->num_delete_tokens
= 0;
670 void remove_stale_share_mode_entries(struct share_mode_data
*d
)
675 while (i
< d
->num_share_modes
) {
676 if (d
->share_modes
[i
].stale
) {
677 struct share_mode_entry
*m
= d
->share_modes
;
678 m
[i
] = m
[d
->num_share_modes
-1];
679 d
->num_share_modes
-= 1;
686 bool set_share_mode(struct share_mode_lock
*lck
, files_struct
*fsp
,
687 uid_t uid
, uint64_t mid
, uint16 op_type
)
689 struct share_mode_data
*d
= lck
->data
;
690 struct share_mode_entry
*tmp
, *e
;
692 tmp
= talloc_realloc(d
, d
->share_modes
, struct share_mode_entry
,
693 d
->num_share_modes
+1);
697 d
->share_modes
= tmp
;
698 e
= &d
->share_modes
[d
->num_share_modes
];
699 d
->num_share_modes
+= 1;
703 e
->pid
= messaging_server_id(fsp
->conn
->sconn
->msg_ctx
);
704 e
->share_access
= fsp
->share_access
;
705 e
->private_options
= fsp
->fh
->private_options
;
706 e
->access_mask
= fsp
->access_mask
;
708 e
->op_type
= op_type
;
709 e
->time
.tv_sec
= fsp
->open_time
.tv_sec
;
710 e
->time
.tv_usec
= fsp
->open_time
.tv_usec
;
711 e
->id
= fsp
->file_id
;
712 e
->share_file_id
= fsp
->fh
->gen_id
;
713 e
->uid
= (uint32
)uid
;
714 e
->flags
= fsp
->posix_open
? SHARE_MODE_FLAG_POSIX_OPEN
: 0;
715 e
->name_hash
= fsp
->name_hash
;
720 static struct share_mode_entry
*find_share_mode_entry(
721 struct share_mode_lock
*lck
, files_struct
*fsp
)
723 struct share_mode_data
*d
= lck
->data
;
724 struct server_id pid
;
727 pid
= messaging_server_id(fsp
->conn
->sconn
->msg_ctx
);
729 for (i
=0; i
<d
->num_share_modes
; i
++) {
730 struct share_mode_entry
*e
= &d
->share_modes
[i
];
732 if (!is_valid_share_mode_entry(e
)) {
735 if (!serverid_equal(&pid
, &e
->pid
)) {
738 if (!file_id_equal(&fsp
->file_id
, &e
->id
)) {
741 if (fsp
->fh
->gen_id
!= e
->share_file_id
) {
749 /*******************************************************************
750 Del the share mode of a file for this process. Return the number of
752 ********************************************************************/
754 bool del_share_mode(struct share_mode_lock
*lck
, files_struct
*fsp
)
756 struct share_mode_entry
*e
;
758 e
= find_share_mode_entry(lck
, fsp
);
762 *e
= lck
->data
->share_modes
[lck
->data
->num_share_modes
-1];
763 lck
->data
->num_share_modes
-= 1;
764 lck
->data
->modified
= True
;
768 bool mark_share_mode_disconnected(struct share_mode_lock
*lck
,
769 struct files_struct
*fsp
)
771 struct share_mode_entry
*e
;
773 if (lck
->data
->num_share_modes
!= 1) {
777 if (fsp
->op
== NULL
) {
780 if (!fsp
->op
->global
->durable
) {
784 e
= find_share_mode_entry(lck
, fsp
);
789 DEBUG(10, ("Marking share mode entry disconnected for durable handle\n"));
791 server_id_set_disconnected(&e
->pid
);
794 * On reopen the caller needs to check that
795 * the client comes with the correct handle.
797 e
->share_file_id
= fsp
->op
->global
->open_persistent_id
;
799 lck
->data
->modified
= true;
803 /*******************************************************************
804 Remove an oplock mid and mode entry from a share mode.
805 ********************************************************************/
807 bool remove_share_oplock(struct share_mode_lock
*lck
, files_struct
*fsp
)
809 struct share_mode_entry
*e
;
811 e
= find_share_mode_entry(lck
, fsp
);
816 e
->op_type
= NO_OPLOCK
;
817 lck
->data
->modified
= True
;
821 /*******************************************************************
822 Downgrade a oplock type from exclusive to level II.
823 ********************************************************************/
825 bool downgrade_share_oplock(struct share_mode_lock
*lck
, files_struct
*fsp
)
827 struct share_mode_entry
*e
;
829 e
= find_share_mode_entry(lck
, fsp
);
834 e
->op_type
= LEVEL_II_OPLOCK
;
835 lck
->data
->modified
= True
;
839 /****************************************************************************
840 Adds a delete on close token.
841 ****************************************************************************/
843 static bool add_delete_on_close_token(struct share_mode_data
*d
,
845 const struct security_token
*nt_tok
,
846 const struct security_unix_token
*tok
)
848 struct delete_token
*tmp
, *dtl
;
850 tmp
= talloc_realloc(d
, d
->delete_tokens
, struct delete_token
,
851 d
->num_delete_tokens
+1);
855 d
->delete_tokens
= tmp
;
856 dtl
= &d
->delete_tokens
[d
->num_delete_tokens
];
858 dtl
->name_hash
= name_hash
;
859 dtl
->delete_nt_token
= dup_nt_token(d
->delete_tokens
, nt_tok
);
860 if (dtl
->delete_nt_token
== NULL
) {
863 dtl
->delete_token
= copy_unix_token(d
->delete_tokens
, tok
);
864 if (dtl
->delete_token
== NULL
) {
867 d
->num_delete_tokens
+= 1;
872 /****************************************************************************
873 Sets the delete on close flag over all share modes on this file.
874 Modify the share mode entry for all files open
875 on this device and inode to tell other smbds we have
876 changed the delete on close flag. This will be noticed
877 in the close code, the last closer will delete the file
879 This makes a copy of any struct security_unix_token into the
880 lck entry. This function is used when the lock is already granted.
881 ****************************************************************************/
883 void set_delete_on_close_lck(files_struct
*fsp
,
884 struct share_mode_lock
*lck
,
885 bool delete_on_close
,
886 const struct security_token
*nt_tok
,
887 const struct security_unix_token
*tok
)
889 struct share_mode_data
*d
= lck
->data
;
893 if (delete_on_close
) {
894 SMB_ASSERT(nt_tok
!= NULL
);
895 SMB_ASSERT(tok
!= NULL
);
897 SMB_ASSERT(nt_tok
== NULL
);
898 SMB_ASSERT(tok
== NULL
);
901 for (i
=0; i
<d
->num_delete_tokens
; i
++) {
902 struct delete_token
*dt
= &d
->delete_tokens
[i
];
903 if (dt
->name_hash
== fsp
->name_hash
) {
905 if (delete_on_close
== false) {
906 /* Delete this entry. */
907 TALLOC_FREE(dt
->delete_nt_token
);
908 TALLOC_FREE(dt
->delete_token
);
909 *dt
= d
->delete_tokens
[
910 d
->num_delete_tokens
-1];
911 d
->num_delete_tokens
-= 1;
913 /* Replace this token with the
915 TALLOC_FREE(dt
->delete_nt_token
);
916 dt
->delete_nt_token
= dup_nt_token(dt
, nt_tok
);
917 SMB_ASSERT(dt
->delete_nt_token
!= NULL
);
918 TALLOC_FREE(dt
->delete_token
);
919 dt
->delete_token
= copy_unix_token(dt
, tok
);
920 SMB_ASSERT(dt
->delete_token
!= NULL
);
926 if (!delete_on_close
) {
927 /* Nothing to delete - not found. */
931 ret
= add_delete_on_close_token(lck
->data
, fsp
->name_hash
, nt_tok
, tok
);
935 bool set_delete_on_close(files_struct
*fsp
, bool delete_on_close
,
936 const struct security_token
*nt_tok
,
937 const struct security_unix_token
*tok
)
939 struct share_mode_lock
*lck
;
941 DEBUG(10,("set_delete_on_close: %s delete on close flag for "
943 delete_on_close
? "Adding" : "Removing", fsp_fnum_dbg(fsp
),
946 lck
= get_existing_share_mode_lock(talloc_tos(), fsp
->file_id
);
951 if (delete_on_close
) {
952 set_delete_on_close_lck(fsp
, lck
, true,
956 set_delete_on_close_lck(fsp
, lck
, false,
961 if (fsp
->is_directory
) {
962 SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp
->fsp_name
));
963 send_stat_cache_delete_message(fsp
->conn
->sconn
->msg_ctx
,
964 fsp
->fsp_name
->base_name
);
969 fsp
->delete_on_close
= delete_on_close
;
974 static struct delete_token
*find_delete_on_close_token(
975 struct share_mode_data
*d
, uint32_t name_hash
)
979 DEBUG(10, ("find_delete_on_close_token: name_hash = 0x%x\n",
980 (unsigned int)name_hash
));
982 for (i
=0; i
<d
->num_delete_tokens
; i
++) {
983 struct delete_token
*dt
= &d
->delete_tokens
[i
];
985 DEBUG(10, ("find__delete_on_close_token: dt->name_hash = 0x%x\n",
986 (unsigned int)dt
->name_hash
));
987 if (dt
->name_hash
== name_hash
) {
994 /****************************************************************************
995 Return the NT token and UNIX token if there's a match. Return true if
997 ****************************************************************************/
999 bool get_delete_on_close_token(struct share_mode_lock
*lck
,
1001 const struct security_token
**pp_nt_tok
,
1002 const struct security_unix_token
**pp_tok
)
1004 struct delete_token
*dt
;
1006 dt
= find_delete_on_close_token(lck
->data
, name_hash
);
1010 *pp_nt_tok
= dt
->delete_nt_token
;
1011 *pp_tok
= dt
->delete_token
;
1015 bool is_delete_on_close_set(struct share_mode_lock
*lck
, uint32_t name_hash
)
1017 return find_delete_on_close_token(lck
->data
, name_hash
) != NULL
;
1020 bool set_sticky_write_time(struct file_id fileid
, struct timespec write_time
)
1022 struct share_mode_lock
*lck
;
1024 DEBUG(5,("set_sticky_write_time: %s id=%s\n",
1025 timestring(talloc_tos(),
1026 convert_timespec_to_time_t(write_time
)),
1027 file_id_string_tos(&fileid
)));
1029 lck
= get_existing_share_mode_lock(talloc_tos(), fileid
);
1034 if (timespec_compare(&lck
->data
->changed_write_time
, &write_time
) != 0) {
1035 lck
->data
->modified
= True
;
1036 lck
->data
->changed_write_time
= write_time
;
1043 bool set_write_time(struct file_id fileid
, struct timespec write_time
)
1045 struct share_mode_lock
*lck
;
1047 DEBUG(5,("set_write_time: %s id=%s\n",
1048 timestring(talloc_tos(),
1049 convert_timespec_to_time_t(write_time
)),
1050 file_id_string_tos(&fileid
)));
1052 lck
= get_existing_share_mode_lock(talloc_tos(), fileid
);
1057 if (timespec_compare(&lck
->data
->old_write_time
, &write_time
) != 0) {
1058 lck
->data
->modified
= True
;
1059 lck
->data
->old_write_time
= write_time
;
1066 struct timespec
get_share_mode_write_time(struct share_mode_lock
*lck
)
1068 struct share_mode_data
*d
= lck
->data
;
1070 if (!null_timespec(d
->changed_write_time
)) {
1071 return d
->changed_write_time
;
1073 return d
->old_write_time
;