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 "lib/util/server_id.h"
41 #include "locking/proto.h"
42 #include "smbd/globals.h"
43 #include "dbwrap/dbwrap.h"
44 #include "dbwrap/dbwrap_open.h"
45 #include "../libcli/security/security.h"
49 #include "../librpc/gen_ndr/ndr_open_files.h"
50 #include "librpc/gen_ndr/ndr_file_id.h"
51 #include "locking/leases_db.h"
54 #define DBGC_CLASS DBGC_LOCKING
56 #define NO_LOCKING_COUNT (-1)
58 /****************************************************************************
60 ****************************************************************************/
62 const char *lock_type_name(enum brl_type lock_type)
69 case PENDING_READ_LOCK:
70 return "PENDING_READ";
71 case PENDING_WRITE_LOCK:
72 return "PENDING_WRITE";
78 const char *lock_flav_name(enum brl_flavour lock_flav)
80 return (lock_flav == WINDOWS_LOCK) ? "WINDOWS_LOCK" : "POSIX_LOCK";
83 /****************************************************************************
84 Utility function called to see if a file region is locked.
85 Called in the read/write codepath.
86 ****************************************************************************/
88 void init_strict_lock_struct(files_struct *fsp,
92 enum brl_type lock_type,
93 struct lock_struct *plock)
95 SMB_ASSERT(lock_type == READ_LOCK || lock_type == WRITE_LOCK);
97 plock->context.smblctx = smblctx;
98 plock->context.tid = fsp->conn->cnum;
99 plock->context.pid = messaging_server_id(fsp->conn->sconn->msg_ctx);
100 plock->start = start;
102 plock->fnum = fsp->fnum;
103 plock->lock_type = lock_type;
104 plock->lock_flav = lp_posix_cifsu_locktype(fsp);
107 bool strict_lock_check_default(files_struct *fsp, struct lock_struct *plock)
109 struct byte_range_lock *br_lck;
110 int strict_locking = lp_strict_locking(fsp->conn->params);
113 if (plock->size == 0) {
117 if (!lp_locking(fsp->conn->params) || !strict_locking) {
121 if (strict_locking == Auto) {
122 uint32_t lease_type = fsp_lease_type(fsp);
124 if ((lease_type & SMB2_LEASE_READ) &&
125 (plock->lock_type == READ_LOCK))
127 DBG_DEBUG("optimisation - read lease on file %s\n",
132 if ((lease_type & SMB2_LEASE_WRITE) &&
133 (plock->lock_type == WRITE_LOCK))
135 DBG_DEBUG("optimisation - write lease on file %s\n",
141 br_lck = brl_get_locks_readonly(fsp);
145 ret = brl_locktest(br_lck, plock);
149 * We got a lock conflict. Retry with rw locks to enable
150 * autocleanup. This is the slow path anyway.
152 br_lck = brl_get_locks(talloc_tos(), fsp);
153 if (br_lck == NULL) {
156 ret = brl_locktest(br_lck, plock);
160 DEBUG(10, ("strict_lock_default: flavour = %s brl start=%ju "
161 "len=%ju %s for fnum %ju file %s\n",
162 lock_flav_name(plock->lock_flav),
163 (uintmax_t)plock->start, (uintmax_t)plock->size,
164 ret ? "unlocked" : "locked",
165 (uintmax_t)plock->fnum, fsp_str_dbg(fsp)));
170 /****************************************************************************
171 Find out if a lock could be granted - return who is blocking us if we can't.
172 ****************************************************************************/
174 NTSTATUS query_lock(files_struct *fsp,
178 enum brl_type *plock_type,
179 enum brl_flavour lock_flav)
181 struct byte_range_lock *br_lck = NULL;
183 if (!fsp->can_lock) {
184 return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
187 if (!lp_locking(fsp->conn->params)) {
191 br_lck = brl_get_locks_readonly(fsp);
193 return NT_STATUS_NO_MEMORY;
196 return brl_lockquery(br_lck,
198 messaging_server_id(fsp->conn->sconn->msg_ctx),
205 static void increment_current_lock_count(files_struct *fsp,
206 enum brl_flavour lock_flav)
208 if (lock_flav == WINDOWS_LOCK &&
209 fsp->current_lock_count != NO_LOCKING_COUNT) {
210 /* blocking ie. pending, locks also count here,
211 * as this is an efficiency counter to avoid checking
212 * the lock db. on close. JRA. */
214 fsp->current_lock_count++;
216 /* Notice that this has had a POSIX lock request.
217 * We can't count locks after this so forget them.
219 fsp->current_lock_count = NO_LOCKING_COUNT;
223 static void decrement_current_lock_count(files_struct *fsp,
224 enum brl_flavour lock_flav)
226 if (lock_flav == WINDOWS_LOCK &&
227 fsp->current_lock_count != NO_LOCKING_COUNT) {
228 SMB_ASSERT(fsp->current_lock_count > 0);
229 fsp->current_lock_count--;
233 /****************************************************************************
234 Utility function called by locking requests.
235 ****************************************************************************/
237 struct byte_range_lock *do_lock(struct messaging_context *msg_ctx,
242 enum brl_type lock_type,
243 enum brl_flavour lock_flav,
246 struct server_id *pblocker_pid,
249 struct byte_range_lock *br_lck = NULL;
250 struct server_id blocker_pid;
251 uint64_t blocker_smblctx;
253 /* silently return ok on print files as we don't do locking there */
254 if (fsp->print_file) {
255 *perr = NT_STATUS_OK;
259 if (!fsp->can_lock) {
260 *perr = fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
264 if (!lp_locking(fsp->conn->params)) {
265 *perr = NT_STATUS_OK;
269 /* NOTE! 0 byte long ranges ARE allowed and should be stored */
271 DEBUG(10,("do_lock: lock flavour %s lock type %s start=%ju len=%ju "
272 "blocking_lock=%s requested for %s file %s\n",
273 lock_flav_name(lock_flav), lock_type_name(lock_type),
274 (uintmax_t)offset, (uintmax_t)count, blocking_lock ? "true" :
275 "false", fsp_fnum_dbg(fsp), fsp_str_dbg(fsp)));
277 br_lck = brl_get_locks(talloc_tos(), fsp);
279 *perr = NT_STATUS_NO_MEMORY;
283 *perr = brl_lock(msg_ctx,
286 messaging_server_id(fsp->conn->sconn->msg_ctx),
295 if (psmblctx != NULL) {
296 *psmblctx = blocker_smblctx;
298 if (pblocker_pid != NULL) {
299 *pblocker_pid = blocker_pid;
302 DEBUG(10, ("do_lock: returning status=%s\n", nt_errstr(*perr)));
304 increment_current_lock_count(fsp, lock_flav);
308 /****************************************************************************
309 Utility function called by unlocking requests.
310 ****************************************************************************/
312 NTSTATUS do_unlock(struct messaging_context *msg_ctx,
317 enum brl_flavour lock_flav)
320 struct byte_range_lock *br_lck = NULL;
322 if (!fsp->can_lock) {
323 return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
326 if (!lp_locking(fsp->conn->params)) {
330 DBG_DEBUG("unlock start=%"PRIu64" len=%"PRIu64" requested for %s file "
337 br_lck = brl_get_locks(talloc_tos(), fsp);
339 return NT_STATUS_NO_MEMORY;
342 ok = brl_unlock(msg_ctx,
345 messaging_server_id(fsp->conn->sconn->msg_ctx),
353 DEBUG(10,("do_unlock: returning ERRlock.\n" ));
354 return NT_STATUS_RANGE_NOT_LOCKED;
357 decrement_current_lock_count(fsp, lock_flav);
361 /****************************************************************************
362 Cancel any pending blocked locks.
363 ****************************************************************************/
365 NTSTATUS do_lock_cancel(files_struct *fsp,
369 enum brl_flavour lock_flav)
372 struct byte_range_lock *br_lck = NULL;
374 if (!fsp->can_lock) {
375 return fsp->is_directory ?
376 NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
379 if (!lp_locking(fsp->conn->params)) {
380 return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
383 DEBUG(10, ("do_lock_cancel: cancel start=%ju len=%ju requested for "
384 "%s file %s\n", (uintmax_t)offset, (uintmax_t)count,
385 fsp_fnum_dbg(fsp), fsp_str_dbg(fsp)));
387 br_lck = brl_get_locks(talloc_tos(), fsp);
389 return NT_STATUS_NO_MEMORY;
392 ok = brl_lock_cancel(br_lck,
394 messaging_server_id(fsp->conn->sconn->msg_ctx),
402 DEBUG(10,("do_lock_cancel: returning ERRcancelviolation.\n" ));
403 return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
406 decrement_current_lock_count(fsp, lock_flav);
410 /****************************************************************************
411 Remove any locks on this fd. Called from file_close().
412 ****************************************************************************/
414 void locking_close_file(struct messaging_context *msg_ctx,
416 enum file_close_type close_type)
418 struct byte_range_lock *br_lck;
420 if (!lp_locking(fsp->conn->params)) {
424 /* If we have no outstanding locks or pending
425 * locks then we don't need to look in the lock db.
428 if (fsp->current_lock_count == 0) {
432 br_lck = brl_get_locks(talloc_tos(),fsp);
435 cancel_pending_lock_requests_by_fid(fsp, br_lck, close_type);
436 brl_close_fnum(msg_ctx, br_lck);
441 /*******************************************************************
442 Print out a share mode.
443 ********************************************************************/
445 char *share_mode_str(TALLOC_CTX *ctx, int num,
446 const struct file_id *id,
447 const struct share_mode_entry *e)
449 struct server_id_buf tmp;
451 return talloc_asprintf(ctx, "share_mode_entry[%d]: "
452 "pid = %s, share_access = 0x%x, private_options = 0x%x, "
453 "access_mask = 0x%x, mid = 0x%llx, type= 0x%x, gen_id = %llu, "
454 "uid = %u, flags = %u, file_id %s, name_hash = 0x%x",
456 server_id_str_buf(e->pid, &tmp),
457 e->share_access, e->private_options,
458 e->access_mask, (unsigned long long)e->op_mid,
459 e->op_type, (unsigned long long)e->share_file_id,
460 (unsigned int)e->uid, (unsigned int)e->flags,
461 file_id_string_tos(id),
462 (unsigned int)e->name_hash);
465 /*******************************************************************
466 Fetch a share mode where we know one MUST exist. This call reference
467 counts it internally to allow for nested lock fetches.
468 ********************************************************************/
470 struct share_mode_lock *get_existing_share_mode_lock(TALLOC_CTX *mem_ctx,
471 const struct file_id id)
473 return get_share_mode_lock(mem_ctx, id, NULL, NULL, NULL);
476 static bool rename_lease_fn(struct share_mode_lock *lck,
477 struct share_mode_entry *e,
480 struct share_mode_data *d = lck->data;
483 status = leases_db_rename(&e->client_guid,
490 if (!NT_STATUS_IS_OK(status)) {
491 /* Any error recovery possible here ? */
492 DBG_WARNING("Failed to rename lease key for "
493 "renamed file %s:%s. %s\n",
502 /*******************************************************************
503 Sets the service name and filename for rename.
504 At this point we emit "file renamed" messages to all
505 process id's that have this file open.
506 Based on an initial code idea from SATOH Fumiyasu <fumiya@samba.gr.jp>
507 ********************************************************************/
509 bool rename_share_filename(struct messaging_context *msg_ctx,
510 struct share_mode_lock *lck,
512 const char *servicepath,
513 uint32_t orig_name_hash,
514 uint32_t new_name_hash,
515 const struct smb_filename *smb_fname_dst)
517 struct share_mode_data *d = lck->data;
518 struct file_rename_message msg = {
520 .servicepath = servicepath,
521 .base_name = smb_fname_dst->base_name,
522 .stream_name = smb_fname_dst->stream_name,
525 struct server_id self_pid = messaging_server_id(msg_ctx);
528 DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n",
529 servicepath, smb_fname_dst->base_name));
532 * rename_internal_fsp() and rename_internals() add './' to
533 * head of newname if newname does not contain a '/'.
536 if (strncmp(msg.base_name, "./", 2) == 0) {
540 d->servicepath = talloc_strdup(d, msg.servicepath);
541 d->base_name = talloc_strdup(d, msg.base_name);
542 d->stream_name = talloc_strdup(d, msg.stream_name);
543 if ((d->servicepath == NULL) ||
544 (d->base_name == NULL) ||
545 ((msg.stream_name != NULL) && (d->stream_name == NULL))) {
546 DBG_WARNING("talloc failed\n");
551 /* Send the messages. */
552 for (i=0; i<d->num_share_modes; i++) {
553 struct share_mode_entry *se = &d->share_modes[i];
555 enum ndr_err_code ndr_err;
557 if (!is_valid_share_mode_entry(se)) {
561 /* If this is a hardlink to the inode
562 with a different name, skip this. */
563 if (se->name_hash != orig_name_hash) {
567 se->name_hash = new_name_hash;
569 /* But not to ourselves... */
570 if (serverid_equal(&se->pid, &self_pid)) {
574 if (share_mode_stale_pid(d, i)) {
578 msg.share_file_id = se->share_file_id;
580 ndr_err = ndr_push_struct_blob(
584 (ndr_push_flags_fn_t)ndr_push_file_rename_message);
585 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
586 DBG_DEBUG("ndr_push_file_rename_message failed: %s\n",
587 ndr_errstr(ndr_err));
590 if (DEBUGLEVEL >= 10) {
591 struct server_id_buf tmp;
592 DBG_DEBUG("sending rename message to %s\n",
593 server_id_str_buf(se->pid, &tmp));
594 NDR_PRINT_DEBUG(file_rename_message, &msg);
597 messaging_send(msg_ctx, se->pid, MSG_SMB_FILE_RENAME, &blob);
599 TALLOC_FREE(blob.data);
602 ok = share_mode_forall_leases(lck, rename_lease_fn, NULL);
605 * Ignore error here. Not sure what to do..
607 DBG_WARNING("share_mode_forall_leases failed\n");
613 void get_file_infos(struct file_id id,
615 bool *delete_on_close,
616 struct timespec *write_time)
618 struct share_mode_lock *lck;
620 if (delete_on_close) {
621 *delete_on_close = false;
625 ZERO_STRUCTP(write_time);
628 if (!(lck = fetch_share_mode_unlocked(talloc_tos(), id))) {
632 if (delete_on_close) {
633 *delete_on_close = is_delete_on_close_set(lck, name_hash);
637 *write_time = get_share_mode_write_time(lck);
643 bool is_valid_share_mode_entry(const struct share_mode_entry *e)
651 num_props += ((e->op_type == NO_OPLOCK) ? 1 : 0);
652 num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0);
653 num_props += (LEVEL_II_OPLOCK_TYPE(e->op_type) ? 1 : 0);
654 num_props += (e->op_type == LEASE_OPLOCK);
656 if ((num_props > 1) && serverid_exists(&e->pid)) {
657 smb_panic("Invalid share mode entry");
659 return (num_props != 0);
663 * See if we need to remove a lease being referred to by a
664 * share mode that is being marked stale or deleted.
667 static void remove_share_mode_lease(struct share_mode_data *d,
668 struct share_mode_entry *e)
673 op_type = e->op_type;
674 e->op_type = NO_OPLOCK;
678 if (op_type != LEASE_OPLOCK) {
683 * This used to reference a lease. If there's no other one referencing
687 for (i=0; i<d->num_share_modes; i++) {
688 struct share_mode_entry *e2 = &d->share_modes[i];
697 if (smb2_lease_equal(&e->client_guid,
704 if (i < d->num_share_modes) {
714 status = leases_db_del(&e->client_guid,
718 DEBUG(10, ("%s: leases_db_del returned %s\n", __func__,
724 * In case d->share_modes[i] conflicts with something or otherwise is
725 * being used, we need to make sure the corresponding process still
728 bool share_mode_stale_pid(struct share_mode_data *d, uint32_t idx)
730 struct server_id_buf tmp;
731 struct share_mode_entry *e;
733 if (idx > d->num_share_modes) {
734 DBG_WARNING("Asking for index %"PRIu32", "
735 "only %"PRIu32" around\n",
740 e = &d->share_modes[idx];
747 if (serverid_exists(&e->pid)) {
748 DBG_DEBUG("PID %s (index %"PRIu32" out of %"PRIu32") "
750 server_id_str_buf(e->pid, &tmp),
755 DBG_DEBUG("PID %s (index %"PRIu32" out of %"PRIu32") "
756 "does not exist anymore\n",
757 server_id_str_buf(e->pid, &tmp),
763 if (d->num_delete_tokens != 0) {
766 for (i=0; i<d->num_share_modes; i++) {
767 bool valid = !d->share_modes[i].stale;
773 if (i == d->num_share_modes) {
775 * No valid (non-stale) share mode found, all
776 * who might have set the delete token are
779 TALLOC_FREE(d->delete_tokens);
780 d->num_delete_tokens = 0;
784 remove_share_mode_lease(d, e);
790 void remove_stale_share_mode_entries(struct share_mode_data *d)
795 while (i < d->num_share_modes) {
796 if (d->share_modes[i].stale) {
797 struct share_mode_entry *m = d->share_modes;
798 m[i] = m[d->num_share_modes-1];
799 d->num_share_modes -= 1;
806 bool set_share_mode(struct share_mode_lock *lck,
807 struct files_struct *fsp,
811 const struct GUID *client_guid,
812 const struct smb2_lease_key *lease_key)
814 struct share_mode_data *d = lck->data;
815 struct share_mode_entry *tmp, *e;
817 tmp = talloc_realloc(d, d->share_modes, struct share_mode_entry,
818 d->num_share_modes+1);
822 d->share_modes = tmp;
823 e = &d->share_modes[d->num_share_modes];
824 d->num_share_modes += 1;
828 e->pid = messaging_server_id(fsp->conn->sconn->msg_ctx);
829 e->share_access = fsp->share_access;
830 e->private_options = fsp->fh->private_options;
831 e->access_mask = fsp->access_mask;
833 e->op_type = op_type;
835 if (op_type == LEASE_OPLOCK) {
836 e->client_guid = *client_guid;
837 e->lease_key = *lease_key;
840 e->time.tv_sec = fsp->open_time.tv_sec;
841 e->time.tv_usec = fsp->open_time.tv_usec;
842 e->share_file_id = fsp->fh->gen_id;
843 e->uid = (uint32_t)uid;
844 e->flags = (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) ?
845 SHARE_MODE_FLAG_POSIX_OPEN : 0;
846 e->name_hash = fsp->name_hash;
851 struct share_mode_entry *find_share_mode_entry(
852 struct share_mode_lock *lck, files_struct *fsp)
854 struct share_mode_data *d = lck->data;
855 struct server_id pid;
858 pid = messaging_server_id(fsp->conn->sconn->msg_ctx);
860 for (i=0; i<d->num_share_modes; i++) {
861 struct share_mode_entry *e = &d->share_modes[i];
863 if (!is_valid_share_mode_entry(e)) {
866 if (!serverid_equal(&pid, &e->pid)) {
869 if (fsp->fh->gen_id != e->share_file_id) {
877 /*******************************************************************
878 Del the share mode of a file for this process.
879 ********************************************************************/
881 bool del_share_mode(struct share_mode_lock *lck, files_struct *fsp)
883 struct share_mode_entry *e;
885 e = find_share_mode_entry(lck, fsp);
889 remove_share_mode_lease(lck->data, e);
890 *e = lck->data->share_modes[lck->data->num_share_modes-1];
891 lck->data->num_share_modes -= 1;
892 lck->data->modified = True;
896 bool mark_share_mode_disconnected(struct share_mode_lock *lck,
897 struct files_struct *fsp)
899 struct share_mode_entry *e;
901 if (lck->data->num_share_modes != 1) {
905 if (fsp->op == NULL) {
908 if (!fsp->op->global->durable) {
912 e = find_share_mode_entry(lck, fsp);
917 DEBUG(10, ("Marking share mode entry disconnected for durable handle\n"));
919 server_id_set_disconnected(&e->pid);
922 * On reopen the caller needs to check that
923 * the client comes with the correct handle.
925 e->share_file_id = fsp->op->global->open_persistent_id;
927 lck->data->modified = true;
931 /*******************************************************************
932 Remove an oplock mid and mode entry from a share mode.
933 ********************************************************************/
935 bool remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
937 struct share_mode_data *d = lck->data;
938 struct share_mode_entry *e;
940 e = find_share_mode_entry(lck, fsp);
945 remove_share_mode_lease(d, e);
950 /*******************************************************************
951 Downgrade a oplock type from exclusive to level II.
952 ********************************************************************/
954 bool downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
956 struct share_mode_entry *e;
958 e = find_share_mode_entry(lck, fsp);
963 e->op_type = LEVEL_II_OPLOCK;
964 lck->data->modified = True;
968 /****************************************************************************
969 Adds a delete on close token.
970 ****************************************************************************/
972 static bool add_delete_on_close_token(struct share_mode_data *d,
974 const struct security_token *nt_tok,
975 const struct security_unix_token *tok)
977 struct delete_token *tmp, *dtl;
979 tmp = talloc_realloc(d, d->delete_tokens, struct delete_token,
980 d->num_delete_tokens+1);
984 d->delete_tokens = tmp;
985 dtl = &d->delete_tokens[d->num_delete_tokens];
987 dtl->name_hash = name_hash;
988 dtl->delete_nt_token = dup_nt_token(d->delete_tokens, nt_tok);
989 if (dtl->delete_nt_token == NULL) {
992 dtl->delete_token = copy_unix_token(d->delete_tokens, tok);
993 if (dtl->delete_token == NULL) {
996 d->num_delete_tokens += 1;
1001 void reset_delete_on_close_lck(files_struct *fsp,
1002 struct share_mode_lock *lck)
1004 struct share_mode_data *d = lck->data;
1007 for (i=0; i<d->num_delete_tokens; i++) {
1008 struct delete_token *dt = &d->delete_tokens[i];
1010 if (dt->name_hash == fsp->name_hash) {
1013 /* Delete this entry. */
1014 TALLOC_FREE(dt->delete_nt_token);
1015 TALLOC_FREE(dt->delete_token);
1016 *dt = d->delete_tokens[d->num_delete_tokens-1];
1017 d->num_delete_tokens -= 1;
1022 /****************************************************************************
1023 Sets the delete on close flag over all share modes on this file.
1024 Modify the share mode entry for all files open
1025 on this device and inode to tell other smbds we have
1026 changed the delete on close flag. This will be noticed
1027 in the close code, the last closer will delete the file
1029 This makes a copy of any struct security_unix_token into the
1030 lck entry. This function is used when the lock is already granted.
1031 ****************************************************************************/
1033 void set_delete_on_close_lck(files_struct *fsp,
1034 struct share_mode_lock *lck,
1035 const struct security_token *nt_tok,
1036 const struct security_unix_token *tok)
1038 struct messaging_context *msg_ctx = fsp->conn->sconn->msg_ctx;
1039 struct share_mode_data *d = lck->data;
1042 DATA_BLOB fid_blob = {};
1043 enum ndr_err_code ndr_err;
1045 SMB_ASSERT(nt_tok != NULL);
1046 SMB_ASSERT(tok != NULL);
1048 for (i=0; i<d->num_delete_tokens; i++) {
1049 struct delete_token *dt = &d->delete_tokens[i];
1050 if (dt->name_hash == fsp->name_hash) {
1053 /* Replace this token with the given tok. */
1054 TALLOC_FREE(dt->delete_nt_token);
1055 dt->delete_nt_token = dup_nt_token(dt, nt_tok);
1056 SMB_ASSERT(dt->delete_nt_token != NULL);
1057 TALLOC_FREE(dt->delete_token);
1058 dt->delete_token = copy_unix_token(dt, tok);
1059 SMB_ASSERT(dt->delete_token != NULL);
1065 ret = add_delete_on_close_token(lck->data, fsp->name_hash, nt_tok, tok);
1068 ndr_err = ndr_push_struct_blob(&fid_blob, talloc_tos(), &fsp->file_id,
1069 (ndr_push_flags_fn_t)ndr_push_file_id);
1070 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1071 DEBUG(10, ("ndr_push_file_id failed: %s\n",
1072 ndr_errstr(ndr_err)));
1075 for (i=0; i<d->num_share_modes; i++) {
1076 struct share_mode_entry *e = &d->share_modes[i];
1079 status = messaging_send(
1080 msg_ctx, e->pid, MSG_SMB_NOTIFY_CANCEL_DELETED,
1083 if (!NT_STATUS_IS_OK(status)) {
1084 struct server_id_buf tmp;
1085 DEBUG(10, ("%s: messaging_send to %s returned %s\n",
1086 __func__, server_id_str_buf(e->pid, &tmp),
1087 nt_errstr(status)));
1091 TALLOC_FREE(fid_blob.data);
1094 bool set_delete_on_close(files_struct *fsp, bool delete_on_close,
1095 const struct security_token *nt_tok,
1096 const struct security_unix_token *tok)
1098 struct share_mode_lock *lck;
1100 DEBUG(10,("set_delete_on_close: %s delete on close flag for "
1102 delete_on_close ? "Adding" : "Removing", fsp_fnum_dbg(fsp),
1105 lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
1110 if (delete_on_close) {
1111 set_delete_on_close_lck(fsp, lck, nt_tok, tok);
1113 reset_delete_on_close_lck(fsp, lck);
1116 if (fsp->is_directory) {
1117 SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name));
1118 send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
1119 fsp->fsp_name->base_name);
1124 fsp->delete_on_close = delete_on_close;
1129 static struct delete_token *find_delete_on_close_token(
1130 struct share_mode_data *d, uint32_t name_hash)
1134 DEBUG(10, ("find_delete_on_close_token: name_hash = 0x%x\n",
1135 (unsigned int)name_hash));
1137 for (i=0; i<d->num_delete_tokens; i++) {
1138 struct delete_token *dt = &d->delete_tokens[i];
1140 DEBUG(10, ("find__delete_on_close_token: dt->name_hash = 0x%x\n",
1141 (unsigned int)dt->name_hash ));
1142 if (dt->name_hash == name_hash) {
1149 /****************************************************************************
1150 Return the NT token and UNIX token if there's a match. Return true if
1151 found, false if not.
1152 ****************************************************************************/
1154 bool get_delete_on_close_token(struct share_mode_lock *lck,
1156 const struct security_token **pp_nt_tok,
1157 const struct security_unix_token **pp_tok)
1159 struct delete_token *dt;
1161 dt = find_delete_on_close_token(lck->data, name_hash);
1165 *pp_nt_tok = dt->delete_nt_token;
1166 *pp_tok = dt->delete_token;
1170 bool is_delete_on_close_set(struct share_mode_lock *lck, uint32_t name_hash)
1172 return find_delete_on_close_token(lck->data, name_hash) != NULL;
1175 bool set_sticky_write_time(struct file_id fileid, struct timespec write_time)
1177 struct share_mode_lock *lck;
1179 DEBUG(5,("set_sticky_write_time: %s id=%s\n",
1180 timestring(talloc_tos(),
1181 convert_timespec_to_time_t(write_time)),
1182 file_id_string_tos(&fileid)));
1184 lck = get_existing_share_mode_lock(talloc_tos(), fileid);
1189 if (timespec_compare(&lck->data->changed_write_time, &write_time) != 0) {
1190 lck->data->modified = True;
1191 lck->data->changed_write_time = write_time;
1198 bool set_write_time(struct file_id fileid, struct timespec write_time)
1200 struct share_mode_lock *lck;
1202 DEBUG(5,("set_write_time: %s id=%s\n",
1203 timestring(talloc_tos(),
1204 convert_timespec_to_time_t(write_time)),
1205 file_id_string_tos(&fileid)));
1207 lck = get_existing_share_mode_lock(talloc_tos(), fileid);
1212 if (timespec_compare(&lck->data->old_write_time, &write_time) != 0) {
1213 lck->data->modified = True;
1214 lck->data->old_write_time = write_time;
1221 struct timespec get_share_mode_write_time(struct share_mode_lock *lck)
1223 struct share_mode_data *d = lck->data;
1225 if (!null_timespec(d->changed_write_time)) {
1226 return d->changed_write_time;
1228 return d->old_write_time;
1231 bool file_has_open_streams(files_struct *fsp)
1233 struct share_mode_lock *lock = NULL;
1234 struct share_mode_data *d = NULL;
1237 lock = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
1243 for (i = 0; i < d->num_share_modes; i++) {
1244 struct share_mode_entry *e = &d->share_modes[i];
1246 if (share_mode_stale_pid(d, i)) {
1250 if (e->private_options &
1251 NTCREATEX_OPTIONS_PRIVATE_STREAM_BASEOPEN)
1263 * Walk share mode entries, looking at every lease only once
1266 bool share_mode_forall_leases(
1267 struct share_mode_lock *lck,
1268 bool (*fn)(struct share_mode_lock *lck,
1269 struct share_mode_entry *e,
1270 void *private_data),
1273 struct share_mode_data *d = lck->data;
1274 uint32_t *leases = NULL;
1275 uint32_t num_leases = 0;
1278 leases = talloc_array(talloc_tos(), uint32_t, d->num_share_modes);
1279 if (leases == NULL) {
1283 for (i=0; i<d->num_share_modes; i++) {
1284 struct share_mode_entry *e = &d->share_modes[i];
1288 ok = is_valid_share_mode_entry(e);
1293 if (e->op_type != LEASE_OPLOCK) {
1298 * See if we have already seen "e"'s lease. This is
1299 * O(n^2). If we sort "leases", we can get this down
1303 for (j=0; j<num_leases; j++) {
1304 uint32_t idx = leases[j];
1305 struct share_mode_entry *l = &d->share_modes[idx];
1307 if (smb2_lease_equal(&e->client_guid,
1314 if (j < num_leases) {
1316 * Don't look at "e"'s lease, we've already
1322 stop = fn(lck, e, private_data);
1324 TALLOC_FREE(leases);
1328 leases[num_leases] = i;
1332 TALLOC_FREE(leases);