ctdb-logging: Separate out syslog and file logging backends
[Samba.git] / source3 / locking / locking.c
bloba320068e6dc9c1f1684bade458531ce3fa3eac03
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 "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"
45 #include "serverid.h"
46 #include "messages.h"
47 #include "util_tdb.h"
48 #include "../librpc/gen_ndr/ndr_open_files.h"
50 #undef DBGC_CLASS
51 #define DBGC_CLASS DBGC_LOCKING
53 #define NO_LOCKING_COUNT (-1)
55 /****************************************************************************
56 Debugging aids :-).
57 ****************************************************************************/
59 const char *lock_type_name(enum brl_type lock_type)
61 switch (lock_type) {
62 case READ_LOCK:
63 return "READ";
64 case WRITE_LOCK:
65 return "WRITE";
66 case PENDING_READ_LOCK:
67 return "PENDING_READ";
68 case PENDING_WRITE_LOCK:
69 return "PENDING_WRITE";
70 default:
71 return "other";
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,
86 uint64_t smblctx,
87 br_off start,
88 br_off size,
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);
97 plock->start = start;
98 plock->size = size;
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);
108 bool ret = False;
110 if (plock->size == 0) {
111 return True;
114 if (!lp_locking(fsp->conn->params) || !strict_locking) {
115 return True;
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)));
124 return true;
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)));
130 return true;
134 br_lck = brl_get_locks_readonly(fsp);
135 if (!br_lck) {
136 return true;
138 ret = brl_locktest(br_lck, plock);
140 if (!ret) {
142 * We got a lock conflict. Retry with rw locks to enable
143 * autocleanup. This is the slow path anyway.
145 br_lck = brl_get_locks(talloc_tos(), fsp);
146 ret = brl_locktest(br_lck, plock);
147 TALLOC_FREE(br_lck);
150 DEBUG(10, ("strict_lock_default: flavour = %s brl start=%ju "
151 "len=%ju %s for fnum %ju file %s\n",
152 lock_flav_name(plock->lock_flav),
153 (uintmax_t)plock->start, (uintmax_t)plock->size,
154 ret ? "unlocked" : "locked",
155 (uintmax_t)plock->fnum, fsp_str_dbg(fsp)));
157 return ret;
160 void strict_unlock_default(files_struct *fsp, struct lock_struct *plock)
164 /****************************************************************************
165 Find out if a lock could be granted - return who is blocking us if we can't.
166 ****************************************************************************/
168 NTSTATUS query_lock(files_struct *fsp,
169 uint64_t *psmblctx,
170 uint64_t *pcount,
171 uint64_t *poffset,
172 enum brl_type *plock_type,
173 enum brl_flavour lock_flav)
175 struct byte_range_lock *br_lck = NULL;
177 if (!fsp->can_lock) {
178 return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
181 if (!lp_locking(fsp->conn->params)) {
182 return NT_STATUS_OK;
185 br_lck = brl_get_locks_readonly(fsp);
186 if (!br_lck) {
187 return NT_STATUS_NO_MEMORY;
190 return brl_lockquery(br_lck,
191 psmblctx,
192 messaging_server_id(fsp->conn->sconn->msg_ctx),
193 poffset,
194 pcount,
195 plock_type,
196 lock_flav);
199 static void increment_current_lock_count(files_struct *fsp,
200 enum brl_flavour lock_flav)
202 if (lock_flav == WINDOWS_LOCK &&
203 fsp->current_lock_count != NO_LOCKING_COUNT) {
204 /* blocking ie. pending, locks also count here,
205 * as this is an efficiency counter to avoid checking
206 * the lock db. on close. JRA. */
208 fsp->current_lock_count++;
209 } else {
210 /* Notice that this has had a POSIX lock request.
211 * We can't count locks after this so forget them.
213 fsp->current_lock_count = NO_LOCKING_COUNT;
217 static void decrement_current_lock_count(files_struct *fsp,
218 enum brl_flavour lock_flav)
220 if (lock_flav == WINDOWS_LOCK &&
221 fsp->current_lock_count != NO_LOCKING_COUNT) {
222 SMB_ASSERT(fsp->current_lock_count > 0);
223 fsp->current_lock_count--;
227 /****************************************************************************
228 Utility function called by locking requests.
229 ****************************************************************************/
231 struct byte_range_lock *do_lock(struct messaging_context *msg_ctx,
232 files_struct *fsp,
233 uint64_t smblctx,
234 uint64_t count,
235 uint64_t offset,
236 enum brl_type lock_type,
237 enum brl_flavour lock_flav,
238 bool blocking_lock,
239 NTSTATUS *perr,
240 uint64_t *psmblctx)
242 struct byte_range_lock *br_lck = NULL;
244 /* silently return ok on print files as we don't do locking there */
245 if (fsp->print_file) {
246 *perr = NT_STATUS_OK;
247 return NULL;
250 if (!fsp->can_lock) {
251 *perr = fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
252 return NULL;
255 if (!lp_locking(fsp->conn->params)) {
256 *perr = NT_STATUS_OK;
257 return NULL;
260 /* NOTE! 0 byte long ranges ARE allowed and should be stored */
262 DEBUG(10,("do_lock: lock flavour %s lock type %s start=%ju len=%ju "
263 "blocking_lock=%s requested for %s file %s\n",
264 lock_flav_name(lock_flav), lock_type_name(lock_type),
265 (uintmax_t)offset, (uintmax_t)count, blocking_lock ? "true" :
266 "false", fsp_fnum_dbg(fsp), fsp_str_dbg(fsp)));
268 br_lck = brl_get_locks(talloc_tos(), fsp);
269 if (!br_lck) {
270 *perr = NT_STATUS_NO_MEMORY;
271 return NULL;
274 *perr = brl_lock(msg_ctx,
275 br_lck,
276 smblctx,
277 messaging_server_id(fsp->conn->sconn->msg_ctx),
278 offset,
279 count,
280 lock_type,
281 lock_flav,
282 blocking_lock,
283 psmblctx);
285 DEBUG(10, ("do_lock: returning status=%s\n", nt_errstr(*perr)));
287 increment_current_lock_count(fsp, lock_flav);
288 return br_lck;
291 /****************************************************************************
292 Utility function called by unlocking requests.
293 ****************************************************************************/
295 NTSTATUS do_unlock(struct messaging_context *msg_ctx,
296 files_struct *fsp,
297 uint64_t smblctx,
298 uint64_t count,
299 uint64_t offset,
300 enum brl_flavour lock_flav)
302 bool ok = False;
303 struct byte_range_lock *br_lck = NULL;
305 if (!fsp->can_lock) {
306 return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
309 if (!lp_locking(fsp->conn->params)) {
310 return NT_STATUS_OK;
313 DEBUG(10, ("do_unlock: unlock start=%ju len=%ju requested for %s file "
314 "%s\n", (uintmax_t)offset, (uintmax_t)count,
315 fsp_fnum_dbg(fsp), fsp_str_dbg(fsp)));
317 br_lck = brl_get_locks(talloc_tos(), fsp);
318 if (!br_lck) {
319 return NT_STATUS_NO_MEMORY;
322 ok = brl_unlock(msg_ctx,
323 br_lck,
324 smblctx,
325 messaging_server_id(fsp->conn->sconn->msg_ctx),
326 offset,
327 count,
328 lock_flav);
330 TALLOC_FREE(br_lck);
332 if (!ok) {
333 DEBUG(10,("do_unlock: returning ERRlock.\n" ));
334 return NT_STATUS_RANGE_NOT_LOCKED;
337 decrement_current_lock_count(fsp, lock_flav);
338 return NT_STATUS_OK;
341 /****************************************************************************
342 Cancel any pending blocked locks.
343 ****************************************************************************/
345 NTSTATUS do_lock_cancel(files_struct *fsp,
346 uint64 smblctx,
347 uint64_t count,
348 uint64_t offset,
349 enum brl_flavour lock_flav)
351 bool ok = False;
352 struct byte_range_lock *br_lck = NULL;
354 if (!fsp->can_lock) {
355 return fsp->is_directory ?
356 NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
359 if (!lp_locking(fsp->conn->params)) {
360 return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
363 DEBUG(10, ("do_lock_cancel: cancel start=%ju len=%ju requested for "
364 "%s file %s\n", (uintmax_t)offset, (uintmax_t)count,
365 fsp_fnum_dbg(fsp), fsp_str_dbg(fsp)));
367 br_lck = brl_get_locks(talloc_tos(), fsp);
368 if (!br_lck) {
369 return NT_STATUS_NO_MEMORY;
372 ok = brl_lock_cancel(br_lck,
373 smblctx,
374 messaging_server_id(fsp->conn->sconn->msg_ctx),
375 offset,
376 count,
377 lock_flav);
379 TALLOC_FREE(br_lck);
381 if (!ok) {
382 DEBUG(10,("do_lock_cancel: returning ERRcancelviolation.\n" ));
383 return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
386 decrement_current_lock_count(fsp, lock_flav);
387 return NT_STATUS_OK;
390 /****************************************************************************
391 Remove any locks on this fd. Called from file_close().
392 ****************************************************************************/
394 void locking_close_file(struct messaging_context *msg_ctx,
395 files_struct *fsp,
396 enum file_close_type close_type)
398 struct byte_range_lock *br_lck;
400 if (!lp_locking(fsp->conn->params)) {
401 return;
404 /* If we have no outstanding locks or pending
405 * locks then we don't need to look in the lock db.
408 if (fsp->current_lock_count == 0) {
409 return;
412 br_lck = brl_get_locks(talloc_tos(),fsp);
414 if (br_lck) {
415 cancel_pending_lock_requests_by_fid(fsp, br_lck, close_type);
416 brl_close_fnum(msg_ctx, br_lck);
417 TALLOC_FREE(br_lck);
421 /*******************************************************************
422 Print out a share mode.
423 ********************************************************************/
425 char *share_mode_str(TALLOC_CTX *ctx, int num, const struct share_mode_entry *e)
427 return talloc_asprintf(ctx, "share_mode_entry[%d]: "
428 "pid = %s, share_access = 0x%x, private_options = 0x%x, "
429 "access_mask = 0x%x, mid = 0x%llx, type= 0x%x, gen_id = %llu, "
430 "uid = %u, flags = %u, file_id %s, name_hash = 0x%x",
431 num,
432 procid_str_static(&e->pid),
433 e->share_access, e->private_options,
434 e->access_mask, (unsigned long long)e->op_mid,
435 e->op_type, (unsigned long long)e->share_file_id,
436 (unsigned int)e->uid, (unsigned int)e->flags,
437 file_id_string_tos(&e->id),
438 (unsigned int)e->name_hash);
441 /*******************************************************************
442 Fetch a share mode where we know one MUST exist. This call reference
443 counts it internally to allow for nested lock fetches.
444 ********************************************************************/
446 struct share_mode_lock *get_existing_share_mode_lock(TALLOC_CTX *mem_ctx,
447 const struct file_id id)
449 return get_share_mode_lock(mem_ctx, id, NULL, NULL, NULL);
452 /*******************************************************************
453 Sets the service name and filename for rename.
454 At this point we emit "file renamed" messages to all
455 process id's that have this file open.
456 Based on an initial code idea from SATOH Fumiyasu <fumiya@samba.gr.jp>
457 ********************************************************************/
459 bool rename_share_filename(struct messaging_context *msg_ctx,
460 struct share_mode_lock *lck,
461 struct file_id id,
462 const char *servicepath,
463 uint32_t orig_name_hash,
464 uint32_t new_name_hash,
465 const struct smb_filename *smb_fname_dst)
467 struct share_mode_data *d = lck->data;
468 size_t sp_len;
469 size_t bn_len;
470 size_t sn_len;
471 size_t msg_len;
472 char *frm = NULL;
473 int i;
474 bool strip_two_chars = false;
475 bool has_stream = smb_fname_dst->stream_name != NULL;
476 struct server_id self_pid = messaging_server_id(msg_ctx);
478 DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n",
479 servicepath, smb_fname_dst->base_name));
482 * rename_internal_fsp() and rename_internals() add './' to
483 * head of newname if newname does not contain a '/'.
485 if (smb_fname_dst->base_name[0] &&
486 smb_fname_dst->base_name[1] &&
487 smb_fname_dst->base_name[0] == '.' &&
488 smb_fname_dst->base_name[1] == '/') {
489 strip_two_chars = true;
492 d->servicepath = talloc_strdup(d, servicepath);
493 d->base_name = talloc_strdup(d, smb_fname_dst->base_name +
494 (strip_two_chars ? 2 : 0));
495 d->stream_name = talloc_strdup(d, smb_fname_dst->stream_name);
496 if (d->base_name == NULL ||
497 (has_stream && d->stream_name == NULL) ||
498 d->servicepath == NULL) {
499 DEBUG(0, ("rename_share_filename: talloc failed\n"));
500 return False;
502 d->modified = True;
504 sp_len = strlen(d->servicepath);
505 bn_len = strlen(d->base_name);
506 sn_len = has_stream ? strlen(d->stream_name) : 0;
508 msg_len = MSG_FILE_RENAMED_MIN_SIZE + sp_len + 1 + bn_len + 1 +
509 sn_len + 1;
511 /* Set up the name changed message. */
512 frm = talloc_array(d, char, msg_len);
513 if (!frm) {
514 return False;
517 push_file_id_24(frm, &id);
519 DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len ));
521 strlcpy(&frm[24],
522 d->servicepath ? d->servicepath : "",
523 sp_len+1);
524 strlcpy(&frm[24 + sp_len + 1],
525 d->base_name ? d->base_name : "",
526 bn_len+1);
527 strlcpy(&frm[24 + sp_len + 1 + bn_len + 1],
528 d->stream_name ? d->stream_name : "",
529 sn_len+1);
531 /* Send the messages. */
532 for (i=0; i<d->num_share_modes; i++) {
533 struct share_mode_entry *se = &d->share_modes[i];
534 if (!is_valid_share_mode_entry(se)) {
535 continue;
538 /* If this is a hardlink to the inode
539 with a different name, skip this. */
540 if (se->name_hash != orig_name_hash) {
541 continue;
544 se->name_hash = new_name_hash;
546 /* But not to ourselves... */
547 if (serverid_equal(&se->pid, &self_pid)) {
548 continue;
551 if (share_mode_stale_pid(d, i)) {
552 continue;
555 DEBUG(10,("rename_share_filename: sending rename message to "
556 "pid %s file_id %s sharepath %s base_name %s "
557 "stream_name %s\n",
558 procid_str_static(&se->pid),
559 file_id_string_tos(&id),
560 d->servicepath, d->base_name,
561 has_stream ? d->stream_name : ""));
563 messaging_send_buf(msg_ctx, se->pid, MSG_SMB_FILE_RENAME,
564 (uint8 *)frm, msg_len);
567 return True;
570 void get_file_infos(struct file_id id,
571 uint32_t name_hash,
572 bool *delete_on_close,
573 struct timespec *write_time)
575 struct share_mode_lock *lck;
577 if (delete_on_close) {
578 *delete_on_close = false;
581 if (write_time) {
582 ZERO_STRUCTP(write_time);
585 if (!(lck = fetch_share_mode_unlocked(talloc_tos(), id))) {
586 return;
589 if (delete_on_close) {
590 *delete_on_close = is_delete_on_close_set(lck, name_hash);
593 if (write_time) {
594 *write_time = get_share_mode_write_time(lck);
597 TALLOC_FREE(lck);
600 bool is_valid_share_mode_entry(const struct share_mode_entry *e)
602 int num_props = 0;
604 if (e->stale) {
605 return false;
608 num_props += ((e->op_type == NO_OPLOCK) ? 1 : 0);
609 num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0);
610 num_props += (LEVEL_II_OPLOCK_TYPE(e->op_type) ? 1 : 0);
612 if ((num_props > 1) && serverid_exists(&e->pid)) {
613 smb_panic("Invalid share mode entry");
615 return (num_props != 0);
619 * In case d->share_modes[i] conflicts with something or otherwise is
620 * being used, we need to make sure the corresponding process still
621 * exists.
623 bool share_mode_stale_pid(struct share_mode_data *d, uint32_t idx)
625 struct share_mode_entry *e;
627 if (idx > d->num_share_modes) {
628 DEBUG(1, ("Asking for index %u, only %u around\n",
629 idx, (unsigned)d->num_share_modes));
630 return false;
632 e = &d->share_modes[idx];
633 if (e->stale) {
635 * Checked before
637 return true;
639 if (serverid_exists(&e->pid)) {
640 DEBUG(10, ("PID %s (index %u out of %u) still exists\n",
641 procid_str_static(&e->pid), idx,
642 (unsigned)d->num_share_modes));
643 return false;
645 DEBUG(10, ("PID %s (index %u out of %u) does not exist anymore\n",
646 procid_str_static(&e->pid), idx,
647 (unsigned)d->num_share_modes));
649 e->stale = true;
651 if (d->num_delete_tokens != 0) {
652 uint32_t i, num_stale;
655 * We cannot have any delete tokens
656 * if there are no valid share modes.
659 num_stale = 0;
661 for (i=0; i<d->num_share_modes; i++) {
662 if (d->share_modes[i].stale) {
663 num_stale += 1;
667 if (num_stale == d->num_share_modes) {
669 * No non-stale share mode found
671 TALLOC_FREE(d->delete_tokens);
672 d->num_delete_tokens = 0;
676 d->modified = true;
677 return true;
680 void remove_stale_share_mode_entries(struct share_mode_data *d)
682 uint32_t i;
684 i = 0;
685 while (i < d->num_share_modes) {
686 if (d->share_modes[i].stale) {
687 struct share_mode_entry *m = d->share_modes;
688 m[i] = m[d->num_share_modes-1];
689 d->num_share_modes -= 1;
690 } else {
691 i += 1;
696 bool set_share_mode(struct share_mode_lock *lck, files_struct *fsp,
697 uid_t uid, uint64_t mid, uint16 op_type)
699 struct share_mode_data *d = lck->data;
700 struct share_mode_entry *tmp, *e;
702 tmp = talloc_realloc(d, d->share_modes, struct share_mode_entry,
703 d->num_share_modes+1);
704 if (tmp == NULL) {
705 return false;
707 d->share_modes = tmp;
708 e = &d->share_modes[d->num_share_modes];
709 d->num_share_modes += 1;
710 d->modified = true;
712 ZERO_STRUCTP(e);
713 e->pid = messaging_server_id(fsp->conn->sconn->msg_ctx);
714 e->share_access = fsp->share_access;
715 e->private_options = fsp->fh->private_options;
716 e->access_mask = fsp->access_mask;
717 e->op_mid = mid;
718 e->op_type = op_type;
719 e->time.tv_sec = fsp->open_time.tv_sec;
720 e->time.tv_usec = fsp->open_time.tv_usec;
721 e->id = fsp->file_id;
722 e->share_file_id = fsp->fh->gen_id;
723 e->uid = (uint32)uid;
724 e->flags = fsp->posix_open ? SHARE_MODE_FLAG_POSIX_OPEN : 0;
725 e->name_hash = fsp->name_hash;
727 return true;
730 static struct share_mode_entry *find_share_mode_entry(
731 struct share_mode_lock *lck, files_struct *fsp)
733 struct share_mode_data *d = lck->data;
734 struct server_id pid;
735 int i;
737 pid = messaging_server_id(fsp->conn->sconn->msg_ctx);
739 for (i=0; i<d->num_share_modes; i++) {
740 struct share_mode_entry *e = &d->share_modes[i];
742 if (!is_valid_share_mode_entry(e)) {
743 continue;
745 if (!serverid_equal(&pid, &e->pid)) {
746 continue;
748 if (!file_id_equal(&fsp->file_id, &e->id)) {
749 continue;
751 if (fsp->fh->gen_id != e->share_file_id) {
752 continue;
754 return e;
756 return NULL;
759 /*******************************************************************
760 Del the share mode of a file for this process. Return the number of
761 entries left.
762 ********************************************************************/
764 bool del_share_mode(struct share_mode_lock *lck, files_struct *fsp)
766 struct share_mode_entry *e;
768 e = find_share_mode_entry(lck, fsp);
769 if (e == NULL) {
770 return False;
772 *e = lck->data->share_modes[lck->data->num_share_modes-1];
773 lck->data->num_share_modes -= 1;
774 lck->data->modified = True;
775 return True;
778 bool mark_share_mode_disconnected(struct share_mode_lock *lck,
779 struct files_struct *fsp)
781 struct share_mode_entry *e;
783 if (lck->data->num_share_modes != 1) {
784 return false;
787 if (fsp->op == NULL) {
788 return false;
790 if (!fsp->op->global->durable) {
791 return false;
794 e = find_share_mode_entry(lck, fsp);
795 if (e == NULL) {
796 return false;
799 DEBUG(10, ("Marking share mode entry disconnected for durable handle\n"));
801 server_id_set_disconnected(&e->pid);
804 * On reopen the caller needs to check that
805 * the client comes with the correct handle.
807 e->share_file_id = fsp->op->global->open_persistent_id;
809 lck->data->modified = true;
810 return true;
813 /*******************************************************************
814 Remove an oplock mid and mode entry from a share mode.
815 ********************************************************************/
817 bool remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
819 struct share_mode_entry *e;
821 e = find_share_mode_entry(lck, fsp);
822 if (e == NULL) {
823 return False;
826 e->op_type = NO_OPLOCK;
827 lck->data->modified = True;
828 return True;
831 /*******************************************************************
832 Downgrade a oplock type from exclusive to level II.
833 ********************************************************************/
835 bool downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
837 struct share_mode_entry *e;
839 e = find_share_mode_entry(lck, fsp);
840 if (e == NULL) {
841 return False;
844 e->op_type = LEVEL_II_OPLOCK;
845 lck->data->modified = True;
846 return True;
849 /****************************************************************************
850 Adds a delete on close token.
851 ****************************************************************************/
853 static bool add_delete_on_close_token(struct share_mode_data *d,
854 uint32_t name_hash,
855 const struct security_token *nt_tok,
856 const struct security_unix_token *tok)
858 struct delete_token *tmp, *dtl;
860 tmp = talloc_realloc(d, d->delete_tokens, struct delete_token,
861 d->num_delete_tokens+1);
862 if (tmp == NULL) {
863 return false;
865 d->delete_tokens = tmp;
866 dtl = &d->delete_tokens[d->num_delete_tokens];
868 dtl->name_hash = name_hash;
869 dtl->delete_nt_token = dup_nt_token(d->delete_tokens, nt_tok);
870 if (dtl->delete_nt_token == NULL) {
871 return false;
873 dtl->delete_token = copy_unix_token(d->delete_tokens, tok);
874 if (dtl->delete_token == NULL) {
875 return false;
877 d->num_delete_tokens += 1;
878 d->modified = true;
879 return true;
882 /****************************************************************************
883 Sets the delete on close flag over all share modes on this file.
884 Modify the share mode entry for all files open
885 on this device and inode to tell other smbds we have
886 changed the delete on close flag. This will be noticed
887 in the close code, the last closer will delete the file
888 if flag is set.
889 This makes a copy of any struct security_unix_token into the
890 lck entry. This function is used when the lock is already granted.
891 ****************************************************************************/
893 void set_delete_on_close_lck(files_struct *fsp,
894 struct share_mode_lock *lck,
895 bool delete_on_close,
896 const struct security_token *nt_tok,
897 const struct security_unix_token *tok)
899 struct share_mode_data *d = lck->data;
900 int i;
901 bool ret;
903 if (delete_on_close) {
904 SMB_ASSERT(nt_tok != NULL);
905 SMB_ASSERT(tok != NULL);
906 } else {
907 SMB_ASSERT(nt_tok == NULL);
908 SMB_ASSERT(tok == NULL);
911 for (i=0; i<d->num_delete_tokens; i++) {
912 struct delete_token *dt = &d->delete_tokens[i];
913 if (dt->name_hash == fsp->name_hash) {
914 d->modified = true;
915 if (delete_on_close == false) {
916 /* Delete this entry. */
917 TALLOC_FREE(dt->delete_nt_token);
918 TALLOC_FREE(dt->delete_token);
919 *dt = d->delete_tokens[
920 d->num_delete_tokens-1];
921 d->num_delete_tokens -= 1;
922 } else {
923 /* Replace this token with the
924 given tok. */
925 TALLOC_FREE(dt->delete_nt_token);
926 dt->delete_nt_token = dup_nt_token(dt, nt_tok);
927 SMB_ASSERT(dt->delete_nt_token != NULL);
928 TALLOC_FREE(dt->delete_token);
929 dt->delete_token = copy_unix_token(dt, tok);
930 SMB_ASSERT(dt->delete_token != NULL);
932 return;
936 if (!delete_on_close) {
937 /* Nothing to delete - not found. */
938 return;
941 ret = add_delete_on_close_token(lck->data, fsp->name_hash, nt_tok, tok);
942 SMB_ASSERT(ret);
945 bool set_delete_on_close(files_struct *fsp, bool delete_on_close,
946 const struct security_token *nt_tok,
947 const struct security_unix_token *tok)
949 struct share_mode_lock *lck;
951 DEBUG(10,("set_delete_on_close: %s delete on close flag for "
952 "%s, file %s\n",
953 delete_on_close ? "Adding" : "Removing", fsp_fnum_dbg(fsp),
954 fsp_str_dbg(fsp)));
956 lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
957 if (lck == NULL) {
958 return False;
961 if (delete_on_close) {
962 set_delete_on_close_lck(fsp, lck, true,
963 nt_tok,
964 tok);
965 } else {
966 set_delete_on_close_lck(fsp, lck, false,
967 NULL,
968 NULL);
971 if (fsp->is_directory) {
972 SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name));
973 send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
974 fsp->fsp_name->base_name);
977 TALLOC_FREE(lck);
979 fsp->delete_on_close = delete_on_close;
981 return True;
984 static struct delete_token *find_delete_on_close_token(
985 struct share_mode_data *d, uint32_t name_hash)
987 uint32_t i;
989 DEBUG(10, ("find_delete_on_close_token: name_hash = 0x%x\n",
990 (unsigned int)name_hash));
992 for (i=0; i<d->num_delete_tokens; i++) {
993 struct delete_token *dt = &d->delete_tokens[i];
995 DEBUG(10, ("find__delete_on_close_token: dt->name_hash = 0x%x\n",
996 (unsigned int)dt->name_hash ));
997 if (dt->name_hash == name_hash) {
998 return dt;
1001 return NULL;
1004 /****************************************************************************
1005 Return the NT token and UNIX token if there's a match. Return true if
1006 found, false if not.
1007 ****************************************************************************/
1009 bool get_delete_on_close_token(struct share_mode_lock *lck,
1010 uint32_t name_hash,
1011 const struct security_token **pp_nt_tok,
1012 const struct security_unix_token **pp_tok)
1014 struct delete_token *dt;
1016 dt = find_delete_on_close_token(lck->data, name_hash);
1017 if (dt == NULL) {
1018 return false;
1020 *pp_nt_tok = dt->delete_nt_token;
1021 *pp_tok = dt->delete_token;
1022 return true;
1025 bool is_delete_on_close_set(struct share_mode_lock *lck, uint32_t name_hash)
1027 return find_delete_on_close_token(lck->data, name_hash) != NULL;
1030 bool set_sticky_write_time(struct file_id fileid, struct timespec write_time)
1032 struct share_mode_lock *lck;
1034 DEBUG(5,("set_sticky_write_time: %s id=%s\n",
1035 timestring(talloc_tos(),
1036 convert_timespec_to_time_t(write_time)),
1037 file_id_string_tos(&fileid)));
1039 lck = get_existing_share_mode_lock(talloc_tos(), fileid);
1040 if (lck == NULL) {
1041 return False;
1044 if (timespec_compare(&lck->data->changed_write_time, &write_time) != 0) {
1045 lck->data->modified = True;
1046 lck->data->changed_write_time = write_time;
1049 TALLOC_FREE(lck);
1050 return True;
1053 bool set_write_time(struct file_id fileid, struct timespec write_time)
1055 struct share_mode_lock *lck;
1057 DEBUG(5,("set_write_time: %s id=%s\n",
1058 timestring(talloc_tos(),
1059 convert_timespec_to_time_t(write_time)),
1060 file_id_string_tos(&fileid)));
1062 lck = get_existing_share_mode_lock(talloc_tos(), fileid);
1063 if (lck == NULL) {
1064 return False;
1067 if (timespec_compare(&lck->data->old_write_time, &write_time) != 0) {
1068 lck->data->modified = True;
1069 lck->data->old_write_time = write_time;
1072 TALLOC_FREE(lck);
1073 return True;
1076 struct timespec get_share_mode_write_time(struct share_mode_lock *lck)
1078 struct share_mode_data *d = lck->data;
1080 if (!null_timespec(d->changed_write_time)) {
1081 return d->changed_write_time;
1083 return d->old_write_time;