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"
49 #include "locking/leases_db.h"
52 #define DBGC_CLASS DBGC_LOCKING
54 #define NO_LOCKING_COUNT (-1)
56 /****************************************************************************
58 ****************************************************************************/
60 const char *lock_type_name(enum brl_type lock_type)
67 case PENDING_READ_LOCK:
68 return "PENDING_READ";
69 case PENDING_WRITE_LOCK:
70 return "PENDING_WRITE";
76 const char *lock_flav_name(enum brl_flavour lock_flav)
78 return (lock_flav == WINDOWS_LOCK) ? "WINDOWS_LOCK" : "POSIX_LOCK";
81 /****************************************************************************
82 Utility function called to see if a file region is locked.
83 Called in the read/write codepath.
84 ****************************************************************************/
86 void init_strict_lock_struct(files_struct *fsp,
90 enum brl_type lock_type,
91 struct lock_struct *plock)
93 SMB_ASSERT(lock_type == READ_LOCK || lock_type == WRITE_LOCK);
95 plock->context.smblctx = smblctx;
96 plock->context.tid = fsp->conn->cnum;
97 plock->context.pid = messaging_server_id(fsp->conn->sconn->msg_ctx);
100 plock->fnum = fsp->fnum;
101 plock->lock_type = lock_type;
102 plock->lock_flav = lp_posix_cifsu_locktype(fsp);
105 bool strict_lock_default(files_struct *fsp, struct lock_struct *plock)
107 struct byte_range_lock *br_lck;
108 int strict_locking = lp_strict_locking(fsp->conn->params);
111 if (plock->size == 0) {
115 if (!lp_locking(fsp->conn->params) || !strict_locking) {
119 if (strict_locking == Auto) {
120 if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) &&
121 (plock->lock_type == READ_LOCK ||
122 plock->lock_type == WRITE_LOCK)) {
123 DEBUG(10, ("is_locked: optimisation - exclusive oplock "
124 "on file %s\n", fsp_str_dbg(fsp)));
127 if ((fsp->oplock_type == LEVEL_II_OPLOCK) &&
128 (plock->lock_type == READ_LOCK)) {
129 DEBUG(10, ("is_locked: optimisation - level II oplock "
130 "on file %s\n", fsp_str_dbg(fsp)));
135 br_lck = brl_get_locks_readonly(fsp);
139 ret = brl_locktest(br_lck, plock);
143 * We got a lock conflict. Retry with rw locks to enable
144 * autocleanup. This is the slow path anyway.
146 br_lck = brl_get_locks(talloc_tos(), fsp);
147 ret = brl_locktest(br_lck, plock);
151 DEBUG(10, ("strict_lock_default: flavour = %s brl start=%ju "
152 "len=%ju %s for fnum %ju file %s\n",
153 lock_flav_name(plock->lock_flav),
154 (uintmax_t)plock->start, (uintmax_t)plock->size,
155 ret ? "unlocked" : "locked",
156 (uintmax_t)plock->fnum, fsp_str_dbg(fsp)));
161 void strict_unlock_default(files_struct *fsp, struct lock_struct *plock)
165 /****************************************************************************
166 Find out if a lock could be granted - return who is blocking us if we can't.
167 ****************************************************************************/
169 NTSTATUS query_lock(files_struct *fsp,
173 enum brl_type *plock_type,
174 enum brl_flavour lock_flav)
176 struct byte_range_lock *br_lck = NULL;
178 if (!fsp->can_lock) {
179 return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
182 if (!lp_locking(fsp->conn->params)) {
186 br_lck = brl_get_locks_readonly(fsp);
188 return NT_STATUS_NO_MEMORY;
191 return brl_lockquery(br_lck,
193 messaging_server_id(fsp->conn->sconn->msg_ctx),
200 static void increment_current_lock_count(files_struct *fsp,
201 enum brl_flavour lock_flav)
203 if (lock_flav == WINDOWS_LOCK &&
204 fsp->current_lock_count != NO_LOCKING_COUNT) {
205 /* blocking ie. pending, locks also count here,
206 * as this is an efficiency counter to avoid checking
207 * the lock db. on close. JRA. */
209 fsp->current_lock_count++;
211 /* Notice that this has had a POSIX lock request.
212 * We can't count locks after this so forget them.
214 fsp->current_lock_count = NO_LOCKING_COUNT;
218 static void decrement_current_lock_count(files_struct *fsp,
219 enum brl_flavour lock_flav)
221 if (lock_flav == WINDOWS_LOCK &&
222 fsp->current_lock_count != NO_LOCKING_COUNT) {
223 SMB_ASSERT(fsp->current_lock_count > 0);
224 fsp->current_lock_count--;
228 /****************************************************************************
229 Utility function called by locking requests.
230 ****************************************************************************/
232 struct byte_range_lock *do_lock(struct messaging_context *msg_ctx,
237 enum brl_type lock_type,
238 enum brl_flavour lock_flav,
243 struct byte_range_lock *br_lck = NULL;
245 /* silently return ok on print files as we don't do locking there */
246 if (fsp->print_file) {
247 *perr = NT_STATUS_OK;
251 if (!fsp->can_lock) {
252 *perr = fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
256 if (!lp_locking(fsp->conn->params)) {
257 *perr = NT_STATUS_OK;
261 /* NOTE! 0 byte long ranges ARE allowed and should be stored */
263 DEBUG(10,("do_lock: lock flavour %s lock type %s start=%ju len=%ju "
264 "blocking_lock=%s requested for %s file %s\n",
265 lock_flav_name(lock_flav), lock_type_name(lock_type),
266 (uintmax_t)offset, (uintmax_t)count, blocking_lock ? "true" :
267 "false", fsp_fnum_dbg(fsp), fsp_str_dbg(fsp)));
269 br_lck = brl_get_locks(talloc_tos(), fsp);
271 *perr = NT_STATUS_NO_MEMORY;
275 *perr = brl_lock(msg_ctx,
278 messaging_server_id(fsp->conn->sconn->msg_ctx),
286 DEBUG(10, ("do_lock: returning status=%s\n", nt_errstr(*perr)));
288 increment_current_lock_count(fsp, lock_flav);
292 /****************************************************************************
293 Utility function called by unlocking requests.
294 ****************************************************************************/
296 NTSTATUS do_unlock(struct messaging_context *msg_ctx,
301 enum brl_flavour lock_flav)
304 struct byte_range_lock *br_lck = NULL;
306 if (!fsp->can_lock) {
307 return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
310 if (!lp_locking(fsp->conn->params)) {
314 DEBUG(10, ("do_unlock: unlock start=%ju len=%ju requested for %s file "
315 "%s\n", (uintmax_t)offset, (uintmax_t)count,
316 fsp_fnum_dbg(fsp), fsp_str_dbg(fsp)));
318 br_lck = brl_get_locks(talloc_tos(), fsp);
320 return NT_STATUS_NO_MEMORY;
323 ok = brl_unlock(msg_ctx,
326 messaging_server_id(fsp->conn->sconn->msg_ctx),
334 DEBUG(10,("do_unlock: returning ERRlock.\n" ));
335 return NT_STATUS_RANGE_NOT_LOCKED;
338 decrement_current_lock_count(fsp, lock_flav);
342 /****************************************************************************
343 Cancel any pending blocked locks.
344 ****************************************************************************/
346 NTSTATUS do_lock_cancel(files_struct *fsp,
350 enum brl_flavour lock_flav)
353 struct byte_range_lock *br_lck = NULL;
355 if (!fsp->can_lock) {
356 return fsp->is_directory ?
357 NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
360 if (!lp_locking(fsp->conn->params)) {
361 return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
364 DEBUG(10, ("do_lock_cancel: cancel start=%ju len=%ju requested for "
365 "%s file %s\n", (uintmax_t)offset, (uintmax_t)count,
366 fsp_fnum_dbg(fsp), fsp_str_dbg(fsp)));
368 br_lck = brl_get_locks(talloc_tos(), fsp);
370 return NT_STATUS_NO_MEMORY;
373 ok = brl_lock_cancel(br_lck,
375 messaging_server_id(fsp->conn->sconn->msg_ctx),
383 DEBUG(10,("do_lock_cancel: returning ERRcancelviolation.\n" ));
384 return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
387 decrement_current_lock_count(fsp, lock_flav);
391 /****************************************************************************
392 Remove any locks on this fd. Called from file_close().
393 ****************************************************************************/
395 void locking_close_file(struct messaging_context *msg_ctx,
397 enum file_close_type close_type)
399 struct byte_range_lock *br_lck;
401 if (!lp_locking(fsp->conn->params)) {
405 /* If we have no outstanding locks or pending
406 * locks then we don't need to look in the lock db.
409 if (fsp->current_lock_count == 0) {
413 br_lck = brl_get_locks(talloc_tos(),fsp);
416 cancel_pending_lock_requests_by_fid(fsp, br_lck, close_type);
417 brl_close_fnum(msg_ctx, br_lck);
422 /*******************************************************************
423 Print out a share mode.
424 ********************************************************************/
426 char *share_mode_str(TALLOC_CTX *ctx, int num, const struct share_mode_entry *e)
428 return talloc_asprintf(ctx, "share_mode_entry[%d]: "
429 "pid = %s, share_access = 0x%x, private_options = 0x%x, "
430 "access_mask = 0x%x, mid = 0x%llx, type= 0x%x, gen_id = %llu, "
431 "uid = %u, flags = %u, file_id %s, name_hash = 0x%x",
433 procid_str_static(&e->pid),
434 e->share_access, e->private_options,
435 e->access_mask, (unsigned long long)e->op_mid,
436 e->op_type, (unsigned long long)e->share_file_id,
437 (unsigned int)e->uid, (unsigned int)e->flags,
438 file_id_string_tos(&e->id),
439 (unsigned int)e->name_hash);
442 /*******************************************************************
443 Fetch a share mode where we know one MUST exist. This call reference
444 counts it internally to allow for nested lock fetches.
445 ********************************************************************/
447 struct share_mode_lock *get_existing_share_mode_lock(TALLOC_CTX *mem_ctx,
448 const struct file_id id)
450 return get_share_mode_lock(mem_ctx, id, NULL, NULL, NULL);
453 /*******************************************************************
454 Sets the service name and filename for rename.
455 At this point we emit "file renamed" messages to all
456 process id's that have this file open.
457 Based on an initial code idea from SATOH Fumiyasu <fumiya@samba.gr.jp>
458 ********************************************************************/
460 bool rename_share_filename(struct messaging_context *msg_ctx,
461 struct share_mode_lock *lck,
463 const char *servicepath,
464 uint32_t orig_name_hash,
465 uint32_t new_name_hash,
466 const struct smb_filename *smb_fname_dst)
468 struct share_mode_data *d = lck->data;
475 bool strip_two_chars = false;
476 bool has_stream = smb_fname_dst->stream_name != NULL;
477 struct server_id self_pid = messaging_server_id(msg_ctx);
479 DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n",
480 servicepath, smb_fname_dst->base_name));
483 * rename_internal_fsp() and rename_internals() add './' to
484 * head of newname if newname does not contain a '/'.
486 if (smb_fname_dst->base_name[0] &&
487 smb_fname_dst->base_name[1] &&
488 smb_fname_dst->base_name[0] == '.' &&
489 smb_fname_dst->base_name[1] == '/') {
490 strip_two_chars = true;
493 d->servicepath = talloc_strdup(d, servicepath);
494 d->base_name = talloc_strdup(d, smb_fname_dst->base_name +
495 (strip_two_chars ? 2 : 0));
496 d->stream_name = talloc_strdup(d, smb_fname_dst->stream_name);
497 if (d->base_name == NULL ||
498 (has_stream && d->stream_name == NULL) ||
499 d->servicepath == NULL) {
500 DEBUG(0, ("rename_share_filename: talloc failed\n"));
505 sp_len = strlen(d->servicepath);
506 bn_len = strlen(d->base_name);
507 sn_len = has_stream ? strlen(d->stream_name) : 0;
509 msg_len = MSG_FILE_RENAMED_MIN_SIZE + sp_len + 1 + bn_len + 1 +
512 /* Set up the name changed message. */
513 frm = talloc_array(d, char, msg_len);
518 push_file_id_24(frm, &id);
520 DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len ));
523 d->servicepath ? d->servicepath : "",
525 strlcpy(&frm[24 + sp_len + 1],
526 d->base_name ? d->base_name : "",
528 strlcpy(&frm[24 + sp_len + 1 + bn_len + 1],
529 d->stream_name ? d->stream_name : "",
532 /* Send the messages. */
533 for (i=0; i<d->num_share_modes; i++) {
534 struct share_mode_entry *se = &d->share_modes[i];
535 if (!is_valid_share_mode_entry(se)) {
539 /* If this is a hardlink to the inode
540 with a different name, skip this. */
541 if (se->name_hash != orig_name_hash) {
545 se->name_hash = new_name_hash;
547 /* But not to ourselves... */
548 if (serverid_equal(&se->pid, &self_pid)) {
552 if (share_mode_stale_pid(d, i)) {
556 DEBUG(10,("rename_share_filename: sending rename message to "
557 "pid %s file_id %s sharepath %s base_name %s "
559 procid_str_static(&se->pid),
560 file_id_string_tos(&id),
561 d->servicepath, d->base_name,
562 has_stream ? d->stream_name : ""));
564 messaging_send_buf(msg_ctx, se->pid, MSG_SMB_FILE_RENAME,
565 (uint8 *)frm, msg_len);
571 void get_file_infos(struct file_id id,
573 bool *delete_on_close,
574 struct timespec *write_time)
576 struct share_mode_lock *lck;
578 if (delete_on_close) {
579 *delete_on_close = false;
583 ZERO_STRUCTP(write_time);
586 if (!(lck = fetch_share_mode_unlocked(talloc_tos(), id))) {
590 if (delete_on_close) {
591 *delete_on_close = is_delete_on_close_set(lck, name_hash);
595 *write_time = get_share_mode_write_time(lck);
601 bool is_valid_share_mode_entry(const struct share_mode_entry *e)
609 num_props += ((e->op_type == NO_OPLOCK) ? 1 : 0);
610 num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0);
611 num_props += (LEVEL_II_OPLOCK_TYPE(e->op_type) ? 1 : 0);
612 num_props += (e->op_type == LEASE_OPLOCK);
614 if ((num_props > 1) && serverid_exists(&e->pid)) {
615 smb_panic("Invalid share mode entry");
617 return (num_props != 0);
621 * See if we need to remove a lease being referred to by a
622 * share mode that is being marked stale or deleted.
625 static void remove_share_mode_lease(struct share_mode_data *d,
626 struct share_mode_entry *e)
628 struct GUID client_guid;
629 struct smb2_lease_key lease_key;
634 op_type = e->op_type;
635 e->op_type = NO_OPLOCK;
639 if (op_type != LEASE_OPLOCK) {
644 * This used to reference a lease. If there's no other one referencing
648 lease_idx = e->lease_idx;
649 e->lease_idx = UINT32_MAX;
651 for (i=0; i<d->num_share_modes; i++) {
652 if (d->share_modes[i].stale) {
655 if (e == &d->share_modes[i]) {
659 if (d->share_modes[i].lease_idx == lease_idx) {
663 if (i < d->num_share_modes) {
671 &d->leases[lease_idx].client_guid,
672 sizeof(client_guid));
673 lease_key = d->leases[lease_idx].lease_key;
676 d->leases[lease_idx] = d->leases[d->num_leases];
679 * We changed the lease array. Fix all references to it.
681 for (i=0; i<d->num_share_modes; i++) {
682 if (d->share_modes[i].lease_idx == d->num_leases) {
683 d->share_modes[i].lease_idx = lease_idx;
684 d->share_modes[i].lease = &d->leases[lease_idx];
691 status = leases_db_del(&client_guid,
695 DEBUG(10, ("%s: leases_db_del returned %s\n", __func__,
701 * In case d->share_modes[i] conflicts with something or otherwise is
702 * being used, we need to make sure the corresponding process still
705 bool share_mode_stale_pid(struct share_mode_data *d, uint32_t idx)
707 struct share_mode_entry *e;
709 if (idx > d->num_share_modes) {
710 DEBUG(1, ("Asking for index %u, only %u around\n",
711 idx, (unsigned)d->num_share_modes));
714 e = &d->share_modes[idx];
721 if (serverid_exists(&e->pid)) {
722 DEBUG(10, ("PID %s (index %u out of %u) still exists\n",
723 procid_str_static(&e->pid), idx,
724 (unsigned)d->num_share_modes));
727 DEBUG(10, ("PID %s (index %u out of %u) does not exist anymore\n",
728 procid_str_static(&e->pid), idx,
729 (unsigned)d->num_share_modes));
733 if (d->num_delete_tokens != 0) {
734 uint32_t i, num_stale;
737 * We cannot have any delete tokens
738 * if there are no valid share modes.
743 for (i=0; i<d->num_share_modes; i++) {
744 if (d->share_modes[i].stale) {
749 if (num_stale == d->num_share_modes) {
751 * No non-stale share mode found
753 TALLOC_FREE(d->delete_tokens);
754 d->num_delete_tokens = 0;
758 remove_share_mode_lease(d, e);
764 void remove_stale_share_mode_entries(struct share_mode_data *d)
769 while (i < d->num_share_modes) {
770 if (d->share_modes[i].stale) {
771 struct share_mode_entry *m = d->share_modes;
772 m[i] = m[d->num_share_modes-1];
773 d->num_share_modes -= 1;
780 bool set_share_mode(struct share_mode_lock *lck, struct files_struct *fsp,
781 uid_t uid, uint64_t mid, uint16_t op_type,
784 struct share_mode_data *d = lck->data;
785 struct share_mode_entry *tmp, *e;
786 struct share_mode_lease *lease = NULL;
788 if (lease_idx == UINT32_MAX) {
790 } else if (lease_idx >= d->num_leases) {
793 lease = &d->leases[lease_idx];
796 tmp = talloc_realloc(d, d->share_modes, struct share_mode_entry,
797 d->num_share_modes+1);
801 d->share_modes = tmp;
802 e = &d->share_modes[d->num_share_modes];
803 d->num_share_modes += 1;
807 e->pid = messaging_server_id(fsp->conn->sconn->msg_ctx);
808 e->share_access = fsp->share_access;
809 e->private_options = fsp->fh->private_options;
810 e->access_mask = fsp->access_mask;
812 e->op_type = op_type;
813 e->lease_idx = lease_idx;
815 e->time.tv_sec = fsp->open_time.tv_sec;
816 e->time.tv_usec = fsp->open_time.tv_usec;
817 e->id = fsp->file_id;
818 e->share_file_id = fsp->fh->gen_id;
819 e->uid = (uint32)uid;
820 e->flags = fsp->posix_open ? SHARE_MODE_FLAG_POSIX_OPEN : 0;
821 e->name_hash = fsp->name_hash;
826 static struct share_mode_entry *find_share_mode_entry(
827 struct share_mode_lock *lck, files_struct *fsp)
829 struct share_mode_data *d = lck->data;
830 struct server_id pid;
833 pid = messaging_server_id(fsp->conn->sconn->msg_ctx);
835 for (i=0; i<d->num_share_modes; i++) {
836 struct share_mode_entry *e = &d->share_modes[i];
838 if (!is_valid_share_mode_entry(e)) {
841 if (!serverid_equal(&pid, &e->pid)) {
844 if (!file_id_equal(&fsp->file_id, &e->id)) {
847 if (fsp->fh->gen_id != e->share_file_id) {
855 /*******************************************************************
856 Del the share mode of a file for this process. Return the number of
858 ********************************************************************/
860 bool del_share_mode(struct share_mode_lock *lck, files_struct *fsp)
862 struct share_mode_entry *e;
864 e = find_share_mode_entry(lck, fsp);
868 remove_share_mode_lease(lck->data, e);
869 *e = lck->data->share_modes[lck->data->num_share_modes-1];
870 lck->data->num_share_modes -= 1;
871 lck->data->modified = True;
875 bool mark_share_mode_disconnected(struct share_mode_lock *lck,
876 struct files_struct *fsp)
878 struct share_mode_entry *e;
880 if (lck->data->num_share_modes != 1) {
884 if (fsp->op == NULL) {
887 if (!fsp->op->global->durable) {
891 e = find_share_mode_entry(lck, fsp);
896 DEBUG(10, ("Marking share mode entry disconnected for durable handle\n"));
898 server_id_set_disconnected(&e->pid);
901 * On reopen the caller needs to check that
902 * the client comes with the correct handle.
904 e->share_file_id = fsp->op->global->open_persistent_id;
906 lck->data->modified = true;
910 /*******************************************************************
911 Remove an oplock mid and mode entry from a share mode.
912 ********************************************************************/
914 bool remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
916 struct share_mode_data *d = lck->data;
917 struct share_mode_entry *e;
919 e = find_share_mode_entry(lck, fsp);
924 remove_share_mode_lease(d, e);
929 /*******************************************************************
930 Downgrade a oplock type from exclusive to level II.
931 ********************************************************************/
933 bool downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
935 struct share_mode_entry *e;
937 e = find_share_mode_entry(lck, fsp);
942 e->op_type = LEVEL_II_OPLOCK;
943 lck->data->modified = True;
947 /****************************************************************************
948 Adds a delete on close token.
949 ****************************************************************************/
951 static bool add_delete_on_close_token(struct share_mode_data *d,
953 const struct security_token *nt_tok,
954 const struct security_unix_token *tok)
956 struct delete_token *tmp, *dtl;
958 tmp = talloc_realloc(d, d->delete_tokens, struct delete_token,
959 d->num_delete_tokens+1);
963 d->delete_tokens = tmp;
964 dtl = &d->delete_tokens[d->num_delete_tokens];
966 dtl->name_hash = name_hash;
967 dtl->delete_nt_token = dup_nt_token(d->delete_tokens, nt_tok);
968 if (dtl->delete_nt_token == NULL) {
971 dtl->delete_token = copy_unix_token(d->delete_tokens, tok);
972 if (dtl->delete_token == NULL) {
975 d->num_delete_tokens += 1;
980 /****************************************************************************
981 Sets the delete on close flag over all share modes on this file.
982 Modify the share mode entry for all files open
983 on this device and inode to tell other smbds we have
984 changed the delete on close flag. This will be noticed
985 in the close code, the last closer will delete the file
987 This makes a copy of any struct security_unix_token into the
988 lck entry. This function is used when the lock is already granted.
989 ****************************************************************************/
991 void set_delete_on_close_lck(files_struct *fsp,
992 struct share_mode_lock *lck,
993 bool delete_on_close,
994 const struct security_token *nt_tok,
995 const struct security_unix_token *tok)
997 struct share_mode_data *d = lck->data;
1001 if (delete_on_close) {
1002 SMB_ASSERT(nt_tok != NULL);
1003 SMB_ASSERT(tok != NULL);
1005 SMB_ASSERT(nt_tok == NULL);
1006 SMB_ASSERT(tok == NULL);
1009 for (i=0; i<d->num_delete_tokens; i++) {
1010 struct delete_token *dt = &d->delete_tokens[i];
1011 if (dt->name_hash == fsp->name_hash) {
1013 if (delete_on_close == false) {
1014 /* Delete this entry. */
1015 TALLOC_FREE(dt->delete_nt_token);
1016 TALLOC_FREE(dt->delete_token);
1017 *dt = d->delete_tokens[
1018 d->num_delete_tokens-1];
1019 d->num_delete_tokens -= 1;
1021 /* Replace this token with the
1023 TALLOC_FREE(dt->delete_nt_token);
1024 dt->delete_nt_token = dup_nt_token(dt, nt_tok);
1025 SMB_ASSERT(dt->delete_nt_token != NULL);
1026 TALLOC_FREE(dt->delete_token);
1027 dt->delete_token = copy_unix_token(dt, tok);
1028 SMB_ASSERT(dt->delete_token != NULL);
1034 if (!delete_on_close) {
1035 /* Nothing to delete - not found. */
1039 ret = add_delete_on_close_token(lck->data, fsp->name_hash, nt_tok, tok);
1043 bool set_delete_on_close(files_struct *fsp, bool delete_on_close,
1044 const struct security_token *nt_tok,
1045 const struct security_unix_token *tok)
1047 struct share_mode_lock *lck;
1049 DEBUG(10,("set_delete_on_close: %s delete on close flag for "
1051 delete_on_close ? "Adding" : "Removing", fsp_fnum_dbg(fsp),
1054 lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
1059 if (delete_on_close) {
1060 set_delete_on_close_lck(fsp, lck, true,
1064 set_delete_on_close_lck(fsp, lck, false,
1069 if (fsp->is_directory) {
1070 SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name));
1071 send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
1072 fsp->fsp_name->base_name);
1077 fsp->delete_on_close = delete_on_close;
1082 static struct delete_token *find_delete_on_close_token(
1083 struct share_mode_data *d, uint32_t name_hash)
1087 DEBUG(10, ("find_delete_on_close_token: name_hash = 0x%x\n",
1088 (unsigned int)name_hash));
1090 for (i=0; i<d->num_delete_tokens; i++) {
1091 struct delete_token *dt = &d->delete_tokens[i];
1093 DEBUG(10, ("find__delete_on_close_token: dt->name_hash = 0x%x\n",
1094 (unsigned int)dt->name_hash ));
1095 if (dt->name_hash == name_hash) {
1102 /****************************************************************************
1103 Return the NT token and UNIX token if there's a match. Return true if
1104 found, false if not.
1105 ****************************************************************************/
1107 bool get_delete_on_close_token(struct share_mode_lock *lck,
1109 const struct security_token **pp_nt_tok,
1110 const struct security_unix_token **pp_tok)
1112 struct delete_token *dt;
1114 dt = find_delete_on_close_token(lck->data, name_hash);
1118 *pp_nt_tok = dt->delete_nt_token;
1119 *pp_tok = dt->delete_token;
1123 bool is_delete_on_close_set(struct share_mode_lock *lck, uint32_t name_hash)
1125 return find_delete_on_close_token(lck->data, name_hash) != NULL;
1128 bool set_sticky_write_time(struct file_id fileid, struct timespec write_time)
1130 struct share_mode_lock *lck;
1132 DEBUG(5,("set_sticky_write_time: %s id=%s\n",
1133 timestring(talloc_tos(),
1134 convert_timespec_to_time_t(write_time)),
1135 file_id_string_tos(&fileid)));
1137 lck = get_existing_share_mode_lock(talloc_tos(), fileid);
1142 if (timespec_compare(&lck->data->changed_write_time, &write_time) != 0) {
1143 lck->data->modified = True;
1144 lck->data->changed_write_time = write_time;
1151 bool set_write_time(struct file_id fileid, struct timespec write_time)
1153 struct share_mode_lock *lck;
1155 DEBUG(5,("set_write_time: %s id=%s\n",
1156 timestring(talloc_tos(),
1157 convert_timespec_to_time_t(write_time)),
1158 file_id_string_tos(&fileid)));
1160 lck = get_existing_share_mode_lock(talloc_tos(), fileid);
1165 if (timespec_compare(&lck->data->old_write_time, &write_time) != 0) {
1166 lck->data->modified = True;
1167 lck->data->old_write_time = write_time;
1174 struct timespec get_share_mode_write_time(struct share_mode_lock *lck)
1176 struct share_mode_data *d = lck->data;
1178 if (!null_timespec(d->changed_write_time)) {
1179 return d->changed_write_time;
1181 return d->old_write_time;