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
,
139 plock
->context
.smblctx
,
146 DEBUG(10, ("strict_lock_default: flavour = %s brl start=%ju "
147 "len=%ju %s for fnum %ju file %s\n",
148 lock_flav_name(plock
->lock_flav
),
149 (uintmax_t)plock
->start
, (uintmax_t)plock
->size
,
150 ret
? "unlocked" : "locked",
151 (uintmax_t)plock
->fnum
, fsp_str_dbg(fsp
)));
156 void strict_unlock_default(files_struct
*fsp
, struct lock_struct
*plock
)
160 /****************************************************************************
161 Find out if a lock could be granted - return who is blocking us if we can't.
162 ****************************************************************************/
164 NTSTATUS
query_lock(files_struct
*fsp
,
168 enum brl_type
*plock_type
,
169 enum brl_flavour lock_flav
)
171 struct byte_range_lock
*br_lck
= NULL
;
173 if (!fsp
->can_lock
) {
174 return fsp
->is_directory
? NT_STATUS_INVALID_DEVICE_REQUEST
: NT_STATUS_INVALID_HANDLE
;
177 if (!lp_locking(fsp
->conn
->params
)) {
181 br_lck
= brl_get_locks_readonly(fsp
);
183 return NT_STATUS_NO_MEMORY
;
186 return brl_lockquery(br_lck
,
188 messaging_server_id(fsp
->conn
->sconn
->msg_ctx
),
195 static void increment_current_lock_count(files_struct
*fsp
,
196 enum brl_flavour lock_flav
)
198 if (lock_flav
== WINDOWS_LOCK
&&
199 fsp
->current_lock_count
!= NO_LOCKING_COUNT
) {
200 /* blocking ie. pending, locks also count here,
201 * as this is an efficiency counter to avoid checking
202 * the lock db. on close. JRA. */
204 fsp
->current_lock_count
++;
206 /* Notice that this has had a POSIX lock request.
207 * We can't count locks after this so forget them.
209 fsp
->current_lock_count
= NO_LOCKING_COUNT
;
213 static void decrement_current_lock_count(files_struct
*fsp
,
214 enum brl_flavour lock_flav
)
216 if (lock_flav
== WINDOWS_LOCK
&&
217 fsp
->current_lock_count
!= NO_LOCKING_COUNT
) {
218 SMB_ASSERT(fsp
->current_lock_count
> 0);
219 fsp
->current_lock_count
--;
223 /****************************************************************************
224 Utility function called by locking requests.
225 ****************************************************************************/
227 struct byte_range_lock
*do_lock(struct messaging_context
*msg_ctx
,
232 enum brl_type lock_type
,
233 enum brl_flavour lock_flav
,
238 struct byte_range_lock
*br_lck
= NULL
;
240 /* silently return ok on print files as we don't do locking there */
241 if (fsp
->print_file
) {
242 *perr
= NT_STATUS_OK
;
246 if (!fsp
->can_lock
) {
247 *perr
= fsp
->is_directory
? NT_STATUS_INVALID_DEVICE_REQUEST
: NT_STATUS_INVALID_HANDLE
;
251 if (!lp_locking(fsp
->conn
->params
)) {
252 *perr
= NT_STATUS_OK
;
256 /* NOTE! 0 byte long ranges ARE allowed and should be stored */
258 DEBUG(10,("do_lock: lock flavour %s lock type %s start=%ju len=%ju "
259 "blocking_lock=%s requested for %s file %s\n",
260 lock_flav_name(lock_flav
), lock_type_name(lock_type
),
261 (uintmax_t)offset
, (uintmax_t)count
, blocking_lock
? "true" :
262 "false", fsp_fnum_dbg(fsp
), fsp_str_dbg(fsp
)));
264 br_lck
= brl_get_locks(talloc_tos(), fsp
);
266 *perr
= NT_STATUS_NO_MEMORY
;
270 *perr
= brl_lock(msg_ctx
,
273 messaging_server_id(fsp
->conn
->sconn
->msg_ctx
),
281 DEBUG(10, ("do_lock: returning status=%s\n", nt_errstr(*perr
)));
283 increment_current_lock_count(fsp
, lock_flav
);
287 /****************************************************************************
288 Utility function called by unlocking requests.
289 ****************************************************************************/
291 NTSTATUS
do_unlock(struct messaging_context
*msg_ctx
,
296 enum brl_flavour lock_flav
)
299 struct byte_range_lock
*br_lck
= NULL
;
301 if (!fsp
->can_lock
) {
302 return fsp
->is_directory
? NT_STATUS_INVALID_DEVICE_REQUEST
: NT_STATUS_INVALID_HANDLE
;
305 if (!lp_locking(fsp
->conn
->params
)) {
309 DEBUG(10, ("do_unlock: unlock start=%ju len=%ju requested for %s file "
310 "%s\n", (uintmax_t)offset
, (uintmax_t)count
,
311 fsp_fnum_dbg(fsp
), fsp_str_dbg(fsp
)));
313 br_lck
= brl_get_locks(talloc_tos(), fsp
);
315 return NT_STATUS_NO_MEMORY
;
318 ok
= brl_unlock(msg_ctx
,
321 messaging_server_id(fsp
->conn
->sconn
->msg_ctx
),
329 DEBUG(10,("do_unlock: returning ERRlock.\n" ));
330 return NT_STATUS_RANGE_NOT_LOCKED
;
333 decrement_current_lock_count(fsp
, lock_flav
);
337 /****************************************************************************
338 Cancel any pending blocked locks.
339 ****************************************************************************/
341 NTSTATUS
do_lock_cancel(files_struct
*fsp
,
345 enum brl_flavour lock_flav
)
348 struct byte_range_lock
*br_lck
= NULL
;
350 if (!fsp
->can_lock
) {
351 return fsp
->is_directory
?
352 NT_STATUS_INVALID_DEVICE_REQUEST
: NT_STATUS_INVALID_HANDLE
;
355 if (!lp_locking(fsp
->conn
->params
)) {
356 return NT_STATUS_DOS(ERRDOS
, ERRcancelviolation
);
359 DEBUG(10, ("do_lock_cancel: cancel start=%ju len=%ju requested for "
360 "%s file %s\n", (uintmax_t)offset
, (uintmax_t)count
,
361 fsp_fnum_dbg(fsp
), fsp_str_dbg(fsp
)));
363 br_lck
= brl_get_locks(talloc_tos(), fsp
);
365 return NT_STATUS_NO_MEMORY
;
368 ok
= brl_lock_cancel(br_lck
,
370 messaging_server_id(fsp
->conn
->sconn
->msg_ctx
),
378 DEBUG(10,("do_lock_cancel: returning ERRcancelviolation.\n" ));
379 return NT_STATUS_DOS(ERRDOS
, ERRcancelviolation
);
382 decrement_current_lock_count(fsp
, lock_flav
);
386 /****************************************************************************
387 Remove any locks on this fd. Called from file_close().
388 ****************************************************************************/
390 void locking_close_file(struct messaging_context
*msg_ctx
,
392 enum file_close_type close_type
)
394 struct byte_range_lock
*br_lck
;
396 if (!lp_locking(fsp
->conn
->params
)) {
400 /* If we have no outstanding locks or pending
401 * locks then we don't need to look in the lock db.
404 if (fsp
->current_lock_count
== 0) {
408 br_lck
= brl_get_locks(talloc_tos(),fsp
);
411 cancel_pending_lock_requests_by_fid(fsp
, br_lck
, close_type
);
412 brl_close_fnum(msg_ctx
, br_lck
);
417 /*******************************************************************
418 Print out a share mode.
419 ********************************************************************/
421 char *share_mode_str(TALLOC_CTX
*ctx
, int num
, const struct share_mode_entry
*e
)
423 return talloc_asprintf(ctx
, "share_mode_entry[%d]: "
424 "pid = %s, share_access = 0x%x, private_options = 0x%x, "
425 "access_mask = 0x%x, mid = 0x%llx, type= 0x%x, gen_id = %llu, "
426 "uid = %u, flags = %u, file_id %s, name_hash = 0x%x",
428 procid_str_static(&e
->pid
),
429 e
->share_access
, e
->private_options
,
430 e
->access_mask
, (unsigned long long)e
->op_mid
,
431 e
->op_type
, (unsigned long long)e
->share_file_id
,
432 (unsigned int)e
->uid
, (unsigned int)e
->flags
,
433 file_id_string_tos(&e
->id
),
434 (unsigned int)e
->name_hash
);
437 /*******************************************************************
438 Fetch a share mode where we know one MUST exist. This call reference
439 counts it internally to allow for nested lock fetches.
440 ********************************************************************/
442 struct share_mode_lock
*get_existing_share_mode_lock(TALLOC_CTX
*mem_ctx
,
443 const struct file_id id
)
445 return get_share_mode_lock(mem_ctx
, id
, NULL
, NULL
, NULL
);
448 /*******************************************************************
449 Sets the service name and filename for rename.
450 At this point we emit "file renamed" messages to all
451 process id's that have this file open.
452 Based on an initial code idea from SATOH Fumiyasu <fumiya@samba.gr.jp>
453 ********************************************************************/
455 bool rename_share_filename(struct messaging_context
*msg_ctx
,
456 struct share_mode_lock
*lck
,
458 const char *servicepath
,
459 uint32_t orig_name_hash
,
460 uint32_t new_name_hash
,
461 const struct smb_filename
*smb_fname_dst
)
463 struct share_mode_data
*d
= lck
->data
;
470 bool strip_two_chars
= false;
471 bool has_stream
= smb_fname_dst
->stream_name
!= NULL
;
472 struct server_id self_pid
= messaging_server_id(msg_ctx
);
474 DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n",
475 servicepath
, smb_fname_dst
->base_name
));
478 * rename_internal_fsp() and rename_internals() add './' to
479 * head of newname if newname does not contain a '/'.
481 if (smb_fname_dst
->base_name
[0] &&
482 smb_fname_dst
->base_name
[1] &&
483 smb_fname_dst
->base_name
[0] == '.' &&
484 smb_fname_dst
->base_name
[1] == '/') {
485 strip_two_chars
= true;
488 d
->servicepath
= talloc_strdup(d
, servicepath
);
489 d
->base_name
= talloc_strdup(d
, smb_fname_dst
->base_name
+
490 (strip_two_chars
? 2 : 0));
491 d
->stream_name
= talloc_strdup(d
, smb_fname_dst
->stream_name
);
492 if (d
->base_name
== NULL
||
493 (has_stream
&& d
->stream_name
== NULL
) ||
494 d
->servicepath
== NULL
) {
495 DEBUG(0, ("rename_share_filename: talloc failed\n"));
500 sp_len
= strlen(d
->servicepath
);
501 bn_len
= strlen(d
->base_name
);
502 sn_len
= has_stream
? strlen(d
->stream_name
) : 0;
504 msg_len
= MSG_FILE_RENAMED_MIN_SIZE
+ sp_len
+ 1 + bn_len
+ 1 +
507 /* Set up the name changed message. */
508 frm
= talloc_array(d
, char, msg_len
);
513 push_file_id_24(frm
, &id
);
515 DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len
));
518 d
->servicepath
? d
->servicepath
: "",
520 strlcpy(&frm
[24 + sp_len
+ 1],
521 d
->base_name
? d
->base_name
: "",
523 strlcpy(&frm
[24 + sp_len
+ 1 + bn_len
+ 1],
524 d
->stream_name
? d
->stream_name
: "",
527 /* Send the messages. */
528 for (i
=0; i
<d
->num_share_modes
; i
++) {
529 struct share_mode_entry
*se
= &d
->share_modes
[i
];
530 if (!is_valid_share_mode_entry(se
)) {
534 /* If this is a hardlink to the inode
535 with a different name, skip this. */
536 if (se
->name_hash
!= orig_name_hash
) {
540 se
->name_hash
= new_name_hash
;
542 /* But not to ourselves... */
543 if (serverid_equal(&se
->pid
, &self_pid
)) {
547 if (share_mode_stale_pid(d
, i
)) {
551 DEBUG(10,("rename_share_filename: sending rename message to "
552 "pid %s file_id %s sharepath %s base_name %s "
554 procid_str_static(&se
->pid
),
555 file_id_string_tos(&id
),
556 d
->servicepath
, d
->base_name
,
557 has_stream
? d
->stream_name
: ""));
559 messaging_send_buf(msg_ctx
, se
->pid
, MSG_SMB_FILE_RENAME
,
560 (uint8
*)frm
, msg_len
);
566 void get_file_infos(struct file_id id
,
568 bool *delete_on_close
,
569 struct timespec
*write_time
)
571 struct share_mode_lock
*lck
;
573 if (delete_on_close
) {
574 *delete_on_close
= false;
578 ZERO_STRUCTP(write_time
);
581 if (!(lck
= fetch_share_mode_unlocked(talloc_tos(), id
))) {
585 if (delete_on_close
) {
586 *delete_on_close
= is_delete_on_close_set(lck
, name_hash
);
590 *write_time
= get_share_mode_write_time(lck
);
596 bool is_valid_share_mode_entry(const struct share_mode_entry
*e
)
604 num_props
+= ((e
->op_type
== NO_OPLOCK
) ? 1 : 0);
605 num_props
+= (EXCLUSIVE_OPLOCK_TYPE(e
->op_type
) ? 1 : 0);
606 num_props
+= (LEVEL_II_OPLOCK_TYPE(e
->op_type
) ? 1 : 0);
608 if ((num_props
> 1) && serverid_exists(&e
->pid
)) {
609 smb_panic("Invalid share mode entry");
611 return (num_props
!= 0);
615 * In case d->share_modes[i] conflicts with something or otherwise is
616 * being used, we need to make sure the corresponding process still
619 bool share_mode_stale_pid(struct share_mode_data
*d
, uint32_t idx
)
621 struct share_mode_entry
*e
;
623 if (idx
> d
->num_share_modes
) {
624 DEBUG(1, ("Asking for index %u, only %u around\n",
625 idx
, (unsigned)d
->num_share_modes
));
628 e
= &d
->share_modes
[idx
];
635 if (serverid_exists(&e
->pid
)) {
636 DEBUG(10, ("PID %s (index %u out of %u) still exists\n",
637 procid_str_static(&e
->pid
), idx
,
638 (unsigned)d
->num_share_modes
));
641 DEBUG(10, ("PID %s (index %u out of %u) does not exist anymore\n",
642 procid_str_static(&e
->pid
), idx
,
643 (unsigned)d
->num_share_modes
));
647 if (d
->num_delete_tokens
!= 0) {
648 uint32_t i
, num_stale
;
651 * We cannot have any delete tokens
652 * if there are no valid share modes.
657 for (i
=0; i
<d
->num_share_modes
; i
++) {
658 if (d
->share_modes
[i
].stale
) {
663 if (num_stale
== d
->num_share_modes
) {
665 * No non-stale share mode found
667 TALLOC_FREE(d
->delete_tokens
);
668 d
->num_delete_tokens
= 0;
676 void remove_stale_share_mode_entries(struct share_mode_data
*d
)
681 while (i
< d
->num_share_modes
) {
682 if (d
->share_modes
[i
].stale
) {
683 struct share_mode_entry
*m
= d
->share_modes
;
684 m
[i
] = m
[d
->num_share_modes
-1];
685 d
->num_share_modes
-= 1;
692 bool set_share_mode(struct share_mode_lock
*lck
, files_struct
*fsp
,
693 uid_t uid
, uint64_t mid
, uint16 op_type
)
695 struct share_mode_data
*d
= lck
->data
;
696 struct share_mode_entry
*tmp
, *e
;
698 tmp
= talloc_realloc(d
, d
->share_modes
, struct share_mode_entry
,
699 d
->num_share_modes
+1);
703 d
->share_modes
= tmp
;
704 e
= &d
->share_modes
[d
->num_share_modes
];
705 d
->num_share_modes
+= 1;
709 e
->pid
= messaging_server_id(fsp
->conn
->sconn
->msg_ctx
);
710 e
->share_access
= fsp
->share_access
;
711 e
->private_options
= fsp
->fh
->private_options
;
712 e
->access_mask
= fsp
->access_mask
;
714 e
->op_type
= op_type
;
715 e
->time
.tv_sec
= fsp
->open_time
.tv_sec
;
716 e
->time
.tv_usec
= fsp
->open_time
.tv_usec
;
717 e
->id
= fsp
->file_id
;
718 e
->share_file_id
= fsp
->fh
->gen_id
;
719 e
->uid
= (uint32
)uid
;
720 e
->flags
= fsp
->posix_open
? SHARE_MODE_FLAG_POSIX_OPEN
: 0;
721 e
->name_hash
= fsp
->name_hash
;
726 static struct share_mode_entry
*find_share_mode_entry(
727 struct share_mode_lock
*lck
, files_struct
*fsp
)
729 struct share_mode_data
*d
= lck
->data
;
730 struct server_id pid
;
733 pid
= messaging_server_id(fsp
->conn
->sconn
->msg_ctx
);
735 for (i
=0; i
<d
->num_share_modes
; i
++) {
736 struct share_mode_entry
*e
= &d
->share_modes
[i
];
738 if (!is_valid_share_mode_entry(e
)) {
741 if (!serverid_equal(&pid
, &e
->pid
)) {
744 if (!file_id_equal(&fsp
->file_id
, &e
->id
)) {
747 if (fsp
->fh
->gen_id
!= e
->share_file_id
) {
755 /*******************************************************************
756 Del the share mode of a file for this process. Return the number of
758 ********************************************************************/
760 bool del_share_mode(struct share_mode_lock
*lck
, files_struct
*fsp
)
762 struct share_mode_entry
*e
;
764 e
= find_share_mode_entry(lck
, fsp
);
768 *e
= lck
->data
->share_modes
[lck
->data
->num_share_modes
-1];
769 lck
->data
->num_share_modes
-= 1;
770 lck
->data
->modified
= True
;
774 bool mark_share_mode_disconnected(struct share_mode_lock
*lck
,
775 struct files_struct
*fsp
)
777 struct share_mode_entry
*e
;
779 if (lck
->data
->num_share_modes
!= 1) {
783 if (fsp
->op
== NULL
) {
786 if (!fsp
->op
->global
->durable
) {
790 e
= find_share_mode_entry(lck
, fsp
);
795 DEBUG(10, ("Marking share mode entry disconnected for durable handle\n"));
797 server_id_set_disconnected(&e
->pid
);
800 * On reopen the caller needs to check that
801 * the client comes with the correct handle.
803 e
->share_file_id
= fsp
->op
->global
->open_persistent_id
;
805 lck
->data
->modified
= true;
809 /*******************************************************************
810 Remove an oplock mid and mode entry from a share mode.
811 ********************************************************************/
813 bool remove_share_oplock(struct share_mode_lock
*lck
, files_struct
*fsp
)
815 struct share_mode_entry
*e
;
817 e
= find_share_mode_entry(lck
, fsp
);
822 e
->op_type
= NO_OPLOCK
;
823 lck
->data
->modified
= True
;
827 /*******************************************************************
828 Downgrade a oplock type from exclusive to level II.
829 ********************************************************************/
831 bool downgrade_share_oplock(struct share_mode_lock
*lck
, files_struct
*fsp
)
833 struct share_mode_entry
*e
;
835 e
= find_share_mode_entry(lck
, fsp
);
840 e
->op_type
= LEVEL_II_OPLOCK
;
841 lck
->data
->modified
= True
;
845 /****************************************************************************
846 Adds a delete on close token.
847 ****************************************************************************/
849 static bool add_delete_on_close_token(struct share_mode_data
*d
,
851 const struct security_token
*nt_tok
,
852 const struct security_unix_token
*tok
)
854 struct delete_token
*tmp
, *dtl
;
856 tmp
= talloc_realloc(d
, d
->delete_tokens
, struct delete_token
,
857 d
->num_delete_tokens
+1);
861 d
->delete_tokens
= tmp
;
862 dtl
= &d
->delete_tokens
[d
->num_delete_tokens
];
864 dtl
->name_hash
= name_hash
;
865 dtl
->delete_nt_token
= dup_nt_token(d
->delete_tokens
, nt_tok
);
866 if (dtl
->delete_nt_token
== NULL
) {
869 dtl
->delete_token
= copy_unix_token(d
->delete_tokens
, tok
);
870 if (dtl
->delete_token
== NULL
) {
873 d
->num_delete_tokens
+= 1;
878 /****************************************************************************
879 Sets the delete on close flag over all share modes on this file.
880 Modify the share mode entry for all files open
881 on this device and inode to tell other smbds we have
882 changed the delete on close flag. This will be noticed
883 in the close code, the last closer will delete the file
885 This makes a copy of any struct security_unix_token into the
886 lck entry. This function is used when the lock is already granted.
887 ****************************************************************************/
889 void set_delete_on_close_lck(files_struct
*fsp
,
890 struct share_mode_lock
*lck
,
891 bool delete_on_close
,
892 const struct security_token
*nt_tok
,
893 const struct security_unix_token
*tok
)
895 struct share_mode_data
*d
= lck
->data
;
899 if (delete_on_close
) {
900 SMB_ASSERT(nt_tok
!= NULL
);
901 SMB_ASSERT(tok
!= NULL
);
903 SMB_ASSERT(nt_tok
== NULL
);
904 SMB_ASSERT(tok
== NULL
);
907 for (i
=0; i
<d
->num_delete_tokens
; i
++) {
908 struct delete_token
*dt
= &d
->delete_tokens
[i
];
909 if (dt
->name_hash
== fsp
->name_hash
) {
911 if (delete_on_close
== false) {
912 /* Delete this entry. */
913 TALLOC_FREE(dt
->delete_nt_token
);
914 TALLOC_FREE(dt
->delete_token
);
915 *dt
= d
->delete_tokens
[
916 d
->num_delete_tokens
-1];
917 d
->num_delete_tokens
-= 1;
919 /* Replace this token with the
921 TALLOC_FREE(dt
->delete_nt_token
);
922 dt
->delete_nt_token
= dup_nt_token(dt
, nt_tok
);
923 SMB_ASSERT(dt
->delete_nt_token
!= NULL
);
924 TALLOC_FREE(dt
->delete_token
);
925 dt
->delete_token
= copy_unix_token(dt
, tok
);
926 SMB_ASSERT(dt
->delete_token
!= NULL
);
932 if (!delete_on_close
) {
933 /* Nothing to delete - not found. */
937 ret
= add_delete_on_close_token(lck
->data
, fsp
->name_hash
, nt_tok
, tok
);
941 bool set_delete_on_close(files_struct
*fsp
, bool delete_on_close
,
942 const struct security_token
*nt_tok
,
943 const struct security_unix_token
*tok
)
945 struct share_mode_lock
*lck
;
947 DEBUG(10,("set_delete_on_close: %s delete on close flag for "
949 delete_on_close
? "Adding" : "Removing", fsp_fnum_dbg(fsp
),
952 lck
= get_existing_share_mode_lock(talloc_tos(), fsp
->file_id
);
957 if (delete_on_close
) {
958 set_delete_on_close_lck(fsp
, lck
, true,
962 set_delete_on_close_lck(fsp
, lck
, false,
967 if (fsp
->is_directory
) {
968 SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp
->fsp_name
));
969 send_stat_cache_delete_message(fsp
->conn
->sconn
->msg_ctx
,
970 fsp
->fsp_name
->base_name
);
975 fsp
->delete_on_close
= delete_on_close
;
980 static struct delete_token
*find_delete_on_close_token(
981 struct share_mode_data
*d
, uint32_t name_hash
)
985 DEBUG(10, ("find_delete_on_close_token: name_hash = 0x%x\n",
986 (unsigned int)name_hash
));
988 for (i
=0; i
<d
->num_delete_tokens
; i
++) {
989 struct delete_token
*dt
= &d
->delete_tokens
[i
];
991 DEBUG(10, ("find__delete_on_close_token: dt->name_hash = 0x%x\n",
992 (unsigned int)dt
->name_hash
));
993 if (dt
->name_hash
== name_hash
) {
1000 /****************************************************************************
1001 Return the NT token and UNIX token if there's a match. Return true if
1002 found, false if not.
1003 ****************************************************************************/
1005 bool get_delete_on_close_token(struct share_mode_lock
*lck
,
1007 const struct security_token
**pp_nt_tok
,
1008 const struct security_unix_token
**pp_tok
)
1010 struct delete_token
*dt
;
1012 dt
= find_delete_on_close_token(lck
->data
, name_hash
);
1016 *pp_nt_tok
= dt
->delete_nt_token
;
1017 *pp_tok
= dt
->delete_token
;
1021 bool is_delete_on_close_set(struct share_mode_lock
*lck
, uint32_t name_hash
)
1023 return find_delete_on_close_token(lck
->data
, name_hash
) != NULL
;
1026 bool set_sticky_write_time(struct file_id fileid
, struct timespec write_time
)
1028 struct share_mode_lock
*lck
;
1030 DEBUG(5,("set_sticky_write_time: %s id=%s\n",
1031 timestring(talloc_tos(),
1032 convert_timespec_to_time_t(write_time
)),
1033 file_id_string_tos(&fileid
)));
1035 lck
= get_existing_share_mode_lock(talloc_tos(), fileid
);
1040 if (timespec_compare(&lck
->data
->changed_write_time
, &write_time
) != 0) {
1041 lck
->data
->modified
= True
;
1042 lck
->data
->changed_write_time
= write_time
;
1049 bool set_write_time(struct file_id fileid
, struct timespec write_time
)
1051 struct share_mode_lock
*lck
;
1053 DEBUG(5,("set_write_time: %s id=%s\n",
1054 timestring(talloc_tos(),
1055 convert_timespec_to_time_t(write_time
)),
1056 file_id_string_tos(&fileid
)));
1058 lck
= get_existing_share_mode_lock(talloc_tos(), fileid
);
1063 if (timespec_compare(&lck
->data
->old_write_time
, &write_time
) != 0) {
1064 lck
->data
->modified
= True
;
1065 lck
->data
->old_write_time
= write_time
;
1072 struct timespec
get_share_mode_write_time(struct share_mode_lock
*lck
)
1074 struct share_mode_data
*d
= lck
->data
;
1076 if (!null_timespec(d
->changed_write_time
)) {
1077 return d
->changed_write_time
;
1079 return d
->old_write_time
;