smbd: reject FILE_ATTRIBUTE_TEMPORARY on directories
[Samba.git] / source3 / locking / locking.c
blobbefdc10f369baa09ffbd46c2b9a38ff7795c903c
1 /*
2 Unix SMB/CIFS implementation.
3 Locking functions
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/>.
21 Revision History:
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
30 support.
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.
38 #include "includes.h"
39 #include "lib/util/time_basic.h"
40 #include "system/filesys.h"
41 #include "lib/util/server_id.h"
42 #include "share_mode_lock.h"
43 #include "share_mode_lock_private.h"
44 #include "locking/proto.h"
45 #include "smbd/globals.h"
46 #include "dbwrap/dbwrap.h"
47 #include "dbwrap/dbwrap_open.h"
48 #include "../libcli/security/security.h"
49 #include "serverid.h"
50 #include "messages.h"
51 #include "util_tdb.h"
52 #include "../librpc/gen_ndr/ndr_open_files.h"
53 #include "librpc/gen_ndr/ndr_file_id.h"
54 #include "librpc/gen_ndr/ndr_leases_db.h"
55 #include "locking/leases_db.h"
57 #undef DBGC_CLASS
58 #define DBGC_CLASS DBGC_LOCKING
60 #define NO_LOCKING_COUNT (-1)
62 /****************************************************************************
63 Debugging aids :-).
64 ****************************************************************************/
66 const char *lock_type_name(enum brl_type lock_type)
68 switch (lock_type) {
69 case READ_LOCK:
70 return "READ";
71 case WRITE_LOCK:
72 return "WRITE";
73 default:
74 return "other";
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,
89 uint64_t smblctx,
90 br_off start,
91 br_off size,
92 enum brl_type lock_type,
93 enum brl_flavour lock_flav,
94 struct lock_struct *plock)
96 SMB_ASSERT(lock_type == READ_LOCK || lock_type == WRITE_LOCK);
98 plock->context.smblctx = smblctx;
99 plock->context.tid = fsp->conn->cnum;
100 plock->context.pid = messaging_server_id(fsp->conn->sconn->msg_ctx);
101 plock->start = start;
102 plock->size = size;
103 plock->fnum = fsp->fnum;
104 plock->lock_type = lock_type;
105 plock->lock_flav = lp_posix_cifsu_locktype(fsp);
108 bool strict_lock_check_default(files_struct *fsp, struct lock_struct *plock)
110 struct byte_range_lock *br_lck;
111 int strict_locking = lp_strict_locking(fsp->conn->params);
112 bool ret = False;
114 if (plock->size == 0) {
115 return True;
118 if (!lp_locking(fsp->conn->params) || !strict_locking) {
119 return True;
122 if (strict_locking == Auto) {
123 uint32_t lease_type = fsp_lease_type(fsp);
125 if ((lease_type & SMB2_LEASE_READ) &&
126 (plock->lock_type == READ_LOCK))
128 DBG_DEBUG("optimisation - read lease on file %s\n",
129 fsp_str_dbg(fsp));
130 return true;
133 if ((lease_type & SMB2_LEASE_WRITE) &&
134 (plock->lock_type == WRITE_LOCK))
136 DBG_DEBUG("optimisation - write lease on file %s\n",
137 fsp_str_dbg(fsp));
138 return true;
142 br_lck = brl_get_locks_readonly(fsp);
143 if (!br_lck) {
144 return true;
146 ret = brl_locktest(br_lck, plock);
148 if (!ret) {
150 * We got a lock conflict. Retry with rw locks to enable
151 * autocleanup. This is the slow path anyway.
153 br_lck = brl_get_locks(talloc_tos(), fsp);
154 if (br_lck == NULL) {
155 return true;
157 ret = brl_locktest(br_lck, plock);
158 TALLOC_FREE(br_lck);
161 DEBUG(10, ("strict_lock_default: flavour = %s brl start=%ju "
162 "len=%ju %s for fnum %ju file %s\n",
163 lock_flav_name(plock->lock_flav),
164 (uintmax_t)plock->start, (uintmax_t)plock->size,
165 ret ? "unlocked" : "locked",
166 (uintmax_t)plock->fnum, fsp_str_dbg(fsp)));
168 return ret;
171 /****************************************************************************
172 Find out if a lock could be granted - return who is blocking us if we can't.
173 ****************************************************************************/
175 NTSTATUS query_lock(files_struct *fsp,
176 uint64_t *psmblctx,
177 uint64_t *pcount,
178 uint64_t *poffset,
179 enum brl_type *plock_type,
180 enum brl_flavour lock_flav)
182 struct byte_range_lock *br_lck = NULL;
184 if (!fsp->fsp_flags.can_lock) {
185 return fsp->fsp_flags.is_directory ?
186 NT_STATUS_INVALID_DEVICE_REQUEST :
187 NT_STATUS_INVALID_HANDLE;
190 if (!lp_locking(fsp->conn->params)) {
191 return NT_STATUS_OK;
194 br_lck = brl_get_locks_readonly(fsp);
195 if (!br_lck) {
196 return NT_STATUS_NO_MEMORY;
199 return brl_lockquery(br_lck,
200 psmblctx,
201 messaging_server_id(fsp->conn->sconn->msg_ctx),
202 poffset,
203 pcount,
204 plock_type,
205 lock_flav);
208 static void increment_current_lock_count(files_struct *fsp,
209 enum brl_flavour lock_flav)
211 if (lock_flav == WINDOWS_LOCK &&
212 fsp->current_lock_count != NO_LOCKING_COUNT) {
213 /* blocking ie. pending, locks also count here,
214 * as this is an efficiency counter to avoid checking
215 * the lock db. on close. JRA. */
217 fsp->current_lock_count++;
218 } else {
219 /* Notice that this has had a POSIX lock request.
220 * We can't count locks after this so forget them.
222 fsp->current_lock_count = NO_LOCKING_COUNT;
226 static void decrement_current_lock_count(files_struct *fsp,
227 enum brl_flavour lock_flav)
229 if (lock_flav == WINDOWS_LOCK &&
230 fsp->current_lock_count != NO_LOCKING_COUNT) {
231 SMB_ASSERT(fsp->current_lock_count > 0);
232 fsp->current_lock_count--;
236 /****************************************************************************
237 Utility function called by locking requests.
238 ****************************************************************************/
240 struct do_lock_state {
241 struct files_struct *fsp;
242 TALLOC_CTX *req_mem_ctx;
243 const struct GUID *req_guid;
244 uint64_t smblctx;
245 uint64_t count;
246 uint64_t offset;
247 enum brl_type lock_type;
248 enum brl_flavour lock_flav;
250 struct server_id blocker_pid;
251 uint64_t blocker_smblctx;
252 NTSTATUS status;
255 static void do_lock_fn(
256 const uint8_t *buf,
257 size_t buflen,
258 bool *modified_dependent,
259 void *private_data)
261 struct do_lock_state *state = private_data;
262 struct byte_range_lock *br_lck = NULL;
264 br_lck = brl_get_locks_for_locking(talloc_tos(),
265 state->fsp,
266 state->req_mem_ctx,
267 state->req_guid);
268 if (br_lck == NULL) {
269 state->status = NT_STATUS_NO_MEMORY;
270 return;
273 state->status = brl_lock(
274 br_lck,
275 state->smblctx,
276 messaging_server_id(state->fsp->conn->sconn->msg_ctx),
277 state->offset,
278 state->count,
279 state->lock_type,
280 state->lock_flav,
281 &state->blocker_pid,
282 &state->blocker_smblctx);
284 TALLOC_FREE(br_lck);
287 NTSTATUS do_lock(files_struct *fsp,
288 TALLOC_CTX *req_mem_ctx,
289 const struct GUID *req_guid,
290 uint64_t smblctx,
291 uint64_t count,
292 uint64_t offset,
293 enum brl_type lock_type,
294 enum brl_flavour lock_flav,
295 struct server_id *pblocker_pid,
296 uint64_t *psmblctx)
298 struct do_lock_state state = {
299 .fsp = fsp,
300 .req_mem_ctx = req_mem_ctx,
301 .req_guid = req_guid,
302 .smblctx = smblctx,
303 .count = count,
304 .offset = offset,
305 .lock_type = lock_type,
306 .lock_flav = lock_flav,
308 NTSTATUS status;
310 /* silently return ok on print files as we don't do locking there */
311 if (fsp->print_file) {
312 return NT_STATUS_OK;
315 if (!fsp->fsp_flags.can_lock) {
316 if (fsp->fsp_flags.is_directory) {
317 return NT_STATUS_INVALID_DEVICE_REQUEST;
319 return NT_STATUS_INVALID_HANDLE;
322 if (!lp_locking(fsp->conn->params)) {
323 return NT_STATUS_OK;
326 /* NOTE! 0 byte long ranges ARE allowed and should be stored */
328 DBG_DEBUG("lock flavour %s lock type %s start=%"PRIu64" len=%"PRIu64" "
329 "requested for %s file %s\n",
330 lock_flav_name(lock_flav),
331 lock_type_name(lock_type),
332 offset,
333 count,
334 fsp_fnum_dbg(fsp),
335 fsp_str_dbg(fsp));
337 status = share_mode_do_locked(fsp->file_id, do_lock_fn, &state);
338 if (!NT_STATUS_IS_OK(status)) {
339 DBG_DEBUG("share_mode_do_locked returned %s\n",
340 nt_errstr(status));
341 return status;
344 if (psmblctx != NULL) {
345 *psmblctx = state.blocker_smblctx;
347 if (pblocker_pid != NULL) {
348 *pblocker_pid = state.blocker_pid;
351 DBG_DEBUG("returning status=%s\n", nt_errstr(state.status));
353 increment_current_lock_count(fsp, lock_flav);
355 return state.status;
358 /****************************************************************************
359 Utility function called by unlocking requests.
360 ****************************************************************************/
362 NTSTATUS do_unlock(files_struct *fsp,
363 uint64_t smblctx,
364 uint64_t count,
365 uint64_t offset,
366 enum brl_flavour lock_flav)
368 bool ok = False;
369 struct byte_range_lock *br_lck = NULL;
371 if (!fsp->fsp_flags.can_lock) {
372 return fsp->fsp_flags.is_directory ?
373 NT_STATUS_INVALID_DEVICE_REQUEST :
374 NT_STATUS_INVALID_HANDLE;
377 if (!lp_locking(fsp->conn->params)) {
378 return NT_STATUS_OK;
381 DBG_DEBUG("unlock start=%"PRIu64" len=%"PRIu64" requested for %s file "
382 "%s\n",
383 offset,
384 count,
385 fsp_fnum_dbg(fsp),
386 fsp_str_dbg(fsp));
388 br_lck = brl_get_locks(talloc_tos(), fsp);
389 if (!br_lck) {
390 return NT_STATUS_NO_MEMORY;
393 ok = brl_unlock(br_lck,
394 smblctx,
395 messaging_server_id(fsp->conn->sconn->msg_ctx),
396 offset,
397 count,
398 lock_flav);
400 TALLOC_FREE(br_lck);
402 if (!ok) {
403 DEBUG(10,("do_unlock: returning ERRlock.\n" ));
404 return NT_STATUS_RANGE_NOT_LOCKED;
407 decrement_current_lock_count(fsp, lock_flav);
408 return NT_STATUS_OK;
411 /****************************************************************************
412 Remove any locks on this fd. Called from file_close().
413 ****************************************************************************/
415 void locking_close_file(files_struct *fsp,
416 enum file_close_type close_type)
418 struct byte_range_lock *br_lck;
420 if (!lp_locking(fsp->conn->params)) {
421 return;
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) {
429 return;
432 br_lck = brl_get_locks(talloc_tos(),fsp);
434 if (br_lck) {
436 * Unlocks must trigger dbwrap_watch watchers,
437 * normally in smbd_do_unlocking. Here it's done
438 * implictly, we're closing the file and thus remove a
439 * share mode. This will wake the waiters.
441 brl_close_fnum(br_lck);
442 TALLOC_FREE(br_lck);
446 /*******************************************************************
447 Print out a share mode.
448 ********************************************************************/
450 char *share_mode_str(TALLOC_CTX *ctx, int num,
451 const struct file_id *id,
452 const struct share_mode_entry *e)
454 struct server_id_buf tmp;
455 struct file_id_buf ftmp;
457 return talloc_asprintf(ctx, "share_mode_entry[%d]: "
458 "pid = %s, share_access = 0x%x, private_options = 0x%x, "
459 "access_mask = 0x%x, mid = 0x%llx, type= 0x%x, gen_id = %llu, "
460 "uid = %u, flags = %u, file_id %s, name_hash = 0x%x",
461 num,
462 server_id_str_buf(e->pid, &tmp),
463 e->share_access, e->private_options,
464 e->access_mask, (unsigned long long)e->op_mid,
465 e->op_type, (unsigned long long)e->share_file_id,
466 (unsigned int)e->uid, (unsigned int)e->flags,
467 file_id_str_buf(*id, &ftmp),
468 (unsigned int)e->name_hash);
471 struct rename_share_filename_state {
472 struct share_mode_lock *lck;
473 struct messaging_context *msg_ctx;
474 struct server_id self;
475 uint32_t orig_name_hash;
476 uint32_t new_name_hash;
477 struct file_rename_message msg;
480 static bool rename_lease_fn(struct share_mode_entry *e,
481 void *private_data)
483 struct rename_share_filename_state *state = private_data;
484 struct share_mode_data *d = state->lck->data;
485 NTSTATUS status;
487 status = leases_db_rename(&e->client_guid,
488 &e->lease_key,
489 &d->id,
490 d->servicepath,
491 d->base_name,
492 d->stream_name);
494 if (!NT_STATUS_IS_OK(status)) {
495 /* Any error recovery possible here ? */
496 DBG_WARNING("Failed to rename lease key for "
497 "renamed file %s:%s. %s\n",
498 d->base_name,
499 d->stream_name,
500 nt_errstr(status));
503 return false;
506 /*******************************************************************
507 Sets the service name and filename for rename.
508 At this point we emit "file renamed" messages to all
509 process id's that have this file open.
510 Based on an initial code idea from SATOH Fumiyasu <fumiya@samba.gr.jp>
511 ********************************************************************/
513 static bool rename_share_filename_fn(
514 struct share_mode_entry *e,
515 bool *modified,
516 void *private_data)
518 struct rename_share_filename_state *state = private_data;
519 DATA_BLOB blob;
520 enum ndr_err_code ndr_err;
521 bool ok;
524 * If this is a hardlink to the inode with a different name,
525 * skip this.
527 if (e->name_hash != state->orig_name_hash) {
528 return false;
530 e->name_hash = state->new_name_hash;
531 *modified = true;
533 ok = server_id_equal(&e->pid, &state->self);
534 if (ok) {
535 return false;
538 state->msg.share_file_id = e->share_file_id;
540 ndr_err = ndr_push_struct_blob(
541 &blob,
542 talloc_tos(),
543 &state->msg,
544 (ndr_push_flags_fn_t)ndr_push_file_rename_message);
545 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
546 DBG_DEBUG("ndr_push_file_rename_message failed: %s\n",
547 ndr_errstr(ndr_err));
548 return false;
550 if (DEBUGLEVEL >= 10) {
551 struct server_id_buf tmp;
552 DBG_DEBUG("sending rename message to %s\n",
553 server_id_str_buf(e->pid, &tmp));
554 NDR_PRINT_DEBUG(file_rename_message, &state->msg);
557 messaging_send(state->msg_ctx, e->pid, MSG_SMB_FILE_RENAME, &blob);
559 TALLOC_FREE(blob.data);
561 return false;
564 bool rename_share_filename(struct messaging_context *msg_ctx,
565 struct share_mode_lock *lck,
566 struct file_id id,
567 const char *servicepath,
568 uint32_t orig_name_hash,
569 uint32_t new_name_hash,
570 const struct smb_filename *smb_fname_dst)
572 struct rename_share_filename_state state = {
573 .lck = lck,
574 .msg_ctx = msg_ctx,
575 .self = messaging_server_id(msg_ctx),
576 .orig_name_hash = orig_name_hash,
577 .new_name_hash = new_name_hash,
578 .msg.id = id,
579 .msg.servicepath = servicepath,
580 .msg.base_name = smb_fname_dst->base_name,
581 .msg.stream_name = smb_fname_dst->stream_name,
583 struct share_mode_data *d = lck->data;
584 bool ok;
586 DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n",
587 servicepath, smb_fname_dst->base_name));
590 * rename_internal_fsp() and rename_internals() add './' to
591 * head of newname if newname does not contain a '/'.
594 if (strncmp(state.msg.base_name, "./", 2) == 0) {
595 state.msg.base_name += 2;
598 d->servicepath = talloc_strdup(d, state.msg.servicepath);
599 d->base_name = talloc_strdup(d, state.msg.base_name);
600 d->stream_name = talloc_strdup(d, state.msg.stream_name);
601 if ((d->servicepath == NULL) ||
602 (d->base_name == NULL) ||
603 ((state.msg.stream_name != NULL) && (d->stream_name == NULL))) {
604 DBG_WARNING("talloc failed\n");
605 return false;
607 d->modified = True;
609 ok = share_mode_forall_entries(
610 lck, rename_share_filename_fn, &state);
611 if (!ok) {
612 DBG_WARNING("share_mode_forall_entries failed\n");
615 ok = share_mode_forall_leases(lck, rename_lease_fn, &state);
616 if (!ok) {
618 * Ignore error here. Not sure what to do..
620 DBG_WARNING("share_mode_forall_leases failed\n");
623 return True;
626 void get_file_infos(struct file_id id,
627 uint32_t name_hash,
628 bool *delete_on_close,
629 struct timespec *write_time)
631 struct share_mode_lock *lck;
633 if (delete_on_close) {
634 *delete_on_close = false;
637 if (write_time) {
638 *write_time = make_omit_timespec();
641 if (!(lck = fetch_share_mode_unlocked(talloc_tos(), id))) {
642 return;
645 if (delete_on_close) {
646 *delete_on_close = is_delete_on_close_set(lck, name_hash);
649 if (write_time) {
650 *write_time = get_share_mode_write_time(lck);
653 TALLOC_FREE(lck);
656 bool is_valid_share_mode_entry(const struct share_mode_entry *e)
658 int num_props = 0;
660 if (e->stale) {
661 return false;
664 num_props += ((e->op_type == NO_OPLOCK) ? 1 : 0);
665 num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0);
666 num_props += (LEVEL_II_OPLOCK_TYPE(e->op_type) ? 1 : 0);
667 num_props += (e->op_type == LEASE_OPLOCK);
669 if ((num_props > 1) && serverid_exists(&e->pid)) {
670 smb_panic("Invalid share mode entry");
672 return (num_props != 0);
675 struct find_lease_ref_state {
676 const struct GUID *client_guid;
677 const struct smb2_lease_key *lease_key;
678 bool found_same;
681 static bool find_lease_ref_fn(
682 struct share_mode_entry *e,
683 bool *modified,
684 void *private_data)
686 struct find_lease_ref_state *state = private_data;
688 if (e->stale) {
689 return false;
691 if (e->op_type != LEASE_OPLOCK) {
692 return false;
695 state->found_same = smb2_lease_equal(
696 &e->client_guid,
697 &e->lease_key,
698 state->client_guid,
699 state->lease_key);
701 * If we found a lease reference, look no further (i.e. return true)
703 return state->found_same;
706 NTSTATUS remove_lease_if_stale(struct share_mode_lock *lck,
707 const struct GUID *client_guid,
708 const struct smb2_lease_key *lease_key)
710 struct find_lease_ref_state state = {
711 .client_guid = client_guid, .lease_key = lease_key,
713 struct share_mode_data *d = lck->data;
714 NTSTATUS status;
715 bool ok;
717 ok = share_mode_forall_entries(lck, find_lease_ref_fn, &state);
718 if (!ok) {
719 return NT_STATUS_INTERNAL_ERROR;
722 if (state.found_same) {
723 return NT_STATUS_RESOURCE_IN_USE;
726 status = leases_db_del(client_guid, lease_key, &d->id);
727 if (!NT_STATUS_IS_OK(status)) {
728 int level = DBGLVL_DEBUG;
730 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
731 level = DBGLVL_ERR;
733 DBG_PREFIX(level, ("leases_db_del failed: %s\n",
734 nt_errstr(status)));
736 return status;
739 bool share_entry_stale_pid(struct share_mode_entry *e)
741 struct server_id_buf buf;
742 bool exists;
744 if (e->stale) {
745 return true;
748 exists = serverid_exists(&e->pid);
749 if (exists) {
750 DBG_DEBUG("PID %s still exists\n",
751 server_id_str_buf(e->pid, &buf));
752 return false;
755 DBG_DEBUG("PID %s does not exist anymore\n",
756 server_id_str_buf(e->pid, &buf));
758 e->stale = true;
760 return true;
763 /****************************************************************************
764 Adds a delete on close token.
765 ****************************************************************************/
767 static bool add_delete_on_close_token(struct share_mode_data *d,
768 uint32_t name_hash,
769 const struct security_token *nt_tok,
770 const struct security_unix_token *tok)
772 struct delete_token *tmp, *dtl;
774 tmp = talloc_realloc(d, d->delete_tokens, struct delete_token,
775 d->num_delete_tokens+1);
776 if (tmp == NULL) {
777 return false;
779 d->delete_tokens = tmp;
780 dtl = &d->delete_tokens[d->num_delete_tokens];
782 dtl->name_hash = name_hash;
783 dtl->delete_nt_token = dup_nt_token(d->delete_tokens, nt_tok);
784 if (dtl->delete_nt_token == NULL) {
785 return false;
787 dtl->delete_token = copy_unix_token(d->delete_tokens, tok);
788 if (dtl->delete_token == NULL) {
789 return false;
791 d->num_delete_tokens += 1;
792 d->modified = true;
793 return true;
796 void reset_delete_on_close_lck(files_struct *fsp,
797 struct share_mode_lock *lck)
799 struct share_mode_data *d = lck->data;
800 uint32_t i;
802 for (i=0; i<d->num_delete_tokens; i++) {
803 struct delete_token *dt = &d->delete_tokens[i];
805 if (dt->name_hash == fsp->name_hash) {
806 d->modified = true;
808 /* Delete this entry. */
809 TALLOC_FREE(dt->delete_nt_token);
810 TALLOC_FREE(dt->delete_token);
811 *dt = d->delete_tokens[d->num_delete_tokens-1];
812 d->num_delete_tokens -= 1;
817 struct set_delete_on_close_state {
818 struct messaging_context *msg_ctx;
819 DATA_BLOB blob;
822 static bool set_delete_on_close_fn(
823 struct share_mode_entry *e,
824 bool *modified,
825 void *private_data)
827 struct set_delete_on_close_state *state = private_data;
828 NTSTATUS status;
830 status = messaging_send(
831 state->msg_ctx,
832 e->pid,
833 MSG_SMB_NOTIFY_CANCEL_DELETED,
834 &state->blob);
836 if (!NT_STATUS_IS_OK(status)) {
837 struct server_id_buf tmp;
838 DBG_DEBUG("messaging_send to %s returned %s\n",
839 server_id_str_buf(e->pid, &tmp),
840 nt_errstr(status));
843 return false;
846 /****************************************************************************
847 Sets the delete on close flag over all share modes on this file.
848 Modify the share mode entry for all files open
849 on this device and inode to tell other smbds we have
850 changed the delete on close flag. This will be noticed
851 in the close code, the last closer will delete the file
852 if flag is set.
853 This makes a copy of any struct security_unix_token into the
854 lck entry. This function is used when the lock is already granted.
855 ****************************************************************************/
857 void set_delete_on_close_lck(files_struct *fsp,
858 struct share_mode_lock *lck,
859 const struct security_token *nt_tok,
860 const struct security_unix_token *tok)
862 struct share_mode_data *d = lck->data;
863 struct set_delete_on_close_state state = {
864 .msg_ctx = fsp->conn->sconn->msg_ctx
866 uint32_t i;
867 bool ret;
868 enum ndr_err_code ndr_err;
870 SMB_ASSERT(nt_tok != NULL);
871 SMB_ASSERT(tok != NULL);
873 for (i=0; i<d->num_delete_tokens; i++) {
874 struct delete_token *dt = &d->delete_tokens[i];
875 if (dt->name_hash == fsp->name_hash) {
876 d->modified = true;
878 /* Replace this token with the given tok. */
879 TALLOC_FREE(dt->delete_nt_token);
880 dt->delete_nt_token = dup_nt_token(dt, nt_tok);
881 SMB_ASSERT(dt->delete_nt_token != NULL);
882 TALLOC_FREE(dt->delete_token);
883 dt->delete_token = copy_unix_token(dt, tok);
884 SMB_ASSERT(dt->delete_token != NULL);
886 return;
890 ret = add_delete_on_close_token(lck->data, fsp->name_hash, nt_tok, tok);
891 SMB_ASSERT(ret);
893 ndr_err = ndr_push_struct_blob(
894 &state.blob,
895 talloc_tos(),
896 &fsp->file_id,
897 (ndr_push_flags_fn_t)ndr_push_file_id);
898 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
899 DEBUG(10, ("ndr_push_file_id failed: %s\n",
900 ndr_errstr(ndr_err)));
903 ret = share_mode_forall_entries(
904 lck, set_delete_on_close_fn, &state);
905 if (!ret) {
906 DBG_DEBUG("share_mode_forall_entries failed\n");
909 TALLOC_FREE(state.blob.data);
912 bool set_delete_on_close(files_struct *fsp, bool delete_on_close,
913 const struct security_token *nt_tok,
914 const struct security_unix_token *tok)
916 struct share_mode_lock *lck;
918 DEBUG(10,("set_delete_on_close: %s delete on close flag for "
919 "%s, file %s\n",
920 delete_on_close ? "Adding" : "Removing", fsp_fnum_dbg(fsp),
921 fsp_str_dbg(fsp)));
923 lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
924 if (lck == NULL) {
925 return False;
928 if (delete_on_close) {
929 set_delete_on_close_lck(fsp, lck, nt_tok, tok);
930 } else {
931 reset_delete_on_close_lck(fsp, lck);
934 if (fsp->fsp_flags.is_directory) {
935 SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name));
936 send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
937 fsp->fsp_name->base_name);
940 TALLOC_FREE(lck);
942 fsp->fsp_flags.delete_on_close = delete_on_close;
944 return True;
947 static struct delete_token *find_delete_on_close_token(
948 struct share_mode_data *d, uint32_t name_hash)
950 uint32_t i;
952 DBG_DEBUG("name_hash = 0x%"PRIx32"\n", name_hash);
954 for (i=0; i<d->num_delete_tokens; i++) {
955 struct delete_token *dt = &d->delete_tokens[i];
957 DBG_DEBUG("dt->name_hash = 0x%"PRIx32"\n",
958 dt->name_hash);
959 if (dt->name_hash == name_hash) {
960 return dt;
963 return NULL;
966 /****************************************************************************
967 Return the NT token and UNIX token if there's a match. Return true if
968 found, false if not.
969 ****************************************************************************/
971 bool get_delete_on_close_token(struct share_mode_lock *lck,
972 uint32_t name_hash,
973 const struct security_token **pp_nt_tok,
974 const struct security_unix_token **pp_tok)
976 struct delete_token *dt;
978 dt = find_delete_on_close_token(lck->data, name_hash);
979 if (dt == NULL) {
980 return false;
982 *pp_nt_tok = dt->delete_nt_token;
983 *pp_tok = dt->delete_token;
984 return true;
987 bool is_delete_on_close_set(struct share_mode_lock *lck, uint32_t name_hash)
989 return find_delete_on_close_token(lck->data, name_hash) != NULL;
992 bool set_sticky_write_time(struct file_id fileid, struct timespec write_time)
994 struct share_mode_lock *lck;
995 struct file_id_buf ftmp;
996 struct timeval_buf tbuf;
997 NTTIME nt = full_timespec_to_nt_time(&write_time);
999 DBG_INFO("%s id=%s\n",
1000 timespec_string_buf(&write_time, true, &tbuf),
1001 file_id_str_buf(fileid, &ftmp));
1003 lck = get_existing_share_mode_lock(talloc_tos(), fileid);
1004 if (lck == NULL) {
1005 return False;
1008 if (lck->data->changed_write_time != nt) {
1009 lck->data->modified = True;
1010 lck->data->changed_write_time = nt;
1013 TALLOC_FREE(lck);
1014 return True;
1017 bool set_write_time(struct file_id fileid, struct timespec write_time)
1019 struct share_mode_lock *lck;
1020 struct file_id_buf idbuf;
1021 struct timeval_buf tbuf;
1022 NTTIME nt = full_timespec_to_nt_time(&write_time);
1024 DBG_INFO("%s id=%s\n",
1025 timespec_string_buf(&write_time, true, &tbuf),
1026 file_id_str_buf(fileid, &idbuf));
1028 lck = get_existing_share_mode_lock(talloc_tos(), fileid);
1029 if (lck == NULL) {
1030 return False;
1033 if (lck->data->old_write_time != nt) {
1034 lck->data->modified = True;
1035 lck->data->old_write_time = nt;
1038 TALLOC_FREE(lck);
1039 return True;
1042 struct timespec get_share_mode_write_time(struct share_mode_lock *lck)
1044 struct share_mode_data *d = lck->data;
1046 if (!null_nttime(d->changed_write_time)) {
1047 return nt_time_to_full_timespec(d->changed_write_time);
1049 return nt_time_to_full_timespec(d->old_write_time);
1052 struct file_has_open_streams_state {
1053 bool found_one;
1056 static bool file_has_open_streams_fn(
1057 struct share_mode_entry *e,
1058 bool *modified,
1059 void *private_data)
1061 struct file_has_open_streams_state *state = private_data;
1063 if ((e->private_options &
1064 NTCREATEX_FLAG_STREAM_BASEOPEN) == 0) {
1065 return false;
1068 if (share_entry_stale_pid(e)) {
1069 return false;
1072 state->found_one = true;
1073 return true;
1076 bool file_has_open_streams(files_struct *fsp)
1078 struct file_has_open_streams_state state = { .found_one = false };
1079 struct share_mode_lock *lock = NULL;
1080 bool ok;
1082 lock = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
1083 if (lock == NULL) {
1084 return false;
1087 ok = share_mode_forall_entries(
1088 lock, file_has_open_streams_fn, &state);
1089 TALLOC_FREE(lock);
1091 if (!ok) {
1092 DBG_DEBUG("share_mode_forall_entries failed\n");
1093 return false;
1095 return state.found_one;
1099 * Walk share mode entries, looking at every lease only once
1102 struct share_mode_forall_leases_state {
1103 TALLOC_CTX *mem_ctx;
1104 struct leases_db_key *leases;
1105 bool (*fn)(struct share_mode_entry *e,
1106 void *private_data);
1107 void *private_data;
1108 NTSTATUS status;
1111 static bool share_mode_forall_leases_fn(
1112 struct share_mode_entry *e,
1113 bool *modified,
1114 void *private_data)
1116 struct share_mode_forall_leases_state *state = private_data;
1117 struct leases_db_key *leases = state->leases;
1118 size_t i, num_leases;
1119 bool stop;
1121 if (e->op_type != LEASE_OPLOCK) {
1122 return false;
1125 num_leases = talloc_array_length(leases);
1127 for (i=0; i<num_leases; i++) {
1128 struct leases_db_key *l = &leases[i];
1129 bool same = smb2_lease_equal(
1130 &e->client_guid,
1131 &e->lease_key,
1132 &l->client_guid,
1133 &l->lease_key);
1134 if (same) {
1135 return false;
1139 leases = talloc_realloc(
1140 state->mem_ctx,
1141 leases,
1142 struct leases_db_key,
1143 num_leases+1);
1144 if (leases == NULL) {
1145 state->status = NT_STATUS_NO_MEMORY;
1146 return true;
1148 leases[num_leases] = (struct leases_db_key) {
1149 .client_guid = e->client_guid,
1150 .lease_key = e->lease_key,
1152 state->leases = leases;
1154 stop = state->fn(e, state->private_data);
1155 return stop;
1158 bool share_mode_forall_leases(
1159 struct share_mode_lock *lck,
1160 bool (*fn)(struct share_mode_entry *e,
1161 void *private_data),
1162 void *private_data)
1164 struct share_mode_forall_leases_state state = {
1165 .mem_ctx = talloc_tos(),
1166 .fn = fn,
1167 .private_data = private_data
1169 bool ok;
1171 ok = share_mode_forall_entries(
1172 lck, share_mode_forall_leases_fn, &state);
1173 TALLOC_FREE(state.leases);
1174 if (!ok) {
1175 DBG_DEBUG("share_mode_forall_entries failed\n");
1176 return false;
1179 if (!NT_STATUS_IS_OK(state.status)) {
1180 DBG_DEBUG("share_mode_forall_leases_fn returned %s\n",
1181 nt_errstr(state.status));
1182 return false;
1185 return true;