s3:registry: do not use regdb functions during db upgrade
[Samba/gebeck_regimport.git] / source3 / locking / locking.c
blobcaa2b5aef6417418ed87e576b854f169a8e809f0
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 rewrtten 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 = sconn_server_id(fsp->conn->sconn);
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 sconn_server_id(fsp->conn->sconn),
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 sconn_server_id(fsp->conn->sconn),
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 sconn_server_id(fsp->conn->sconn),
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 sconn_server_id(fsp->conn->sconn),
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]: %s "
499 "pid = %s, share_access = 0x%x, private_options = 0x%x, "
500 "access_mask = 0x%x, mid = 0x%llx, type= 0x%x, gen_id = %lu, "
501 "uid = %u, flags = %u, file_id %s, name_hash = 0x%x",
502 num,
503 e->op_type == UNUSED_SHARE_MODE_ENTRY ? "UNUSED" : "",
504 procid_str_static(&e->pid),
505 e->share_access, e->private_options,
506 e->access_mask, (unsigned long long)e->op_mid,
507 e->op_type, e->share_file_id,
508 (unsigned int)e->uid, (unsigned int)e->flags,
509 file_id_string_tos(&e->id),
510 (unsigned int)e->name_hash);
513 /*******************************************************************
514 Get all share mode entries for a dev/inode pair.
515 ********************************************************************/
517 static bool parse_share_modes(const TDB_DATA dbuf, struct share_mode_lock *lck)
519 int i;
520 struct server_id *pids;
521 bool *pid_exists;
522 enum ndr_err_code ndr_err;
523 DATA_BLOB blob;
525 blob.data = dbuf.dptr;
526 blob.length = dbuf.dsize;
528 ndr_err = ndr_pull_struct_blob(
529 &blob, lck, lck,
530 (ndr_pull_flags_fn_t)ndr_pull_share_mode_lock);
531 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
532 DEBUG(1, ("ndr_pull_share_mode_lock failed\n"));
533 return false;
536 lck->modified = false;
538 if (DEBUGLEVEL >= 10) {
539 DEBUG(10, ("parse_share_modes:\n"));
540 NDR_PRINT_DEBUG(share_mode_lock, lck);
544 * Ensure that each entry has a real process attached.
547 pids = talloc_array(talloc_tos(), struct server_id,
548 lck->num_share_modes);
549 if (pids == NULL) {
550 smb_panic("parse_share_modes: talloc_array failed");
552 pid_exists = talloc_array(talloc_tos(), bool, lck->num_share_modes);
553 if (pid_exists == NULL) {
554 smb_panic("parse_share_modes: talloc_array failed");
557 for (i=0; i<lck->num_share_modes; i++) {
558 pids[i] = lck->share_modes[i].pid;
561 if (!serverids_exist(pids, lck->num_share_modes, pid_exists)) {
562 smb_panic("parse_share_modes: serverids_exist failed");
565 for (i = 0; i < lck->num_share_modes; i++) {
566 struct share_mode_entry *entry_p = &lck->share_modes[i];
567 if (!pid_exists[i]) {
568 entry_p->op_type = UNUSED_SHARE_MODE_ENTRY;
569 lck->modified = True;
572 TALLOC_FREE(pid_exists);
573 TALLOC_FREE(pids);
575 return True;
578 static TDB_DATA unparse_share_modes(struct share_mode_lock *lck)
580 DATA_BLOB blob;
581 enum ndr_err_code ndr_err;
582 uint32_t i;
584 if (DEBUGLEVEL >= 10) {
585 DEBUG(10, ("unparse_share_modes:\n"));
586 NDR_PRINT_DEBUG(share_mode_lock, lck);
589 for (i=0; i<lck->num_share_modes; i++) {
590 if (!is_unused_share_mode_entry(&lck->share_modes[i])) {
591 break;
594 if (i == lck->num_share_modes) {
595 DEBUG(10, ("No used share mode found\n"));
596 return make_tdb_data(NULL, 0);
599 ndr_err = ndr_push_struct_blob(
600 &blob, lck, lck,
601 (ndr_push_flags_fn_t)ndr_push_share_mode_lock);
602 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
603 smb_panic("ndr_push_share_mode_lock failed");
606 return make_tdb_data(blob.data, blob.length);
609 static int share_mode_lock_destructor(struct share_mode_lock *lck)
611 NTSTATUS status;
612 TDB_DATA data;
614 if (!lck->modified) {
615 return 0;
618 data = unparse_share_modes(lck);
620 if (data.dptr == NULL) {
621 if (!lck->fresh) {
622 /* There has been an entry before, delete it */
624 status = dbwrap_record_delete(lck->record);
625 if (!NT_STATUS_IS_OK(status)) {
626 char *errmsg;
628 DEBUG(0, ("delete_rec returned %s\n",
629 nt_errstr(status)));
631 if (asprintf(&errmsg, "could not delete share "
632 "entry: %s\n",
633 nt_errstr(status)) == -1) {
634 smb_panic("could not delete share"
635 "entry");
637 smb_panic(errmsg);
640 goto done;
643 status = dbwrap_record_store(lck->record, data, TDB_REPLACE);
644 if (!NT_STATUS_IS_OK(status)) {
645 char *errmsg;
647 DEBUG(0, ("store returned %s\n", nt_errstr(status)));
649 if (asprintf(&errmsg, "could not store share mode entry: %s",
650 nt_errstr(status)) == -1) {
651 smb_panic("could not store share mode entry");
653 smb_panic(errmsg);
656 done:
658 return 0;
661 static bool fill_share_mode_lock(struct share_mode_lock *lck,
662 struct file_id id,
663 const char *servicepath,
664 const struct smb_filename *smb_fname,
665 TDB_DATA share_mode_data,
666 const struct timespec *old_write_time)
668 bool fresh;
670 /* Ensure we set every field here as the destructor must be
671 valid even if parse_share_modes fails. */
673 lck->servicepath = NULL;
674 lck->base_name = NULL;
675 lck->stream_name = NULL;
676 lck->id = id;
677 lck->num_share_modes = 0;
678 lck->share_modes = NULL;
679 lck->num_delete_tokens = 0;
680 lck->delete_tokens = NULL;
681 ZERO_STRUCT(lck->old_write_time);
682 ZERO_STRUCT(lck->changed_write_time);
684 fresh = (share_mode_data.dptr == NULL);
686 if (fresh) {
687 bool has_stream;
688 if (smb_fname == NULL || servicepath == NULL
689 || old_write_time == NULL) {
690 return False;
693 has_stream = smb_fname->stream_name != NULL;
695 lck->base_name = talloc_strdup(lck, smb_fname->base_name);
696 lck->stream_name = talloc_strdup(lck, smb_fname->stream_name);
697 lck->servicepath = talloc_strdup(lck, servicepath);
698 if (lck->base_name == NULL ||
699 (has_stream && lck->stream_name == NULL) ||
700 lck->servicepath == NULL) {
701 DEBUG(0, ("talloc failed\n"));
702 return False;
704 lck->old_write_time = *old_write_time;
705 lck->modified = false;
706 } else {
707 if (!parse_share_modes(share_mode_data, lck)) {
708 DEBUG(0, ("Could not parse share modes\n"));
709 return False;
712 lck->fresh = fresh;
714 return True;
717 struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
718 const struct file_id id,
719 const char *servicepath,
720 const struct smb_filename *smb_fname,
721 const struct timespec *old_write_time)
723 struct share_mode_lock *lck;
724 struct file_id tmp;
725 struct db_record *rec;
726 TDB_DATA key = locking_key(&id, &tmp);
727 TDB_DATA value;
729 if (!(lck = talloc(mem_ctx, struct share_mode_lock))) {
730 DEBUG(0, ("talloc failed\n"));
731 return NULL;
734 rec = dbwrap_fetch_locked(lock_db, lck, key);
735 if (rec == NULL) {
736 DEBUG(3, ("Could not lock share entry\n"));
737 TALLOC_FREE(lck);
738 return NULL;
741 value = dbwrap_record_get_value(rec);
743 if (!fill_share_mode_lock(lck, id, servicepath, smb_fname,
744 value, old_write_time)) {
745 DEBUG(3, ("fill_share_mode_lock failed\n"));
746 TALLOC_FREE(lck);
747 return NULL;
750 lck->record = rec;
751 talloc_set_destructor(lck, share_mode_lock_destructor);
753 return lck;
756 struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx,
757 const struct file_id id)
759 struct share_mode_lock *lck;
760 struct file_id tmp;
761 TDB_DATA key = locking_key(&id, &tmp);
762 TDB_DATA data;
763 NTSTATUS status;
765 if (!(lck = talloc(mem_ctx, struct share_mode_lock))) {
766 DEBUG(0, ("talloc failed\n"));
767 return NULL;
770 status = dbwrap_fetch(lock_db, lck, key, &data);
771 if (!NT_STATUS_IS_OK(status)) {
772 DEBUG(3, ("Could not fetch share entry\n"));
773 TALLOC_FREE(lck);
774 return NULL;
777 if (!fill_share_mode_lock(lck, id, NULL, NULL, data, NULL)) {
778 DEBUG(10, ("fetch_share_mode_unlocked: no share_mode record "
779 "around (file not open)\n"));
780 TALLOC_FREE(lck);
781 return NULL;
784 return lck;
787 /*******************************************************************
788 Sets the service name and filename for rename.
789 At this point we emit "file renamed" messages to all
790 process id's that have this file open.
791 Based on an initial code idea from SATOH Fumiyasu <fumiya@samba.gr.jp>
792 ********************************************************************/
794 bool rename_share_filename(struct messaging_context *msg_ctx,
795 struct share_mode_lock *lck,
796 const char *servicepath,
797 uint32_t orig_name_hash,
798 uint32_t new_name_hash,
799 const struct smb_filename *smb_fname_dst)
801 size_t sp_len;
802 size_t bn_len;
803 size_t sn_len;
804 size_t msg_len;
805 char *frm = NULL;
806 int i;
807 bool strip_two_chars = false;
808 bool has_stream = smb_fname_dst->stream_name != NULL;
810 DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n",
811 servicepath, smb_fname_dst->base_name));
814 * rename_internal_fsp() and rename_internals() add './' to
815 * head of newname if newname does not contain a '/'.
817 if (smb_fname_dst->base_name[0] &&
818 smb_fname_dst->base_name[1] &&
819 smb_fname_dst->base_name[0] == '.' &&
820 smb_fname_dst->base_name[1] == '/') {
821 strip_two_chars = true;
824 lck->servicepath = talloc_strdup(lck, servicepath);
825 lck->base_name = talloc_strdup(lck, smb_fname_dst->base_name +
826 (strip_two_chars ? 2 : 0));
827 lck->stream_name = talloc_strdup(lck, smb_fname_dst->stream_name);
828 if (lck->base_name == NULL ||
829 (has_stream && lck->stream_name == NULL) ||
830 lck->servicepath == NULL) {
831 DEBUG(0, ("rename_share_filename: talloc failed\n"));
832 return False;
834 lck->modified = True;
836 sp_len = strlen(lck->servicepath);
837 bn_len = strlen(lck->base_name);
838 sn_len = has_stream ? strlen(lck->stream_name) : 0;
840 msg_len = MSG_FILE_RENAMED_MIN_SIZE + sp_len + 1 + bn_len + 1 +
841 sn_len + 1;
843 /* Set up the name changed message. */
844 frm = talloc_array(lck, char, msg_len);
845 if (!frm) {
846 return False;
849 push_file_id_24(frm, &lck->id);
851 DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len ));
853 strlcpy(&frm[24],
854 lck->servicepath ? lck->servicepath : "",
855 sp_len+1);
856 strlcpy(&frm[24 + sp_len + 1],
857 lck->base_name ? lck->base_name : "",
858 bn_len+1);
859 strlcpy(&frm[24 + sp_len + 1 + bn_len + 1],
860 lck->stream_name ? lck->stream_name : "",
861 sn_len+1);
863 /* Send the messages. */
864 for (i=0; i<lck->num_share_modes; i++) {
865 struct share_mode_entry *se = &lck->share_modes[i];
866 if (!is_valid_share_mode_entry(se)) {
867 continue;
870 /* If this is a hardlink to the inode
871 with a different name, skip this. */
872 if (se->name_hash != orig_name_hash) {
873 continue;
876 se->name_hash = new_name_hash;
878 /* But not to ourselves... */
879 if (procid_is_me(&se->pid)) {
880 continue;
883 DEBUG(10,("rename_share_filename: sending rename message to "
884 "pid %s file_id %s sharepath %s base_name %s "
885 "stream_name %s\n",
886 procid_str_static(&se->pid),
887 file_id_string_tos(&lck->id),
888 lck->servicepath, lck->base_name,
889 has_stream ? lck->stream_name : ""));
891 messaging_send_buf(msg_ctx, se->pid, MSG_SMB_FILE_RENAME,
892 (uint8 *)frm, msg_len);
895 return True;
898 void get_file_infos(struct file_id id,
899 uint32_t name_hash,
900 bool *delete_on_close,
901 struct timespec *write_time)
903 struct share_mode_lock *lck;
905 if (delete_on_close) {
906 *delete_on_close = false;
909 if (write_time) {
910 ZERO_STRUCTP(write_time);
913 if (!(lck = fetch_share_mode_unlocked(talloc_tos(), id))) {
914 return;
917 if (delete_on_close) {
918 *delete_on_close = is_delete_on_close_set(lck, name_hash);
921 if (write_time) {
922 struct timespec wt;
924 wt = lck->changed_write_time;
925 if (null_timespec(wt)) {
926 wt = lck->old_write_time;
929 *write_time = wt;
932 TALLOC_FREE(lck);
935 bool is_valid_share_mode_entry(const struct share_mode_entry *e)
937 int num_props = 0;
939 if (e->op_type == UNUSED_SHARE_MODE_ENTRY) {
940 /* cope with dead entries from the process not
941 existing. These should not be considered valid,
942 otherwise we end up doing zero timeout sharing
943 violation */
944 return False;
947 num_props += ((e->op_type == NO_OPLOCK) ? 1 : 0);
948 num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0);
949 num_props += (LEVEL_II_OPLOCK_TYPE(e->op_type) ? 1 : 0);
951 SMB_ASSERT(num_props <= 1);
952 return (num_props != 0);
955 bool is_deferred_open_entry(const struct share_mode_entry *e)
957 return (e->op_type == DEFERRED_OPEN_ENTRY);
960 bool is_unused_share_mode_entry(const struct share_mode_entry *e)
962 return (e->op_type == UNUSED_SHARE_MODE_ENTRY);
965 /*******************************************************************
966 Fill a share mode entry.
967 ********************************************************************/
969 static void fill_share_mode_entry(struct share_mode_entry *e,
970 files_struct *fsp,
971 uid_t uid, uint64_t mid, uint16 op_type)
973 ZERO_STRUCTP(e);
974 e->pid = sconn_server_id(fsp->conn->sconn);
975 e->share_access = fsp->share_access;
976 e->private_options = fsp->fh->private_options;
977 e->access_mask = fsp->access_mask;
978 e->op_mid = mid;
979 e->op_type = op_type;
980 e->time.tv_sec = fsp->open_time.tv_sec;
981 e->time.tv_usec = fsp->open_time.tv_usec;
982 e->id = fsp->file_id;
983 e->share_file_id = fsp->fh->gen_id;
984 e->uid = (uint32)uid;
985 e->flags = fsp->posix_open ? SHARE_MODE_FLAG_POSIX_OPEN : 0;
986 e->name_hash = fsp->name_hash;
989 static void fill_deferred_open_entry(struct share_mode_entry *e,
990 const struct timeval request_time,
991 struct file_id id,
992 struct server_id pid,
993 uint64_t mid)
995 ZERO_STRUCTP(e);
996 e->pid = pid;
997 e->op_mid = mid;
998 e->op_type = DEFERRED_OPEN_ENTRY;
999 e->time.tv_sec = request_time.tv_sec;
1000 e->time.tv_usec = request_time.tv_usec;
1001 e->id = id;
1002 e->uid = (uint32)-1;
1003 e->flags = 0;
1006 static void add_share_mode_entry(struct share_mode_lock *lck,
1007 const struct share_mode_entry *entry)
1009 int i;
1011 for (i=0; i<lck->num_share_modes; i++) {
1012 struct share_mode_entry *e = &lck->share_modes[i];
1013 if (is_unused_share_mode_entry(e)) {
1014 *e = *entry;
1015 break;
1019 if (i == lck->num_share_modes) {
1020 /* No unused entry found */
1021 ADD_TO_ARRAY(lck, struct share_mode_entry, *entry,
1022 &lck->share_modes, &lck->num_share_modes);
1024 lck->modified = True;
1027 void set_share_mode(struct share_mode_lock *lck, files_struct *fsp,
1028 uid_t uid, uint64_t mid, uint16 op_type)
1030 struct share_mode_entry entry;
1031 fill_share_mode_entry(&entry, fsp, uid, mid, op_type);
1032 add_share_mode_entry(lck, &entry);
1035 void add_deferred_open(struct share_mode_lock *lck, uint64_t mid,
1036 struct timeval request_time,
1037 struct server_id pid, struct file_id id)
1039 struct share_mode_entry entry;
1040 fill_deferred_open_entry(&entry, request_time, id, pid, mid);
1041 add_share_mode_entry(lck, &entry);
1044 /*******************************************************************
1045 Check if two share mode entries are identical, ignoring oplock
1046 and mid info and desired_access. (Removed paranoia test - it's
1047 not automatically a logic error if they are identical. JRA.)
1048 ********************************************************************/
1050 static bool share_modes_identical(struct share_mode_entry *e1,
1051 struct share_mode_entry *e2)
1053 /* We used to check for e1->share_access == e2->share_access here
1054 as well as the other fields but 2 different DOS or FCB opens
1055 sharing the same share mode entry may validly differ in
1056 fsp->share_access field. */
1058 return (procid_equal(&e1->pid, &e2->pid) &&
1059 file_id_equal(&e1->id, &e2->id) &&
1060 e1->share_file_id == e2->share_file_id );
1063 static bool deferred_open_identical(struct share_mode_entry *e1,
1064 struct share_mode_entry *e2)
1066 return (procid_equal(&e1->pid, &e2->pid) &&
1067 (e1->op_mid == e2->op_mid) &&
1068 file_id_equal(&e1->id, &e2->id));
1071 static struct share_mode_entry *find_share_mode_entry(struct share_mode_lock *lck,
1072 struct share_mode_entry *entry)
1074 int i;
1076 for (i=0; i<lck->num_share_modes; i++) {
1077 struct share_mode_entry *e = &lck->share_modes[i];
1078 if (is_valid_share_mode_entry(entry) &&
1079 is_valid_share_mode_entry(e) &&
1080 share_modes_identical(e, entry)) {
1081 return e;
1083 if (is_deferred_open_entry(entry) &&
1084 is_deferred_open_entry(e) &&
1085 deferred_open_identical(e, entry)) {
1086 return e;
1089 return NULL;
1092 /*******************************************************************
1093 Del the share mode of a file for this process. Return the number of
1094 entries left.
1095 ********************************************************************/
1097 bool del_share_mode(struct share_mode_lock *lck, files_struct *fsp)
1099 struct share_mode_entry entry, *e;
1101 /* Don't care about the pid owner being correct here - just a search. */
1102 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1104 e = find_share_mode_entry(lck, &entry);
1105 if (e == NULL) {
1106 return False;
1109 e->op_type = UNUSED_SHARE_MODE_ENTRY;
1110 lck->modified = True;
1111 return True;
1114 void del_deferred_open_entry(struct share_mode_lock *lck, uint64_t mid,
1115 struct server_id pid)
1117 struct share_mode_entry entry, *e;
1119 fill_deferred_open_entry(&entry, timeval_zero(),
1120 lck->id, pid, mid);
1122 e = find_share_mode_entry(lck, &entry);
1123 if (e == NULL) {
1124 return;
1127 e->op_type = UNUSED_SHARE_MODE_ENTRY;
1128 lck->modified = True;
1131 /*******************************************************************
1132 Remove an oplock mid and mode entry from a share mode.
1133 ********************************************************************/
1135 bool remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
1137 struct share_mode_entry entry, *e;
1139 /* Don't care about the pid owner being correct here - just a search. */
1140 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1142 e = find_share_mode_entry(lck, &entry);
1143 if (e == NULL) {
1144 return False;
1147 if (EXCLUSIVE_OPLOCK_TYPE(e->op_type)) {
1149 * Going from exclusive or batch,
1150 * we always go through FAKE_LEVEL_II
1151 * first.
1153 if (!EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1154 smb_panic("remove_share_oplock: logic error");
1156 e->op_type = FAKE_LEVEL_II_OPLOCK;
1157 } else {
1158 e->op_type = NO_OPLOCK;
1160 lck->modified = True;
1161 return True;
1164 /*******************************************************************
1165 Downgrade a oplock type from exclusive to level II.
1166 ********************************************************************/
1168 bool downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
1170 struct share_mode_entry entry, *e;
1172 /* Don't care about the pid owner being correct here - just a search. */
1173 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1175 e = find_share_mode_entry(lck, &entry);
1176 if (e == NULL) {
1177 return False;
1180 e->op_type = LEVEL_II_OPLOCK;
1181 lck->modified = True;
1182 return True;
1185 /****************************************************************************
1186 Check if setting delete on close is allowed on this fsp.
1187 ****************************************************************************/
1189 NTSTATUS can_set_delete_on_close(files_struct *fsp, uint32 dosmode)
1192 * Only allow delete on close for writable files.
1195 if ((dosmode & FILE_ATTRIBUTE_READONLY) &&
1196 !lp_delete_readonly(SNUM(fsp->conn))) {
1197 DEBUG(10,("can_set_delete_on_close: file %s delete on close "
1198 "flag set but file attribute is readonly.\n",
1199 fsp_str_dbg(fsp)));
1200 return NT_STATUS_CANNOT_DELETE;
1204 * Only allow delete on close for writable shares.
1207 if (!CAN_WRITE(fsp->conn)) {
1208 DEBUG(10,("can_set_delete_on_close: file %s delete on "
1209 "close flag set but write access denied on share.\n",
1210 fsp_str_dbg(fsp)));
1211 return NT_STATUS_ACCESS_DENIED;
1215 * Only allow delete on close for files/directories opened with delete
1216 * intent.
1219 if (!(fsp->access_mask & DELETE_ACCESS)) {
1220 DEBUG(10,("can_set_delete_on_close: file %s delete on "
1221 "close flag set but delete access denied.\n",
1222 fsp_str_dbg(fsp)));
1223 return NT_STATUS_ACCESS_DENIED;
1226 /* Don't allow delete on close for non-empty directories. */
1227 if (fsp->is_directory) {
1228 SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name));
1230 /* Or the root of a share. */
1231 if (ISDOT(fsp->fsp_name->base_name)) {
1232 DEBUG(10,("can_set_delete_on_close: can't set delete on "
1233 "close for the root of a share.\n"));
1234 return NT_STATUS_ACCESS_DENIED;
1237 return can_delete_directory(fsp->conn,
1238 fsp->fsp_name->base_name);
1241 return NT_STATUS_OK;
1244 /*************************************************************************
1245 Return a talloced copy of a struct security_unix_token. NULL on fail.
1246 (Should this be in locking.c.... ?).
1247 *************************************************************************/
1249 static struct security_unix_token *copy_unix_token(TALLOC_CTX *ctx, const struct security_unix_token *tok)
1251 struct security_unix_token *cpy;
1253 cpy = talloc(ctx, struct security_unix_token);
1254 if (!cpy) {
1255 return NULL;
1258 cpy->uid = tok->uid;
1259 cpy->gid = tok->gid;
1260 cpy->ngroups = tok->ngroups;
1261 if (tok->ngroups) {
1262 /* Make this a talloc child of cpy. */
1263 cpy->groups = (gid_t *)talloc_memdup(
1264 cpy, tok->groups, tok->ngroups * sizeof(gid_t));
1265 if (!cpy->groups) {
1266 TALLOC_FREE(cpy);
1267 return NULL;
1270 return cpy;
1273 /****************************************************************************
1274 Adds a delete on close token.
1275 ****************************************************************************/
1277 static bool add_delete_on_close_token(struct share_mode_lock *lck,
1278 uint32_t name_hash,
1279 const struct security_unix_token *tok)
1281 struct delete_token *tmp, *dtl;
1283 tmp = talloc_realloc(lck, lck->delete_tokens, struct delete_token,
1284 lck->num_delete_tokens+1);
1285 if (tmp == NULL) {
1286 return false;
1288 lck->delete_tokens = tmp;
1289 dtl = &lck->delete_tokens[lck->num_delete_tokens];
1291 dtl->name_hash = name_hash;
1292 dtl->delete_token = copy_unix_token(lck->delete_tokens, tok);
1293 if (dtl->delete_token == NULL) {
1294 return false;
1296 lck->num_delete_tokens += 1;
1297 lck->modified = true;
1298 return true;
1301 /****************************************************************************
1302 Sets the delete on close flag over all share modes on this file.
1303 Modify the share mode entry for all files open
1304 on this device and inode to tell other smbds we have
1305 changed the delete on close flag. This will be noticed
1306 in the close code, the last closer will delete the file
1307 if flag is set.
1308 This makes a copy of any struct security_unix_token into the
1309 lck entry. This function is used when the lock is already granted.
1310 ****************************************************************************/
1312 void set_delete_on_close_lck(files_struct *fsp,
1313 struct share_mode_lock *lck,
1314 bool delete_on_close,
1315 const struct security_unix_token *tok)
1317 int i;
1318 bool ret;
1320 if (delete_on_close) {
1321 SMB_ASSERT(tok != NULL);
1322 } else {
1323 SMB_ASSERT(tok == NULL);
1326 for (i=0; i<lck->num_delete_tokens; i++) {
1327 struct delete_token *dt = &lck->delete_tokens[i];
1328 if (dt->name_hash == fsp->name_hash) {
1329 lck->modified = true;
1330 if (delete_on_close == false) {
1331 /* Delete this entry. */
1332 TALLOC_FREE(dt->delete_token);
1333 *dt = lck->delete_tokens[
1334 lck->num_delete_tokens-1];
1335 lck->num_delete_tokens -= 1;
1336 return;
1338 /* Replace this token with the
1339 given tok. */
1340 TALLOC_FREE(dt->delete_token);
1341 dt->delete_token = copy_unix_token(dt, tok);
1342 SMB_ASSERT(dt->delete_token != NULL);
1346 if (!delete_on_close) {
1347 /* Nothing to delete - not found. */
1348 return;
1351 ret = add_delete_on_close_token(lck, fsp->name_hash, tok);
1352 SMB_ASSERT(ret);
1355 bool set_delete_on_close(files_struct *fsp, bool delete_on_close, const struct security_unix_token *tok)
1357 struct share_mode_lock *lck;
1359 DEBUG(10,("set_delete_on_close: %s delete on close flag for "
1360 "fnum = %d, file %s\n",
1361 delete_on_close ? "Adding" : "Removing", fsp->fnum,
1362 fsp_str_dbg(fsp)));
1364 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
1365 NULL);
1366 if (lck == NULL) {
1367 return False;
1370 set_delete_on_close_lck(fsp, lck, delete_on_close,
1371 delete_on_close ? tok : NULL);
1373 if (fsp->is_directory) {
1374 SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name));
1375 send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
1376 fsp->fsp_name->base_name);
1379 TALLOC_FREE(lck);
1381 fsp->delete_on_close = delete_on_close;
1383 return True;
1386 const struct security_unix_token *get_delete_on_close_token(struct share_mode_lock *lck, uint32_t name_hash)
1388 int i;
1390 DEBUG(10,("get_delete_on_close_token: name_hash = 0x%x\n",
1391 (unsigned int)name_hash ));
1393 for (i=0; i<lck->num_delete_tokens; i++) {
1394 struct delete_token *dt = &lck->delete_tokens[i];
1395 DEBUG(10,("get_delete_on_close_token: dtl->name_hash = 0x%x\n",
1396 (unsigned int)dt->name_hash ));
1397 if (dt->name_hash == name_hash) {
1398 return dt->delete_token;
1401 return NULL;
1404 bool is_delete_on_close_set(struct share_mode_lock *lck, uint32_t name_hash)
1406 return (get_delete_on_close_token(lck, name_hash) != NULL);
1409 bool set_sticky_write_time(struct file_id fileid, struct timespec write_time)
1411 struct share_mode_lock *lck;
1413 DEBUG(5,("set_sticky_write_time: %s id=%s\n",
1414 timestring(talloc_tos(),
1415 convert_timespec_to_time_t(write_time)),
1416 file_id_string_tos(&fileid)));
1418 lck = get_share_mode_lock(NULL, fileid, NULL, NULL, NULL);
1419 if (lck == NULL) {
1420 return False;
1423 if (timespec_compare(&lck->changed_write_time, &write_time) != 0) {
1424 lck->modified = True;
1425 lck->changed_write_time = write_time;
1428 TALLOC_FREE(lck);
1429 return True;
1432 bool set_write_time(struct file_id fileid, struct timespec write_time)
1434 struct share_mode_lock *lck;
1436 DEBUG(5,("set_write_time: %s id=%s\n",
1437 timestring(talloc_tos(),
1438 convert_timespec_to_time_t(write_time)),
1439 file_id_string_tos(&fileid)));
1441 lck = get_share_mode_lock(NULL, fileid, NULL, NULL, NULL);
1442 if (lck == NULL) {
1443 return False;
1446 if (timespec_compare(&lck->old_write_time, &write_time) != 0) {
1447 lck->modified = True;
1448 lck->old_write_time = write_time;
1451 TALLOC_FREE(lck);
1452 return True;
1456 struct forall_state {
1457 void (*fn)(const struct share_mode_entry *entry,
1458 const char *sharepath,
1459 const char *fname,
1460 void *private_data);
1461 void *private_data;
1464 static int traverse_fn(struct db_record *rec, void *_state)
1466 struct forall_state *state = (struct forall_state *)_state;
1467 uint32_t i;
1468 TDB_DATA key;
1469 TDB_DATA value;
1470 DATA_BLOB blob;
1471 enum ndr_err_code ndr_err;
1472 struct share_mode_lock *lck;
1474 key = dbwrap_record_get_key(rec);
1475 value = dbwrap_record_get_value(rec);
1477 /* Ensure this is a locking_key record. */
1478 if (key.dsize != sizeof(struct file_id))
1479 return 0;
1481 lck = talloc(talloc_tos(), struct share_mode_lock);
1482 if (lck == NULL) {
1483 return 0;
1486 blob.data = value.dptr;
1487 blob.length = value.dsize;
1489 ndr_err = ndr_pull_struct_blob(
1490 &blob, lck, lck,
1491 (ndr_pull_flags_fn_t)ndr_pull_share_mode_lock);
1492 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1493 DEBUG(1, ("ndr_pull_share_mode_lock failed\n"));
1494 return 0;
1496 for (i=0; i<lck->num_share_modes; i++) {
1497 state->fn(&lck->share_modes[i],
1498 lck->servicepath, lck->base_name,
1499 state->private_data);
1501 TALLOC_FREE(lck);
1503 return 0;
1506 /*******************************************************************
1507 Call the specified function on each entry under management by the
1508 share mode system.
1509 ********************************************************************/
1511 int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *,
1512 const char *, void *),
1513 void *private_data)
1515 struct forall_state state;
1516 NTSTATUS status;
1517 int count;
1519 if (lock_db == NULL)
1520 return 0;
1522 state.fn = fn;
1523 state.private_data = private_data;
1525 status = dbwrap_traverse_read(lock_db, traverse_fn, (void *)&state,
1526 &count);
1528 if (!NT_STATUS_IS_OK(status)) {
1529 return -1;
1530 } else {
1531 return count;