s3: Put an indirection layer into share_mode_lock
[Samba/id10ts.git] / source3 / locking / locking.c
blobd98d19b3994e4106bf7d6ac1bfd047bde9ca84f2
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 /* the locking database handle */
56 static struct db_context *lock_db;
58 /****************************************************************************
59 Debugging aids :-).
60 ****************************************************************************/
62 const char *lock_type_name(enum brl_type lock_type)
64 switch (lock_type) {
65 case READ_LOCK:
66 return "READ";
67 case WRITE_LOCK:
68 return "WRITE";
69 case PENDING_READ_LOCK:
70 return "PENDING_READ";
71 case PENDING_WRITE_LOCK:
72 return "PENDING_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 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;
101 plock->size = size;
102 plock->fnum = fsp->fnum;
103 plock->lock_type = lock_type;
104 plock->lock_flav = lp_posix_cifsu_locktype(fsp);
107 bool strict_lock_default(files_struct *fsp, struct lock_struct *plock)
109 int strict_locking = lp_strict_locking(fsp->conn->params);
110 bool ret = False;
112 if (plock->size == 0) {
113 return True;
116 if (!lp_locking(fsp->conn->params) || !strict_locking) {
117 return True;
120 if (strict_locking == Auto) {
121 if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (plock->lock_type == READ_LOCK || plock->lock_type == WRITE_LOCK)) {
122 DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp_str_dbg(fsp)));
123 ret = True;
124 } else if ((fsp->oplock_type == LEVEL_II_OPLOCK) &&
125 (plock->lock_type == READ_LOCK)) {
126 DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp_str_dbg(fsp)));
127 ret = True;
128 } else {
129 struct byte_range_lock *br_lck;
131 br_lck = brl_get_locks_readonly(fsp);
132 if (!br_lck) {
133 return True;
135 ret = brl_locktest(br_lck,
136 plock->context.smblctx,
137 plock->context.pid,
138 plock->start,
139 plock->size,
140 plock->lock_type,
141 plock->lock_flav);
143 } else {
144 struct byte_range_lock *br_lck;
146 br_lck = brl_get_locks_readonly(fsp);
147 if (!br_lck) {
148 return True;
150 ret = brl_locktest(br_lck,
151 plock->context.smblctx,
152 plock->context.pid,
153 plock->start,
154 plock->size,
155 plock->lock_type,
156 plock->lock_flav);
159 DEBUG(10,("strict_lock_default: flavour = %s brl start=%.0f "
160 "len=%.0f %s for fnum %d file %s\n",
161 lock_flav_name(plock->lock_flav),
162 (double)plock->start, (double)plock->size,
163 ret ? "unlocked" : "locked",
164 plock->fnum, fsp_str_dbg(fsp)));
166 return ret;
169 void strict_unlock_default(files_struct *fsp, struct lock_struct *plock)
173 /****************************************************************************
174 Find out if a lock could be granted - return who is blocking us if we can't.
175 ****************************************************************************/
177 NTSTATUS query_lock(files_struct *fsp,
178 uint64_t *psmblctx,
179 uint64_t *pcount,
180 uint64_t *poffset,
181 enum brl_type *plock_type,
182 enum brl_flavour lock_flav)
184 struct byte_range_lock *br_lck = NULL;
186 if (!fsp->can_lock) {
187 return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : 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 byte_range_lock *do_lock(struct messaging_context *msg_ctx,
241 files_struct *fsp,
242 uint64_t smblctx,
243 uint64_t count,
244 uint64_t offset,
245 enum brl_type lock_type,
246 enum brl_flavour lock_flav,
247 bool blocking_lock,
248 NTSTATUS *perr,
249 uint64_t *psmblctx,
250 struct blocking_lock_record *blr)
252 struct byte_range_lock *br_lck = NULL;
254 /* silently return ok on print files as we don't do locking there */
255 if (fsp->print_file) {
256 *perr = NT_STATUS_OK;
257 return NULL;
260 if (!fsp->can_lock) {
261 *perr = fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
262 return NULL;
265 if (!lp_locking(fsp->conn->params)) {
266 *perr = NT_STATUS_OK;
267 return NULL;
270 /* NOTE! 0 byte long ranges ARE allowed and should be stored */
272 DEBUG(10,("do_lock: lock flavour %s lock type %s start=%.0f len=%.0f "
273 "blocking_lock=%s requested for fnum %d file %s\n",
274 lock_flav_name(lock_flav), lock_type_name(lock_type),
275 (double)offset, (double)count, blocking_lock ? "true" :
276 "false", fsp->fnum, fsp_str_dbg(fsp)));
278 br_lck = brl_get_locks(talloc_tos(), fsp);
279 if (!br_lck) {
280 *perr = NT_STATUS_NO_MEMORY;
281 return NULL;
284 *perr = brl_lock(msg_ctx,
285 br_lck,
286 smblctx,
287 messaging_server_id(fsp->conn->sconn->msg_ctx),
288 offset,
289 count,
290 lock_type,
291 lock_flav,
292 blocking_lock,
293 psmblctx,
294 blr);
296 DEBUG(10, ("do_lock: returning status=%s\n", nt_errstr(*perr)));
298 increment_current_lock_count(fsp, lock_flav);
299 return br_lck;
302 /****************************************************************************
303 Utility function called by unlocking requests.
304 ****************************************************************************/
306 NTSTATUS do_unlock(struct messaging_context *msg_ctx,
307 files_struct *fsp,
308 uint64_t smblctx,
309 uint64_t count,
310 uint64_t offset,
311 enum brl_flavour lock_flav)
313 bool ok = False;
314 struct byte_range_lock *br_lck = NULL;
316 if (!fsp->can_lock) {
317 return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
320 if (!lp_locking(fsp->conn->params)) {
321 return NT_STATUS_OK;
324 DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for fnum %d file %s\n",
325 (double)offset, (double)count, fsp->fnum,
326 fsp_str_dbg(fsp)));
328 br_lck = brl_get_locks(talloc_tos(), fsp);
329 if (!br_lck) {
330 return NT_STATUS_NO_MEMORY;
333 ok = brl_unlock(msg_ctx,
334 br_lck,
335 smblctx,
336 messaging_server_id(fsp->conn->sconn->msg_ctx),
337 offset,
338 count,
339 lock_flav);
341 TALLOC_FREE(br_lck);
343 if (!ok) {
344 DEBUG(10,("do_unlock: returning ERRlock.\n" ));
345 return NT_STATUS_RANGE_NOT_LOCKED;
348 decrement_current_lock_count(fsp, lock_flav);
349 return NT_STATUS_OK;
352 /****************************************************************************
353 Cancel any pending blocked locks.
354 ****************************************************************************/
356 NTSTATUS do_lock_cancel(files_struct *fsp,
357 uint64 smblctx,
358 uint64_t count,
359 uint64_t offset,
360 enum brl_flavour lock_flav,
361 struct blocking_lock_record *blr)
363 bool ok = False;
364 struct byte_range_lock *br_lck = NULL;
366 if (!fsp->can_lock) {
367 return fsp->is_directory ?
368 NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
371 if (!lp_locking(fsp->conn->params)) {
372 return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
375 DEBUG(10,("do_lock_cancel: cancel start=%.0f len=%.0f requested for fnum %d file %s\n",
376 (double)offset, (double)count, fsp->fnum,
377 fsp_str_dbg(fsp)));
379 br_lck = brl_get_locks(talloc_tos(), fsp);
380 if (!br_lck) {
381 return NT_STATUS_NO_MEMORY;
384 ok = brl_lock_cancel(br_lck,
385 smblctx,
386 messaging_server_id(fsp->conn->sconn->msg_ctx),
387 offset,
388 count,
389 lock_flav,
390 blr);
392 TALLOC_FREE(br_lck);
394 if (!ok) {
395 DEBUG(10,("do_lock_cancel: returning ERRcancelviolation.\n" ));
396 return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
399 decrement_current_lock_count(fsp, lock_flav);
400 return NT_STATUS_OK;
403 /****************************************************************************
404 Remove any locks on this fd. Called from file_close().
405 ****************************************************************************/
407 void locking_close_file(struct messaging_context *msg_ctx,
408 files_struct *fsp,
409 enum file_close_type close_type)
411 struct byte_range_lock *br_lck;
413 if (!lp_locking(fsp->conn->params)) {
414 return;
417 /* If we have not outstanding locks or pending
418 * locks then we don't need to look in the lock db.
421 if (fsp->current_lock_count == 0) {
422 return;
425 br_lck = brl_get_locks(talloc_tos(),fsp);
427 if (br_lck) {
428 cancel_pending_lock_requests_by_fid(fsp, br_lck, close_type);
429 brl_close_fnum(msg_ctx, br_lck);
430 TALLOC_FREE(br_lck);
434 /****************************************************************************
435 Initialise the locking functions.
436 ****************************************************************************/
438 static bool locking_init_internal(bool read_only)
440 brl_init(read_only);
442 if (lock_db)
443 return True;
445 lock_db = db_open(NULL, lock_path("locking.tdb"),
446 lp_open_files_db_hash_size(),
447 TDB_DEFAULT|TDB_VOLATILE|TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH,
448 read_only?O_RDONLY:O_RDWR|O_CREAT, 0644);
450 if (!lock_db) {
451 DEBUG(0,("ERROR: Failed to initialise locking database\n"));
452 return False;
455 if (!posix_locking_init(read_only))
456 return False;
458 return True;
461 bool locking_init(void)
463 return locking_init_internal(false);
466 bool locking_init_readonly(void)
468 return locking_init_internal(true);
471 /*******************************************************************
472 Deinitialize the share_mode management.
473 ******************************************************************/
475 bool locking_end(void)
477 brl_shutdown();
478 TALLOC_FREE(lock_db);
479 return true;
482 /*******************************************************************
483 Form a static locking key for a dev/inode pair.
484 ******************************************************************/
486 static TDB_DATA locking_key(const struct file_id *id, struct file_id *tmp)
488 *tmp = *id;
489 return make_tdb_data((const uint8_t *)tmp, sizeof(*tmp));
492 /*******************************************************************
493 Print out a share mode.
494 ********************************************************************/
496 char *share_mode_str(TALLOC_CTX *ctx, int num, const struct share_mode_entry *e)
498 return talloc_asprintf(ctx, "share_mode_entry[%d]: "
499 "pid = %s, share_access = 0x%x, private_options = 0x%x, "
500 "access_mask = 0x%x, mid = 0x%llx, type= 0x%x, gen_id = %llu, "
501 "uid = %u, flags = %u, file_id %s, name_hash = 0x%x",
502 num,
503 procid_str_static(&e->pid),
504 e->share_access, e->private_options,
505 e->access_mask, (unsigned long long)e->op_mid,
506 e->op_type, (unsigned long long)e->share_file_id,
507 (unsigned int)e->uid, (unsigned int)e->flags,
508 file_id_string_tos(&e->id),
509 (unsigned int)e->name_hash);
512 /*******************************************************************
513 Get all share mode entries for a dev/inode pair.
514 ********************************************************************/
516 static struct share_mode_data *parse_share_modes(TALLOC_CTX *mem_ctx,
517 const TDB_DATA dbuf)
519 struct share_mode_data *d;
520 int i;
521 struct server_id *pids;
522 bool *pid_exists;
523 enum ndr_err_code ndr_err;
524 DATA_BLOB blob;
526 d = talloc_zero(mem_ctx, struct share_mode_data);
527 if (d == NULL) {
528 DEBUG(0, ("talloc failed\n"));
529 goto fail;
532 blob.data = dbuf.dptr;
533 blob.length = dbuf.dsize;
535 ndr_err = ndr_pull_struct_blob(
536 &blob, d, d, (ndr_pull_flags_fn_t)ndr_pull_share_mode_data);
537 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
538 DEBUG(1, ("ndr_pull_share_mode_lock failed\n"));
539 goto fail;
542 d->modified = false;
543 d->fresh = false;
545 if (DEBUGLEVEL >= 10) {
546 DEBUG(10, ("parse_share_modes:\n"));
547 NDR_PRINT_DEBUG(share_mode_data, d);
551 * Ensure that each entry has a real process attached.
554 pids = talloc_array(talloc_tos(), struct server_id,
555 d->num_share_modes);
556 if (pids == NULL) {
557 DEBUG(0, ("talloc failed\n"));
558 goto fail;
560 pid_exists = talloc_array(talloc_tos(), bool, d->num_share_modes);
561 if (pid_exists == NULL) {
562 DEBUG(0, ("talloc failed\n"));
563 goto fail;
566 for (i=0; i<d->num_share_modes; i++) {
567 pids[i] = d->share_modes[i].pid;
569 if (!serverids_exist(pids, d->num_share_modes, pid_exists)) {
570 DEBUG(0, ("serverid_exists failed\n"));
571 goto fail;
574 i = 0;
575 while (i < d->num_share_modes) {
576 struct share_mode_entry *e = &d->share_modes[i];
577 if (!pid_exists[i]) {
578 *e = d->share_modes[d->num_share_modes-1];
579 d->num_share_modes -= 1;
580 d->modified = True;
581 continue;
583 i += 1;
585 TALLOC_FREE(pid_exists);
586 TALLOC_FREE(pids);
587 return d;
588 fail:
589 TALLOC_FREE(d);
590 return NULL;
593 static TDB_DATA unparse_share_modes(struct share_mode_data *d)
595 DATA_BLOB blob;
596 enum ndr_err_code ndr_err;
598 if (DEBUGLEVEL >= 10) {
599 DEBUG(10, ("unparse_share_modes:\n"));
600 NDR_PRINT_DEBUG(share_mode_data, d);
603 if (d->num_share_modes == 0) {
604 DEBUG(10, ("No used share mode found\n"));
605 return make_tdb_data(NULL, 0);
608 ndr_err = ndr_push_struct_blob(
609 &blob, d, d, (ndr_push_flags_fn_t)ndr_push_share_mode_data);
610 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
611 smb_panic("ndr_push_share_mode_lock failed");
614 return make_tdb_data(blob.data, blob.length);
617 static int share_mode_data_destructor(struct share_mode_data *d)
619 NTSTATUS status;
620 TDB_DATA data;
622 if (!d->modified) {
623 return 0;
626 data = unparse_share_modes(d);
628 if (data.dptr == NULL) {
629 if (!d->fresh) {
630 /* There has been an entry before, delete it */
632 status = dbwrap_record_delete(d->record);
633 if (!NT_STATUS_IS_OK(status)) {
634 char *errmsg;
636 DEBUG(0, ("delete_rec returned %s\n",
637 nt_errstr(status)));
639 if (asprintf(&errmsg, "could not delete share "
640 "entry: %s\n",
641 nt_errstr(status)) == -1) {
642 smb_panic("could not delete share"
643 "entry");
645 smb_panic(errmsg);
648 goto done;
651 status = dbwrap_record_store(d->record, data, TDB_REPLACE);
652 if (!NT_STATUS_IS_OK(status)) {
653 char *errmsg;
655 DEBUG(0, ("store returned %s\n", nt_errstr(status)));
657 if (asprintf(&errmsg, "could not store share mode entry: %s",
658 nt_errstr(status)) == -1) {
659 smb_panic("could not store share mode entry");
661 smb_panic(errmsg);
664 done:
666 return 0;
669 static struct share_mode_data *fresh_share_mode_lock(
670 TALLOC_CTX *mem_ctx, const char *servicepath,
671 const struct smb_filename *smb_fname,
672 const struct timespec *old_write_time)
674 struct share_mode_data *d;
676 if ((servicepath == NULL) || (smb_fname == NULL) ||
677 (old_write_time == NULL)) {
678 return NULL;
681 d = talloc_zero(mem_ctx, struct share_mode_data);
682 if (d == NULL) {
683 goto fail;
685 d->base_name = talloc_strdup(d, smb_fname->base_name);
686 if (d->base_name == NULL) {
687 goto fail;
689 if (smb_fname->stream_name != NULL) {
690 d->stream_name = talloc_strdup(d, smb_fname->stream_name);
691 if (d->stream_name == NULL) {
692 goto fail;
695 d->servicepath = talloc_strdup(d, servicepath);
696 if (d->servicepath == NULL) {
697 goto fail;
699 d->old_write_time = *old_write_time;
700 d->modified = false;
701 d->fresh = true;
702 return d;
703 fail:
704 DEBUG(0, ("talloc failed\n"));
705 TALLOC_FREE(d);
706 return NULL;
709 struct share_mode_lock *get_share_mode_lock_fresh(TALLOC_CTX *mem_ctx,
710 const struct file_id id,
711 const char *servicepath,
712 const struct smb_filename *smb_fname,
713 const struct timespec *old_write_time)
715 struct share_mode_lock *lck;
716 struct share_mode_data *d;
717 struct file_id tmp;
718 struct db_record *rec;
719 TDB_DATA key = locking_key(&id, &tmp);
720 TDB_DATA value;
722 rec = dbwrap_fetch_locked(lock_db, mem_ctx, key);
723 if (rec == NULL) {
724 DEBUG(3, ("Could not lock share entry\n"));
725 return NULL;
728 value = dbwrap_record_get_value(rec);
730 if (value.dptr == NULL) {
731 d = fresh_share_mode_lock(mem_ctx, servicepath, smb_fname,
732 old_write_time);
733 } else {
734 d = parse_share_modes(mem_ctx, value);
737 if (d == NULL) {
738 DEBUG(1, ("Could not get share mode lock\n"));
739 TALLOC_FREE(rec);
740 return NULL;
742 d->id = id;
743 d->record = talloc_move(d, &rec);
744 talloc_set_destructor(d, share_mode_data_destructor);
746 lck = talloc(mem_ctx, struct share_mode_lock);
747 if (lck == NULL) {
748 DEBUG(1, ("talloc failed\n"));
749 TALLOC_FREE(d);
750 return NULL;
752 lck->data = talloc_move(lck, &d);
753 return lck;
756 struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
757 const struct file_id id)
759 return get_share_mode_lock_fresh(mem_ctx, id, NULL, NULL, NULL);
762 struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx,
763 const struct file_id id)
765 struct share_mode_lock *lck;
766 struct file_id tmp;
767 TDB_DATA key = locking_key(&id, &tmp);
768 TDB_DATA data;
769 NTSTATUS status;
771 status = dbwrap_fetch(lock_db, talloc_tos(), key, &data);
772 if (!NT_STATUS_IS_OK(status)) {
773 DEBUG(3, ("Could not fetch share entry\n"));
774 return NULL;
776 if (data.dptr == NULL) {
777 return NULL;
779 lck = talloc(mem_ctx, struct share_mode_lock);
780 if (lck == NULL) {
781 TALLOC_FREE(data.dptr);
782 return NULL;
784 lck->data = parse_share_modes(mem_ctx, data);
785 TALLOC_FREE(data.dptr);
786 if (lck->data == NULL) {
787 TALLOC_FREE(lck);
788 return NULL;
790 return lck;
793 /*******************************************************************
794 Sets the service name and filename for rename.
795 At this point we emit "file renamed" messages to all
796 process id's that have this file open.
797 Based on an initial code idea from SATOH Fumiyasu <fumiya@samba.gr.jp>
798 ********************************************************************/
800 bool rename_share_filename(struct messaging_context *msg_ctx,
801 struct share_mode_lock *lck,
802 const char *servicepath,
803 uint32_t orig_name_hash,
804 uint32_t new_name_hash,
805 const struct smb_filename *smb_fname_dst)
807 struct share_mode_data *d = lck->data;
808 size_t sp_len;
809 size_t bn_len;
810 size_t sn_len;
811 size_t msg_len;
812 char *frm = NULL;
813 int i;
814 bool strip_two_chars = false;
815 bool has_stream = smb_fname_dst->stream_name != NULL;
817 DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n",
818 servicepath, smb_fname_dst->base_name));
821 * rename_internal_fsp() and rename_internals() add './' to
822 * head of newname if newname does not contain a '/'.
824 if (smb_fname_dst->base_name[0] &&
825 smb_fname_dst->base_name[1] &&
826 smb_fname_dst->base_name[0] == '.' &&
827 smb_fname_dst->base_name[1] == '/') {
828 strip_two_chars = true;
831 d->servicepath = talloc_strdup(d, servicepath);
832 d->base_name = talloc_strdup(d, smb_fname_dst->base_name +
833 (strip_two_chars ? 2 : 0));
834 d->stream_name = talloc_strdup(d, smb_fname_dst->stream_name);
835 if (d->base_name == NULL ||
836 (has_stream && d->stream_name == NULL) ||
837 d->servicepath == NULL) {
838 DEBUG(0, ("rename_share_filename: talloc failed\n"));
839 return False;
841 d->modified = True;
843 sp_len = strlen(d->servicepath);
844 bn_len = strlen(d->base_name);
845 sn_len = has_stream ? strlen(d->stream_name) : 0;
847 msg_len = MSG_FILE_RENAMED_MIN_SIZE + sp_len + 1 + bn_len + 1 +
848 sn_len + 1;
850 /* Set up the name changed message. */
851 frm = talloc_array(d, char, msg_len);
852 if (!frm) {
853 return False;
856 push_file_id_24(frm, &d->id);
858 DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len ));
860 strlcpy(&frm[24],
861 d->servicepath ? d->servicepath : "",
862 sp_len+1);
863 strlcpy(&frm[24 + sp_len + 1],
864 d->base_name ? d->base_name : "",
865 bn_len+1);
866 strlcpy(&frm[24 + sp_len + 1 + bn_len + 1],
867 d->stream_name ? d->stream_name : "",
868 sn_len+1);
870 /* Send the messages. */
871 for (i=0; i<d->num_share_modes; i++) {
872 struct share_mode_entry *se = &d->share_modes[i];
873 if (!is_valid_share_mode_entry(se)) {
874 continue;
877 /* If this is a hardlink to the inode
878 with a different name, skip this. */
879 if (se->name_hash != orig_name_hash) {
880 continue;
883 se->name_hash = new_name_hash;
885 /* But not to ourselves... */
886 if (procid_is_me(&se->pid)) {
887 continue;
890 DEBUG(10,("rename_share_filename: sending rename message to "
891 "pid %s file_id %s sharepath %s base_name %s "
892 "stream_name %s\n",
893 procid_str_static(&se->pid),
894 file_id_string_tos(&d->id),
895 d->servicepath, d->base_name,
896 has_stream ? d->stream_name : ""));
898 messaging_send_buf(msg_ctx, se->pid, MSG_SMB_FILE_RENAME,
899 (uint8 *)frm, msg_len);
902 return True;
905 void get_file_infos(struct file_id id,
906 uint32_t name_hash,
907 bool *delete_on_close,
908 struct timespec *write_time)
910 struct share_mode_lock *lck;
912 if (delete_on_close) {
913 *delete_on_close = false;
916 if (write_time) {
917 ZERO_STRUCTP(write_time);
920 if (!(lck = fetch_share_mode_unlocked(talloc_tos(), id))) {
921 return;
924 if (delete_on_close) {
925 *delete_on_close = is_delete_on_close_set(lck, name_hash);
928 if (write_time) {
929 struct timespec wt;
931 wt = lck->data->changed_write_time;
932 if (null_timespec(wt)) {
933 wt = lck->data->old_write_time;
936 *write_time = wt;
939 TALLOC_FREE(lck);
942 bool is_valid_share_mode_entry(const struct share_mode_entry *e)
944 int num_props = 0;
946 num_props += ((e->op_type == NO_OPLOCK) ? 1 : 0);
947 num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0);
948 num_props += (LEVEL_II_OPLOCK_TYPE(e->op_type) ? 1 : 0);
950 SMB_ASSERT(num_props <= 1);
951 return (num_props != 0);
954 bool is_deferred_open_entry(const struct share_mode_entry *e)
956 return (e->op_type == DEFERRED_OPEN_ENTRY);
959 /*******************************************************************
960 Fill a share mode entry.
961 ********************************************************************/
963 static void fill_share_mode_entry(struct share_mode_entry *e,
964 files_struct *fsp,
965 uid_t uid, uint64_t mid, uint16 op_type)
967 ZERO_STRUCTP(e);
968 e->pid = messaging_server_id(fsp->conn->sconn->msg_ctx);
969 e->share_access = fsp->share_access;
970 e->private_options = fsp->fh->private_options;
971 e->access_mask = fsp->access_mask;
972 e->op_mid = mid;
973 e->op_type = op_type;
974 e->time.tv_sec = fsp->open_time.tv_sec;
975 e->time.tv_usec = fsp->open_time.tv_usec;
976 e->id = fsp->file_id;
977 e->share_file_id = fsp->fh->gen_id;
978 e->uid = (uint32)uid;
979 e->flags = fsp->posix_open ? SHARE_MODE_FLAG_POSIX_OPEN : 0;
980 e->name_hash = fsp->name_hash;
983 static void fill_deferred_open_entry(struct share_mode_entry *e,
984 const struct timeval request_time,
985 struct file_id id,
986 struct server_id pid,
987 uint64_t mid)
989 ZERO_STRUCTP(e);
990 e->pid = pid;
991 e->op_mid = mid;
992 e->op_type = DEFERRED_OPEN_ENTRY;
993 e->time.tv_sec = request_time.tv_sec;
994 e->time.tv_usec = request_time.tv_usec;
995 e->id = id;
996 e->uid = (uint32)-1;
997 e->flags = 0;
1000 static void add_share_mode_entry(struct share_mode_data *d,
1001 const struct share_mode_entry *entry)
1003 ADD_TO_ARRAY(d, struct share_mode_entry, *entry,
1004 &d->share_modes, &d->num_share_modes);
1005 d->modified = True;
1008 void set_share_mode(struct share_mode_lock *lck, files_struct *fsp,
1009 uid_t uid, uint64_t mid, uint16 op_type)
1011 struct share_mode_entry entry;
1012 fill_share_mode_entry(&entry, fsp, uid, mid, op_type);
1013 add_share_mode_entry(lck->data, &entry);
1016 void add_deferred_open(struct share_mode_lock *lck, uint64_t mid,
1017 struct timeval request_time,
1018 struct server_id pid, struct file_id id)
1020 struct share_mode_entry entry;
1021 fill_deferred_open_entry(&entry, request_time, id, pid, mid);
1022 add_share_mode_entry(lck->data, &entry);
1025 /*******************************************************************
1026 Check if two share mode entries are identical, ignoring oplock
1027 and mid info and desired_access. (Removed paranoia test - it's
1028 not automatically a logic error if they are identical. JRA.)
1029 ********************************************************************/
1031 static bool share_modes_identical(struct share_mode_entry *e1,
1032 struct share_mode_entry *e2)
1034 /* We used to check for e1->share_access == e2->share_access here
1035 as well as the other fields but 2 different DOS or FCB opens
1036 sharing the same share mode entry may validly differ in
1037 fsp->share_access field. */
1039 return (procid_equal(&e1->pid, &e2->pid) &&
1040 file_id_equal(&e1->id, &e2->id) &&
1041 e1->share_file_id == e2->share_file_id );
1044 static bool deferred_open_identical(struct share_mode_entry *e1,
1045 struct share_mode_entry *e2)
1047 return (procid_equal(&e1->pid, &e2->pid) &&
1048 (e1->op_mid == e2->op_mid) &&
1049 file_id_equal(&e1->id, &e2->id));
1052 static struct share_mode_entry *find_share_mode_entry(struct share_mode_data *d,
1053 struct share_mode_entry *entry)
1055 int i;
1057 for (i=0; i<d->num_share_modes; i++) {
1058 struct share_mode_entry *e = &d->share_modes[i];
1059 if (is_valid_share_mode_entry(entry) &&
1060 is_valid_share_mode_entry(e) &&
1061 share_modes_identical(e, entry)) {
1062 return e;
1064 if (is_deferred_open_entry(entry) &&
1065 is_deferred_open_entry(e) &&
1066 deferred_open_identical(e, entry)) {
1067 return e;
1070 return NULL;
1073 /*******************************************************************
1074 Del the share mode of a file for this process. Return the number of
1075 entries left.
1076 ********************************************************************/
1078 bool del_share_mode(struct share_mode_lock *lck, files_struct *fsp)
1080 struct share_mode_entry entry, *e;
1082 /* Don't care about the pid owner being correct here - just a search. */
1083 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1085 e = find_share_mode_entry(lck->data, &entry);
1086 if (e == NULL) {
1087 return False;
1089 *e = lck->data->share_modes[lck->data->num_share_modes-1];
1090 lck->data->num_share_modes -= 1;
1091 lck->data->modified = True;
1092 return True;
1095 void del_deferred_open_entry(struct share_mode_lock *lck, uint64_t mid,
1096 struct server_id pid)
1098 struct share_mode_entry entry, *e;
1100 fill_deferred_open_entry(&entry, timeval_zero(),
1101 lck->data->id, pid, mid);
1103 e = find_share_mode_entry(lck->data, &entry);
1104 if (e == NULL) {
1105 return;
1107 *e = lck->data->share_modes[lck->data->num_share_modes-1];
1108 lck->data->num_share_modes -= 1;
1109 lck->data->modified = True;
1112 /*******************************************************************
1113 Remove an oplock mid and mode entry from a share mode.
1114 ********************************************************************/
1116 bool remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
1118 struct share_mode_entry entry, *e;
1120 /* Don't care about the pid owner being correct here - just a search. */
1121 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1123 e = find_share_mode_entry(lck->data, &entry);
1124 if (e == NULL) {
1125 return False;
1128 if (EXCLUSIVE_OPLOCK_TYPE(e->op_type)) {
1130 * Going from exclusive or batch,
1131 * we always go through FAKE_LEVEL_II
1132 * first.
1134 if (!EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1135 smb_panic("remove_share_oplock: logic error");
1137 e->op_type = FAKE_LEVEL_II_OPLOCK;
1138 } else {
1139 e->op_type = NO_OPLOCK;
1141 lck->data->modified = True;
1142 return True;
1145 /*******************************************************************
1146 Downgrade a oplock type from exclusive to level II.
1147 ********************************************************************/
1149 bool downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
1151 struct share_mode_entry entry, *e;
1153 /* Don't care about the pid owner being correct here - just a search. */
1154 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1156 e = find_share_mode_entry(lck->data, &entry);
1157 if (e == NULL) {
1158 return False;
1161 e->op_type = LEVEL_II_OPLOCK;
1162 lck->data->modified = True;
1163 return True;
1166 /*************************************************************************
1167 Return a talloced copy of a struct security_unix_token. NULL on fail.
1168 (Should this be in locking.c.... ?).
1169 *************************************************************************/
1171 static struct security_unix_token *copy_unix_token(TALLOC_CTX *ctx, const struct security_unix_token *tok)
1173 struct security_unix_token *cpy;
1175 cpy = talloc(ctx, struct security_unix_token);
1176 if (!cpy) {
1177 return NULL;
1180 cpy->uid = tok->uid;
1181 cpy->gid = tok->gid;
1182 cpy->ngroups = tok->ngroups;
1183 if (tok->ngroups) {
1184 /* Make this a talloc child of cpy. */
1185 cpy->groups = (gid_t *)talloc_memdup(
1186 cpy, tok->groups, tok->ngroups * sizeof(gid_t));
1187 if (!cpy->groups) {
1188 TALLOC_FREE(cpy);
1189 return NULL;
1192 return cpy;
1195 /****************************************************************************
1196 Adds a delete on close token.
1197 ****************************************************************************/
1199 static bool add_delete_on_close_token(struct share_mode_data *d,
1200 uint32_t name_hash,
1201 const struct security_unix_token *tok)
1203 struct delete_token *tmp, *dtl;
1205 tmp = talloc_realloc(d, d->delete_tokens, struct delete_token,
1206 d->num_delete_tokens+1);
1207 if (tmp == NULL) {
1208 return false;
1210 d->delete_tokens = tmp;
1211 dtl = &d->delete_tokens[d->num_delete_tokens];
1213 dtl->name_hash = name_hash;
1214 dtl->delete_token = copy_unix_token(d->delete_tokens, tok);
1215 if (dtl->delete_token == NULL) {
1216 return false;
1218 d->num_delete_tokens += 1;
1219 d->modified = true;
1220 return true;
1223 /****************************************************************************
1224 Sets the delete on close flag over all share modes on this file.
1225 Modify the share mode entry for all files open
1226 on this device and inode to tell other smbds we have
1227 changed the delete on close flag. This will be noticed
1228 in the close code, the last closer will delete the file
1229 if flag is set.
1230 This makes a copy of any struct security_unix_token into the
1231 lck entry. This function is used when the lock is already granted.
1232 ****************************************************************************/
1234 void set_delete_on_close_lck(files_struct *fsp,
1235 struct share_mode_lock *lck,
1236 bool delete_on_close,
1237 const struct security_unix_token *tok)
1239 struct share_mode_data *d = lck->data;
1240 int i;
1241 bool ret;
1243 if (delete_on_close) {
1244 SMB_ASSERT(tok != NULL);
1245 } else {
1246 SMB_ASSERT(tok == NULL);
1249 for (i=0; i<d->num_delete_tokens; i++) {
1250 struct delete_token *dt = &d->delete_tokens[i];
1251 if (dt->name_hash == fsp->name_hash) {
1252 d->modified = true;
1253 if (delete_on_close == false) {
1254 /* Delete this entry. */
1255 TALLOC_FREE(dt->delete_token);
1256 *dt = d->delete_tokens[
1257 d->num_delete_tokens-1];
1258 d->num_delete_tokens -= 1;
1259 return;
1261 /* Replace this token with the
1262 given tok. */
1263 TALLOC_FREE(dt->delete_token);
1264 dt->delete_token = copy_unix_token(dt, tok);
1265 SMB_ASSERT(dt->delete_token != NULL);
1269 if (!delete_on_close) {
1270 /* Nothing to delete - not found. */
1271 return;
1274 ret = add_delete_on_close_token(lck->data, fsp->name_hash, tok);
1275 SMB_ASSERT(ret);
1278 bool set_delete_on_close(files_struct *fsp, bool delete_on_close, const struct security_unix_token *tok)
1280 struct share_mode_lock *lck;
1282 DEBUG(10,("set_delete_on_close: %s delete on close flag for "
1283 "fnum = %d, file %s\n",
1284 delete_on_close ? "Adding" : "Removing", fsp->fnum,
1285 fsp_str_dbg(fsp)));
1287 lck = get_share_mode_lock(talloc_tos(), fsp->file_id);
1288 if (lck == NULL) {
1289 return False;
1292 set_delete_on_close_lck(fsp, lck, delete_on_close,
1293 delete_on_close ? tok : NULL);
1295 if (fsp->is_directory) {
1296 SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name));
1297 send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
1298 fsp->fsp_name->base_name);
1301 TALLOC_FREE(lck);
1303 fsp->delete_on_close = delete_on_close;
1305 return True;
1308 const struct security_unix_token *get_delete_on_close_token(struct share_mode_lock *lck, uint32_t name_hash)
1310 int i;
1312 DEBUG(10,("get_delete_on_close_token: name_hash = 0x%x\n",
1313 (unsigned int)name_hash ));
1315 for (i=0; i<lck->data->num_delete_tokens; i++) {
1316 struct delete_token *dt = &lck->data->delete_tokens[i];
1317 DEBUG(10,("get_delete_on_close_token: dtl->name_hash = 0x%x\n",
1318 (unsigned int)dt->name_hash ));
1319 if (dt->name_hash == name_hash) {
1320 return dt->delete_token;
1323 return NULL;
1326 bool is_delete_on_close_set(struct share_mode_lock *lck, uint32_t name_hash)
1328 return (get_delete_on_close_token(lck, name_hash) != NULL);
1331 bool set_sticky_write_time(struct file_id fileid, struct timespec write_time)
1333 struct share_mode_lock *lck;
1335 DEBUG(5,("set_sticky_write_time: %s id=%s\n",
1336 timestring(talloc_tos(),
1337 convert_timespec_to_time_t(write_time)),
1338 file_id_string_tos(&fileid)));
1340 lck = get_share_mode_lock(talloc_tos(), fileid);
1341 if (lck == NULL) {
1342 return False;
1345 if (timespec_compare(&lck->data->changed_write_time, &write_time) != 0) {
1346 lck->data->modified = True;
1347 lck->data->changed_write_time = write_time;
1350 TALLOC_FREE(lck);
1351 return True;
1354 bool set_write_time(struct file_id fileid, struct timespec write_time)
1356 struct share_mode_lock *lck;
1358 DEBUG(5,("set_write_time: %s id=%s\n",
1359 timestring(talloc_tos(),
1360 convert_timespec_to_time_t(write_time)),
1361 file_id_string_tos(&fileid)));
1363 lck = get_share_mode_lock(talloc_tos(), fileid);
1364 if (lck == NULL) {
1365 return False;
1368 if (timespec_compare(&lck->data->old_write_time, &write_time) != 0) {
1369 lck->data->modified = True;
1370 lck->data->old_write_time = write_time;
1373 TALLOC_FREE(lck);
1374 return True;
1378 struct forall_state {
1379 void (*fn)(const struct share_mode_entry *entry,
1380 const char *sharepath,
1381 const char *fname,
1382 void *private_data);
1383 void *private_data;
1386 static int traverse_fn(struct db_record *rec, void *_state)
1388 struct forall_state *state = (struct forall_state *)_state;
1389 uint32_t i;
1390 TDB_DATA key;
1391 TDB_DATA value;
1392 DATA_BLOB blob;
1393 enum ndr_err_code ndr_err;
1394 struct share_mode_data *d;
1396 key = dbwrap_record_get_key(rec);
1397 value = dbwrap_record_get_value(rec);
1399 /* Ensure this is a locking_key record. */
1400 if (key.dsize != sizeof(struct file_id))
1401 return 0;
1403 d = talloc(talloc_tos(), struct share_mode_data);
1404 if (d == NULL) {
1405 return 0;
1408 blob.data = value.dptr;
1409 blob.length = value.dsize;
1411 ndr_err = ndr_pull_struct_blob(
1412 &blob, d, d, (ndr_pull_flags_fn_t)ndr_pull_share_mode_data);
1413 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1414 DEBUG(1, ("ndr_pull_share_mode_lock failed\n"));
1415 return 0;
1417 for (i=0; i<d->num_share_modes; i++) {
1418 state->fn(&d->share_modes[i],
1419 d->servicepath, d->base_name,
1420 state->private_data);
1422 TALLOC_FREE(d);
1424 return 0;
1427 /*******************************************************************
1428 Call the specified function on each entry under management by the
1429 share mode system.
1430 ********************************************************************/
1432 int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *,
1433 const char *, void *),
1434 void *private_data)
1436 struct forall_state state;
1437 NTSTATUS status;
1438 int count;
1440 if (lock_db == NULL)
1441 return 0;
1443 state.fn = fn;
1444 state.private_data = private_data;
1446 status = dbwrap_traverse_read(lock_db, traverse_fn, (void *)&state,
1447 &count);
1449 if (!NT_STATUS_IS_OK(status)) {
1450 return -1;
1451 } else {
1452 return count;