s3: Fix a 64-bit warning
[Samba/gebeck_regimport.git] / source3 / locking / locking.c
blob0c457b7a33dd444e211dfe83a1e26220fe230a7a
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, 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 bool parse_share_modes(const TDB_DATA dbuf, struct share_mode_lock *lck)
518 int i;
519 struct server_id *pids;
520 bool *pid_exists;
521 enum ndr_err_code ndr_err;
522 DATA_BLOB blob;
524 blob.data = dbuf.dptr;
525 blob.length = dbuf.dsize;
527 ndr_err = ndr_pull_struct_blob(
528 &blob, lck, lck,
529 (ndr_pull_flags_fn_t)ndr_pull_share_mode_lock);
530 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
531 DEBUG(1, ("ndr_pull_share_mode_lock failed\n"));
532 return false;
535 lck->modified = false;
537 if (DEBUGLEVEL >= 10) {
538 DEBUG(10, ("parse_share_modes:\n"));
539 NDR_PRINT_DEBUG(share_mode_lock, lck);
543 * Ensure that each entry has a real process attached.
546 pids = talloc_array(talloc_tos(), struct server_id,
547 lck->num_share_modes);
548 if (pids == NULL) {
549 smb_panic("parse_share_modes: talloc_array failed");
551 pid_exists = talloc_array(talloc_tos(), bool, lck->num_share_modes);
552 if (pid_exists == NULL) {
553 smb_panic("parse_share_modes: talloc_array failed");
556 for (i=0; i<lck->num_share_modes; i++) {
557 pids[i] = lck->share_modes[i].pid;
560 if (!serverids_exist(pids, lck->num_share_modes, pid_exists)) {
561 smb_panic("parse_share_modes: serverids_exist failed");
564 i = 0;
565 while (i < lck->num_share_modes) {
566 struct share_mode_entry *e = &lck->share_modes[i];
567 if (!pid_exists[i]) {
568 *e = lck->share_modes[lck->num_share_modes-1];
569 lck->num_share_modes -= 1;
570 lck->modified = True;
571 continue;
573 i += 1;
575 TALLOC_FREE(pid_exists);
576 TALLOC_FREE(pids);
578 return True;
581 static TDB_DATA unparse_share_modes(struct share_mode_lock *lck)
583 DATA_BLOB blob;
584 enum ndr_err_code ndr_err;
586 if (DEBUGLEVEL >= 10) {
587 DEBUG(10, ("unparse_share_modes:\n"));
588 NDR_PRINT_DEBUG(share_mode_lock, lck);
591 if (lck->num_share_modes == 0) {
592 DEBUG(10, ("No used share mode found\n"));
593 return make_tdb_data(NULL, 0);
596 ndr_err = ndr_push_struct_blob(
597 &blob, lck, lck,
598 (ndr_push_flags_fn_t)ndr_push_share_mode_lock);
599 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
600 smb_panic("ndr_push_share_mode_lock failed");
603 return make_tdb_data(blob.data, blob.length);
606 static int share_mode_lock_destructor(struct share_mode_lock *lck)
608 NTSTATUS status;
609 TDB_DATA data;
611 if (!lck->modified) {
612 return 0;
615 data = unparse_share_modes(lck);
617 if (data.dptr == NULL) {
618 if (!lck->fresh) {
619 /* There has been an entry before, delete it */
621 status = dbwrap_record_delete(lck->record);
622 if (!NT_STATUS_IS_OK(status)) {
623 char *errmsg;
625 DEBUG(0, ("delete_rec returned %s\n",
626 nt_errstr(status)));
628 if (asprintf(&errmsg, "could not delete share "
629 "entry: %s\n",
630 nt_errstr(status)) == -1) {
631 smb_panic("could not delete share"
632 "entry");
634 smb_panic(errmsg);
637 goto done;
640 status = dbwrap_record_store(lck->record, data, TDB_REPLACE);
641 if (!NT_STATUS_IS_OK(status)) {
642 char *errmsg;
644 DEBUG(0, ("store returned %s\n", nt_errstr(status)));
646 if (asprintf(&errmsg, "could not store share mode entry: %s",
647 nt_errstr(status)) == -1) {
648 smb_panic("could not store share mode entry");
650 smb_panic(errmsg);
653 done:
655 return 0;
658 static bool fill_share_mode_lock(struct share_mode_lock *lck,
659 struct file_id id,
660 const char *servicepath,
661 const struct smb_filename *smb_fname,
662 TDB_DATA share_mode_data,
663 const struct timespec *old_write_time)
665 bool fresh;
667 /* Ensure we set every field here as the destructor must be
668 valid even if parse_share_modes fails. */
670 lck->servicepath = NULL;
671 lck->base_name = NULL;
672 lck->stream_name = NULL;
673 lck->id = id;
674 lck->num_share_modes = 0;
675 lck->share_modes = NULL;
676 lck->num_delete_tokens = 0;
677 lck->delete_tokens = NULL;
678 ZERO_STRUCT(lck->old_write_time);
679 ZERO_STRUCT(lck->changed_write_time);
681 fresh = (share_mode_data.dptr == NULL);
683 if (fresh) {
684 bool has_stream;
685 if (smb_fname == NULL || servicepath == NULL
686 || old_write_time == NULL) {
687 return False;
690 has_stream = smb_fname->stream_name != NULL;
692 lck->base_name = talloc_strdup(lck, smb_fname->base_name);
693 lck->stream_name = talloc_strdup(lck, smb_fname->stream_name);
694 lck->servicepath = talloc_strdup(lck, servicepath);
695 if (lck->base_name == NULL ||
696 (has_stream && lck->stream_name == NULL) ||
697 lck->servicepath == NULL) {
698 DEBUG(0, ("talloc failed\n"));
699 return False;
701 lck->old_write_time = *old_write_time;
702 lck->modified = false;
703 } else {
704 if (!parse_share_modes(share_mode_data, lck)) {
705 DEBUG(0, ("Could not parse share modes\n"));
706 return False;
709 lck->fresh = fresh;
711 return True;
714 struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
715 const struct file_id id,
716 const char *servicepath,
717 const struct smb_filename *smb_fname,
718 const struct timespec *old_write_time)
720 struct share_mode_lock *lck;
721 struct file_id tmp;
722 struct db_record *rec;
723 TDB_DATA key = locking_key(&id, &tmp);
724 TDB_DATA value;
726 if (!(lck = talloc(mem_ctx, struct share_mode_lock))) {
727 DEBUG(0, ("talloc failed\n"));
728 return NULL;
731 rec = dbwrap_fetch_locked(lock_db, lck, key);
732 if (rec == NULL) {
733 DEBUG(3, ("Could not lock share entry\n"));
734 TALLOC_FREE(lck);
735 return NULL;
738 value = dbwrap_record_get_value(rec);
740 if (!fill_share_mode_lock(lck, id, servicepath, smb_fname,
741 value, old_write_time)) {
742 DEBUG(3, ("fill_share_mode_lock failed\n"));
743 TALLOC_FREE(lck);
744 return NULL;
747 lck->record = rec;
748 talloc_set_destructor(lck, share_mode_lock_destructor);
750 return lck;
753 struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx,
754 const struct file_id id)
756 struct share_mode_lock *lck;
757 struct file_id tmp;
758 TDB_DATA key = locking_key(&id, &tmp);
759 TDB_DATA data;
760 NTSTATUS status;
762 if (!(lck = talloc(mem_ctx, struct share_mode_lock))) {
763 DEBUG(0, ("talloc failed\n"));
764 return NULL;
767 status = dbwrap_fetch(lock_db, lck, key, &data);
768 if (!NT_STATUS_IS_OK(status)) {
769 DEBUG(3, ("Could not fetch share entry\n"));
770 TALLOC_FREE(lck);
771 return NULL;
773 if (data.dptr == NULL) {
774 TALLOC_FREE(lck);
775 return NULL;
778 if (!fill_share_mode_lock(lck, id, NULL, NULL, data, NULL)) {
779 DEBUG(10, ("fetch_share_mode_unlocked: no share_mode record "
780 "around (file not open)\n"));
781 TALLOC_FREE(lck);
782 return NULL;
785 return lck;
788 /*******************************************************************
789 Sets the service name and filename for rename.
790 At this point we emit "file renamed" messages to all
791 process id's that have this file open.
792 Based on an initial code idea from SATOH Fumiyasu <fumiya@samba.gr.jp>
793 ********************************************************************/
795 bool rename_share_filename(struct messaging_context *msg_ctx,
796 struct share_mode_lock *lck,
797 const char *servicepath,
798 uint32_t orig_name_hash,
799 uint32_t new_name_hash,
800 const struct smb_filename *smb_fname_dst)
802 size_t sp_len;
803 size_t bn_len;
804 size_t sn_len;
805 size_t msg_len;
806 char *frm = NULL;
807 int i;
808 bool strip_two_chars = false;
809 bool has_stream = smb_fname_dst->stream_name != NULL;
811 DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n",
812 servicepath, smb_fname_dst->base_name));
815 * rename_internal_fsp() and rename_internals() add './' to
816 * head of newname if newname does not contain a '/'.
818 if (smb_fname_dst->base_name[0] &&
819 smb_fname_dst->base_name[1] &&
820 smb_fname_dst->base_name[0] == '.' &&
821 smb_fname_dst->base_name[1] == '/') {
822 strip_two_chars = true;
825 lck->servicepath = talloc_strdup(lck, servicepath);
826 lck->base_name = talloc_strdup(lck, smb_fname_dst->base_name +
827 (strip_two_chars ? 2 : 0));
828 lck->stream_name = talloc_strdup(lck, smb_fname_dst->stream_name);
829 if (lck->base_name == NULL ||
830 (has_stream && lck->stream_name == NULL) ||
831 lck->servicepath == NULL) {
832 DEBUG(0, ("rename_share_filename: talloc failed\n"));
833 return False;
835 lck->modified = True;
837 sp_len = strlen(lck->servicepath);
838 bn_len = strlen(lck->base_name);
839 sn_len = has_stream ? strlen(lck->stream_name) : 0;
841 msg_len = MSG_FILE_RENAMED_MIN_SIZE + sp_len + 1 + bn_len + 1 +
842 sn_len + 1;
844 /* Set up the name changed message. */
845 frm = talloc_array(lck, char, msg_len);
846 if (!frm) {
847 return False;
850 push_file_id_24(frm, &lck->id);
852 DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len ));
854 strlcpy(&frm[24],
855 lck->servicepath ? lck->servicepath : "",
856 sp_len+1);
857 strlcpy(&frm[24 + sp_len + 1],
858 lck->base_name ? lck->base_name : "",
859 bn_len+1);
860 strlcpy(&frm[24 + sp_len + 1 + bn_len + 1],
861 lck->stream_name ? lck->stream_name : "",
862 sn_len+1);
864 /* Send the messages. */
865 for (i=0; i<lck->num_share_modes; i++) {
866 struct share_mode_entry *se = &lck->share_modes[i];
867 if (!is_valid_share_mode_entry(se)) {
868 continue;
871 /* If this is a hardlink to the inode
872 with a different name, skip this. */
873 if (se->name_hash != orig_name_hash) {
874 continue;
877 se->name_hash = new_name_hash;
879 /* But not to ourselves... */
880 if (procid_is_me(&se->pid)) {
881 continue;
884 DEBUG(10,("rename_share_filename: sending rename message to "
885 "pid %s file_id %s sharepath %s base_name %s "
886 "stream_name %s\n",
887 procid_str_static(&se->pid),
888 file_id_string_tos(&lck->id),
889 lck->servicepath, lck->base_name,
890 has_stream ? lck->stream_name : ""));
892 messaging_send_buf(msg_ctx, se->pid, MSG_SMB_FILE_RENAME,
893 (uint8 *)frm, msg_len);
896 return True;
899 void get_file_infos(struct file_id id,
900 uint32_t name_hash,
901 bool *delete_on_close,
902 struct timespec *write_time)
904 struct share_mode_lock *lck;
906 if (delete_on_close) {
907 *delete_on_close = false;
910 if (write_time) {
911 ZERO_STRUCTP(write_time);
914 if (!(lck = fetch_share_mode_unlocked(talloc_tos(), id))) {
915 return;
918 if (delete_on_close) {
919 *delete_on_close = is_delete_on_close_set(lck, name_hash);
922 if (write_time) {
923 struct timespec wt;
925 wt = lck->changed_write_time;
926 if (null_timespec(wt)) {
927 wt = lck->old_write_time;
930 *write_time = wt;
933 TALLOC_FREE(lck);
936 bool is_valid_share_mode_entry(const struct share_mode_entry *e)
938 int num_props = 0;
940 num_props += ((e->op_type == NO_OPLOCK) ? 1 : 0);
941 num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0);
942 num_props += (LEVEL_II_OPLOCK_TYPE(e->op_type) ? 1 : 0);
944 SMB_ASSERT(num_props <= 1);
945 return (num_props != 0);
948 bool is_deferred_open_entry(const struct share_mode_entry *e)
950 return (e->op_type == DEFERRED_OPEN_ENTRY);
953 /*******************************************************************
954 Fill a share mode entry.
955 ********************************************************************/
957 static void fill_share_mode_entry(struct share_mode_entry *e,
958 files_struct *fsp,
959 uid_t uid, uint64_t mid, uint16 op_type)
961 ZERO_STRUCTP(e);
962 e->pid = messaging_server_id(fsp->conn->sconn->msg_ctx);
963 e->share_access = fsp->share_access;
964 e->private_options = fsp->fh->private_options;
965 e->access_mask = fsp->access_mask;
966 e->op_mid = mid;
967 e->op_type = op_type;
968 e->time.tv_sec = fsp->open_time.tv_sec;
969 e->time.tv_usec = fsp->open_time.tv_usec;
970 e->id = fsp->file_id;
971 e->share_file_id = fsp->fh->gen_id;
972 e->uid = (uint32)uid;
973 e->flags = fsp->posix_open ? SHARE_MODE_FLAG_POSIX_OPEN : 0;
974 e->name_hash = fsp->name_hash;
977 static void fill_deferred_open_entry(struct share_mode_entry *e,
978 const struct timeval request_time,
979 struct file_id id,
980 struct server_id pid,
981 uint64_t mid)
983 ZERO_STRUCTP(e);
984 e->pid = pid;
985 e->op_mid = mid;
986 e->op_type = DEFERRED_OPEN_ENTRY;
987 e->time.tv_sec = request_time.tv_sec;
988 e->time.tv_usec = request_time.tv_usec;
989 e->id = id;
990 e->uid = (uint32)-1;
991 e->flags = 0;
994 static void add_share_mode_entry(struct share_mode_lock *lck,
995 const struct share_mode_entry *entry)
997 ADD_TO_ARRAY(lck, struct share_mode_entry, *entry,
998 &lck->share_modes, &lck->num_share_modes);
999 lck->modified = True;
1002 void set_share_mode(struct share_mode_lock *lck, files_struct *fsp,
1003 uid_t uid, uint64_t mid, uint16 op_type)
1005 struct share_mode_entry entry;
1006 fill_share_mode_entry(&entry, fsp, uid, mid, op_type);
1007 add_share_mode_entry(lck, &entry);
1010 void add_deferred_open(struct share_mode_lock *lck, uint64_t mid,
1011 struct timeval request_time,
1012 struct server_id pid, struct file_id id)
1014 struct share_mode_entry entry;
1015 fill_deferred_open_entry(&entry, request_time, id, pid, mid);
1016 add_share_mode_entry(lck, &entry);
1019 /*******************************************************************
1020 Check if two share mode entries are identical, ignoring oplock
1021 and mid info and desired_access. (Removed paranoia test - it's
1022 not automatically a logic error if they are identical. JRA.)
1023 ********************************************************************/
1025 static bool share_modes_identical(struct share_mode_entry *e1,
1026 struct share_mode_entry *e2)
1028 /* We used to check for e1->share_access == e2->share_access here
1029 as well as the other fields but 2 different DOS or FCB opens
1030 sharing the same share mode entry may validly differ in
1031 fsp->share_access field. */
1033 return (procid_equal(&e1->pid, &e2->pid) &&
1034 file_id_equal(&e1->id, &e2->id) &&
1035 e1->share_file_id == e2->share_file_id );
1038 static bool deferred_open_identical(struct share_mode_entry *e1,
1039 struct share_mode_entry *e2)
1041 return (procid_equal(&e1->pid, &e2->pid) &&
1042 (e1->op_mid == e2->op_mid) &&
1043 file_id_equal(&e1->id, &e2->id));
1046 static struct share_mode_entry *find_share_mode_entry(struct share_mode_lock *lck,
1047 struct share_mode_entry *entry)
1049 int i;
1051 for (i=0; i<lck->num_share_modes; i++) {
1052 struct share_mode_entry *e = &lck->share_modes[i];
1053 if (is_valid_share_mode_entry(entry) &&
1054 is_valid_share_mode_entry(e) &&
1055 share_modes_identical(e, entry)) {
1056 return e;
1058 if (is_deferred_open_entry(entry) &&
1059 is_deferred_open_entry(e) &&
1060 deferred_open_identical(e, entry)) {
1061 return e;
1064 return NULL;
1067 /*******************************************************************
1068 Del the share mode of a file for this process. Return the number of
1069 entries left.
1070 ********************************************************************/
1072 bool del_share_mode(struct share_mode_lock *lck, files_struct *fsp)
1074 struct share_mode_entry entry, *e;
1076 /* Don't care about the pid owner being correct here - just a search. */
1077 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1079 e = find_share_mode_entry(lck, &entry);
1080 if (e == NULL) {
1081 return False;
1083 *e = lck->share_modes[lck->num_share_modes-1];
1084 lck->num_share_modes -= 1;
1085 lck->modified = True;
1086 return True;
1089 void del_deferred_open_entry(struct share_mode_lock *lck, uint64_t mid,
1090 struct server_id pid)
1092 struct share_mode_entry entry, *e;
1094 fill_deferred_open_entry(&entry, timeval_zero(),
1095 lck->id, pid, mid);
1097 e = find_share_mode_entry(lck, &entry);
1098 if (e == NULL) {
1099 return;
1101 *e = lck->share_modes[lck->num_share_modes-1];
1102 lck->num_share_modes -= 1;
1103 lck->modified = True;
1106 /*******************************************************************
1107 Remove an oplock mid and mode entry from a share mode.
1108 ********************************************************************/
1110 bool remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
1112 struct share_mode_entry entry, *e;
1114 /* Don't care about the pid owner being correct here - just a search. */
1115 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1117 e = find_share_mode_entry(lck, &entry);
1118 if (e == NULL) {
1119 return False;
1122 if (EXCLUSIVE_OPLOCK_TYPE(e->op_type)) {
1124 * Going from exclusive or batch,
1125 * we always go through FAKE_LEVEL_II
1126 * first.
1128 if (!EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1129 smb_panic("remove_share_oplock: logic error");
1131 e->op_type = FAKE_LEVEL_II_OPLOCK;
1132 } else {
1133 e->op_type = NO_OPLOCK;
1135 lck->modified = True;
1136 return True;
1139 /*******************************************************************
1140 Downgrade a oplock type from exclusive to level II.
1141 ********************************************************************/
1143 bool downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
1145 struct share_mode_entry entry, *e;
1147 /* Don't care about the pid owner being correct here - just a search. */
1148 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1150 e = find_share_mode_entry(lck, &entry);
1151 if (e == NULL) {
1152 return False;
1155 e->op_type = LEVEL_II_OPLOCK;
1156 lck->modified = True;
1157 return True;
1160 /*************************************************************************
1161 Return a talloced copy of a struct security_unix_token. NULL on fail.
1162 (Should this be in locking.c.... ?).
1163 *************************************************************************/
1165 static struct security_unix_token *copy_unix_token(TALLOC_CTX *ctx, const struct security_unix_token *tok)
1167 struct security_unix_token *cpy;
1169 cpy = talloc(ctx, struct security_unix_token);
1170 if (!cpy) {
1171 return NULL;
1174 cpy->uid = tok->uid;
1175 cpy->gid = tok->gid;
1176 cpy->ngroups = tok->ngroups;
1177 if (tok->ngroups) {
1178 /* Make this a talloc child of cpy. */
1179 cpy->groups = (gid_t *)talloc_memdup(
1180 cpy, tok->groups, tok->ngroups * sizeof(gid_t));
1181 if (!cpy->groups) {
1182 TALLOC_FREE(cpy);
1183 return NULL;
1186 return cpy;
1189 /****************************************************************************
1190 Adds a delete on close token.
1191 ****************************************************************************/
1193 static bool add_delete_on_close_token(struct share_mode_lock *lck,
1194 uint32_t name_hash,
1195 const struct security_unix_token *tok)
1197 struct delete_token *tmp, *dtl;
1199 tmp = talloc_realloc(lck, lck->delete_tokens, struct delete_token,
1200 lck->num_delete_tokens+1);
1201 if (tmp == NULL) {
1202 return false;
1204 lck->delete_tokens = tmp;
1205 dtl = &lck->delete_tokens[lck->num_delete_tokens];
1207 dtl->name_hash = name_hash;
1208 dtl->delete_token = copy_unix_token(lck->delete_tokens, tok);
1209 if (dtl->delete_token == NULL) {
1210 return false;
1212 lck->num_delete_tokens += 1;
1213 lck->modified = true;
1214 return true;
1217 /****************************************************************************
1218 Sets the delete on close flag over all share modes on this file.
1219 Modify the share mode entry for all files open
1220 on this device and inode to tell other smbds we have
1221 changed the delete on close flag. This will be noticed
1222 in the close code, the last closer will delete the file
1223 if flag is set.
1224 This makes a copy of any struct security_unix_token into the
1225 lck entry. This function is used when the lock is already granted.
1226 ****************************************************************************/
1228 void set_delete_on_close_lck(files_struct *fsp,
1229 struct share_mode_lock *lck,
1230 bool delete_on_close,
1231 const struct security_unix_token *tok)
1233 int i;
1234 bool ret;
1236 if (delete_on_close) {
1237 SMB_ASSERT(tok != NULL);
1238 } else {
1239 SMB_ASSERT(tok == NULL);
1242 for (i=0; i<lck->num_delete_tokens; i++) {
1243 struct delete_token *dt = &lck->delete_tokens[i];
1244 if (dt->name_hash == fsp->name_hash) {
1245 lck->modified = true;
1246 if (delete_on_close == false) {
1247 /* Delete this entry. */
1248 TALLOC_FREE(dt->delete_token);
1249 *dt = lck->delete_tokens[
1250 lck->num_delete_tokens-1];
1251 lck->num_delete_tokens -= 1;
1252 return;
1254 /* Replace this token with the
1255 given tok. */
1256 TALLOC_FREE(dt->delete_token);
1257 dt->delete_token = copy_unix_token(dt, tok);
1258 SMB_ASSERT(dt->delete_token != NULL);
1262 if (!delete_on_close) {
1263 /* Nothing to delete - not found. */
1264 return;
1267 ret = add_delete_on_close_token(lck, fsp->name_hash, tok);
1268 SMB_ASSERT(ret);
1271 bool set_delete_on_close(files_struct *fsp, bool delete_on_close, const struct security_unix_token *tok)
1273 struct share_mode_lock *lck;
1275 DEBUG(10,("set_delete_on_close: %s delete on close flag for "
1276 "fnum = %d, file %s\n",
1277 delete_on_close ? "Adding" : "Removing", fsp->fnum,
1278 fsp_str_dbg(fsp)));
1280 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
1281 NULL);
1282 if (lck == NULL) {
1283 return False;
1286 set_delete_on_close_lck(fsp, lck, delete_on_close,
1287 delete_on_close ? tok : NULL);
1289 if (fsp->is_directory) {
1290 SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name));
1291 send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
1292 fsp->fsp_name->base_name);
1295 TALLOC_FREE(lck);
1297 fsp->delete_on_close = delete_on_close;
1299 return True;
1302 const struct security_unix_token *get_delete_on_close_token(struct share_mode_lock *lck, uint32_t name_hash)
1304 int i;
1306 DEBUG(10,("get_delete_on_close_token: name_hash = 0x%x\n",
1307 (unsigned int)name_hash ));
1309 for (i=0; i<lck->num_delete_tokens; i++) {
1310 struct delete_token *dt = &lck->delete_tokens[i];
1311 DEBUG(10,("get_delete_on_close_token: dtl->name_hash = 0x%x\n",
1312 (unsigned int)dt->name_hash ));
1313 if (dt->name_hash == name_hash) {
1314 return dt->delete_token;
1317 return NULL;
1320 bool is_delete_on_close_set(struct share_mode_lock *lck, uint32_t name_hash)
1322 return (get_delete_on_close_token(lck, name_hash) != NULL);
1325 bool set_sticky_write_time(struct file_id fileid, struct timespec write_time)
1327 struct share_mode_lock *lck;
1329 DEBUG(5,("set_sticky_write_time: %s id=%s\n",
1330 timestring(talloc_tos(),
1331 convert_timespec_to_time_t(write_time)),
1332 file_id_string_tos(&fileid)));
1334 lck = get_share_mode_lock(talloc_tos(), fileid, NULL, NULL, NULL);
1335 if (lck == NULL) {
1336 return False;
1339 if (timespec_compare(&lck->changed_write_time, &write_time) != 0) {
1340 lck->modified = True;
1341 lck->changed_write_time = write_time;
1344 TALLOC_FREE(lck);
1345 return True;
1348 bool set_write_time(struct file_id fileid, struct timespec write_time)
1350 struct share_mode_lock *lck;
1352 DEBUG(5,("set_write_time: %s id=%s\n",
1353 timestring(talloc_tos(),
1354 convert_timespec_to_time_t(write_time)),
1355 file_id_string_tos(&fileid)));
1357 lck = get_share_mode_lock(talloc_tos(), fileid, NULL, NULL, NULL);
1358 if (lck == NULL) {
1359 return False;
1362 if (timespec_compare(&lck->old_write_time, &write_time) != 0) {
1363 lck->modified = True;
1364 lck->old_write_time = write_time;
1367 TALLOC_FREE(lck);
1368 return True;
1372 struct forall_state {
1373 void (*fn)(const struct share_mode_entry *entry,
1374 const char *sharepath,
1375 const char *fname,
1376 void *private_data);
1377 void *private_data;
1380 static int traverse_fn(struct db_record *rec, void *_state)
1382 struct forall_state *state = (struct forall_state *)_state;
1383 uint32_t i;
1384 TDB_DATA key;
1385 TDB_DATA value;
1386 DATA_BLOB blob;
1387 enum ndr_err_code ndr_err;
1388 struct share_mode_lock *lck;
1390 key = dbwrap_record_get_key(rec);
1391 value = dbwrap_record_get_value(rec);
1393 /* Ensure this is a locking_key record. */
1394 if (key.dsize != sizeof(struct file_id))
1395 return 0;
1397 lck = talloc(talloc_tos(), struct share_mode_lock);
1398 if (lck == NULL) {
1399 return 0;
1402 blob.data = value.dptr;
1403 blob.length = value.dsize;
1405 ndr_err = ndr_pull_struct_blob(
1406 &blob, lck, lck,
1407 (ndr_pull_flags_fn_t)ndr_pull_share_mode_lock);
1408 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1409 DEBUG(1, ("ndr_pull_share_mode_lock failed\n"));
1410 return 0;
1412 for (i=0; i<lck->num_share_modes; i++) {
1413 state->fn(&lck->share_modes[i],
1414 lck->servicepath, lck->base_name,
1415 state->private_data);
1417 TALLOC_FREE(lck);
1419 return 0;
1422 /*******************************************************************
1423 Call the specified function on each entry under management by the
1424 share mode system.
1425 ********************************************************************/
1427 int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *,
1428 const char *, void *),
1429 void *private_data)
1431 struct forall_state state;
1432 NTSTATUS status;
1433 int count;
1435 if (lock_db == NULL)
1436 return 0;
1438 state.fn = fn;
1439 state.private_data = private_data;
1441 status = dbwrap_traverse_read(lock_db, traverse_fn, (void *)&state,
1442 &count);
1444 if (!NT_STATUS_IS_OK(status)) {
1445 return -1;
1446 } else {
1447 return count;