Add first cut at networkless build instructions for samba-docs
[Samba/bjacke.git] / source3 / locking / locking.c
blob5faebef1fe70b6286baf599699bcccb3eac5e3d1
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"
40 #undef DBGC_CLASS
41 #define DBGC_CLASS DBGC_LOCKING
43 #define NO_LOCKING_COUNT (-1)
45 /* the locking database handle */
46 static struct db_context *lock_db;
48 /****************************************************************************
49 Debugging aids :-).
50 ****************************************************************************/
52 const char *lock_type_name(enum brl_type lock_type)
54 switch (lock_type) {
55 case READ_LOCK:
56 return "READ";
57 case WRITE_LOCK:
58 return "WRITE";
59 case PENDING_READ_LOCK:
60 return "PENDING_READ";
61 case PENDING_WRITE_LOCK:
62 return "PENDING_WRITE";
63 default:
64 return "other";
68 const char *lock_flav_name(enum brl_flavour lock_flav)
70 return (lock_flav == WINDOWS_LOCK) ? "WINDOWS_LOCK" : "POSIX_LOCK";
73 /****************************************************************************
74 Utility function called to see if a file region is locked.
75 Called in the read/write codepath.
76 ****************************************************************************/
78 bool is_locked(files_struct *fsp,
79 uint32 smbpid,
80 SMB_BIG_UINT count,
81 SMB_BIG_UINT offset,
82 enum brl_type lock_type)
84 int strict_locking = lp_strict_locking(fsp->conn->params);
85 enum brl_flavour lock_flav = lp_posix_cifsu_locktype(fsp);
86 bool ret = True;
88 if (count == 0) {
89 return False;
92 if (!lp_locking(fsp->conn->params) || !strict_locking) {
93 return False;
96 if (strict_locking == Auto) {
97 if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (lock_type == READ_LOCK || lock_type == WRITE_LOCK)) {
98 DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp->fsp_name ));
99 ret = False;
100 } else if ((fsp->oplock_type == LEVEL_II_OPLOCK) &&
101 (lock_type == READ_LOCK)) {
102 DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp->fsp_name ));
103 ret = False;
104 } else {
105 struct byte_range_lock *br_lck = brl_get_locks_readonly(talloc_tos(), fsp);
106 if (!br_lck) {
107 return False;
109 ret = !brl_locktest(br_lck,
110 smbpid,
111 procid_self(),
112 offset,
113 count,
114 lock_type,
115 lock_flav);
116 TALLOC_FREE(br_lck);
118 } else {
119 struct byte_range_lock *br_lck = brl_get_locks_readonly(talloc_tos(), fsp);
120 if (!br_lck) {
121 return False;
123 ret = !brl_locktest(br_lck,
124 smbpid,
125 procid_self(),
126 offset,
127 count,
128 lock_type,
129 lock_flav);
130 TALLOC_FREE(br_lck);
133 DEBUG(10,("is_locked: flavour = %s brl start=%.0f len=%.0f %s for fnum %d file %s\n",
134 lock_flav_name(lock_flav),
135 (double)offset, (double)count, ret ? "locked" : "unlocked",
136 fsp->fnum, fsp->fsp_name ));
138 return ret;
141 /****************************************************************************
142 Find out if a lock could be granted - return who is blocking us if we can't.
143 ****************************************************************************/
145 NTSTATUS query_lock(files_struct *fsp,
146 uint32 *psmbpid,
147 SMB_BIG_UINT *pcount,
148 SMB_BIG_UINT *poffset,
149 enum brl_type *plock_type,
150 enum brl_flavour lock_flav)
152 struct byte_range_lock *br_lck = NULL;
153 NTSTATUS status = NT_STATUS_LOCK_NOT_GRANTED;
155 if (!fsp->can_lock) {
156 return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
159 if (!lp_locking(fsp->conn->params)) {
160 return NT_STATUS_OK;
163 br_lck = brl_get_locks_readonly(talloc_tos(), fsp);
164 if (!br_lck) {
165 return NT_STATUS_NO_MEMORY;
168 status = brl_lockquery(br_lck,
169 psmbpid,
170 procid_self(),
171 poffset,
172 pcount,
173 plock_type,
174 lock_flav);
176 TALLOC_FREE(br_lck);
177 return status;
180 /****************************************************************************
181 Utility function called by locking requests.
182 ****************************************************************************/
184 struct byte_range_lock *do_lock(struct messaging_context *msg_ctx,
185 files_struct *fsp,
186 uint32 lock_pid,
187 SMB_BIG_UINT count,
188 SMB_BIG_UINT offset,
189 enum brl_type lock_type,
190 enum brl_flavour lock_flav,
191 bool blocking_lock,
192 NTSTATUS *perr,
193 uint32 *plock_pid)
195 struct byte_range_lock *br_lck = NULL;
197 if (!fsp->can_lock) {
198 *perr = fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
199 return NULL;
202 if (!lp_locking(fsp->conn->params)) {
203 *perr = NT_STATUS_OK;
204 return NULL;
207 /* NOTE! 0 byte long ranges ARE allowed and should be stored */
209 DEBUG(10,("do_lock: lock flavour %s lock type %s start=%.0f len=%.0f requested for fnum %d file %s\n",
210 lock_flav_name(lock_flav), lock_type_name(lock_type),
211 (double)offset, (double)count, fsp->fnum, fsp->fsp_name ));
213 br_lck = brl_get_locks(talloc_tos(), fsp);
214 if (!br_lck) {
215 *perr = NT_STATUS_NO_MEMORY;
216 return NULL;
219 *perr = brl_lock(msg_ctx,
220 br_lck,
221 lock_pid,
222 procid_self(),
223 offset,
224 count,
225 lock_type,
226 lock_flav,
227 blocking_lock,
228 plock_pid);
230 if (lock_flav == WINDOWS_LOCK &&
231 fsp->current_lock_count != NO_LOCKING_COUNT) {
232 /* blocking ie. pending, locks also count here,
233 * as this is an efficiency counter to avoid checking
234 * the lock db. on close. JRA. */
236 fsp->current_lock_count++;
237 } else {
238 /* Notice that this has had a POSIX lock request.
239 * We can't count locks after this so forget them.
241 fsp->current_lock_count = NO_LOCKING_COUNT;
244 return br_lck;
247 /****************************************************************************
248 Utility function called by unlocking requests.
249 ****************************************************************************/
251 NTSTATUS do_unlock(struct messaging_context *msg_ctx,
252 files_struct *fsp,
253 uint32 lock_pid,
254 SMB_BIG_UINT count,
255 SMB_BIG_UINT offset,
256 enum brl_flavour lock_flav)
258 bool ok = False;
259 struct byte_range_lock *br_lck = NULL;
261 if (!fsp->can_lock) {
262 return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
265 if (!lp_locking(fsp->conn->params)) {
266 return NT_STATUS_OK;
269 DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for fnum %d file %s\n",
270 (double)offset, (double)count, fsp->fnum, fsp->fsp_name ));
272 br_lck = brl_get_locks(talloc_tos(), fsp);
273 if (!br_lck) {
274 return NT_STATUS_NO_MEMORY;
277 ok = brl_unlock(msg_ctx,
278 br_lck,
279 lock_pid,
280 procid_self(),
281 offset,
282 count,
283 lock_flav);
285 TALLOC_FREE(br_lck);
287 if (!ok) {
288 DEBUG(10,("do_unlock: returning ERRlock.\n" ));
289 return NT_STATUS_RANGE_NOT_LOCKED;
292 if (lock_flav == WINDOWS_LOCK &&
293 fsp->current_lock_count != NO_LOCKING_COUNT) {
294 SMB_ASSERT(fsp->current_lock_count > 0);
295 fsp->current_lock_count--;
298 return NT_STATUS_OK;
301 /****************************************************************************
302 Cancel any pending blocked locks.
303 ****************************************************************************/
305 NTSTATUS do_lock_cancel(files_struct *fsp,
306 uint32 lock_pid,
307 SMB_BIG_UINT count,
308 SMB_BIG_UINT offset,
309 enum brl_flavour lock_flav)
311 bool ok = False;
312 struct byte_range_lock *br_lck = NULL;
314 if (!fsp->can_lock) {
315 return fsp->is_directory ?
316 NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
319 if (!lp_locking(fsp->conn->params)) {
320 return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
323 DEBUG(10,("do_lock_cancel: cancel start=%.0f len=%.0f requested for fnum %d file %s\n",
324 (double)offset, (double)count, fsp->fnum, fsp->fsp_name ));
326 br_lck = brl_get_locks(talloc_tos(), fsp);
327 if (!br_lck) {
328 return NT_STATUS_NO_MEMORY;
331 ok = brl_lock_cancel(br_lck,
332 lock_pid,
333 procid_self(),
334 offset,
335 count,
336 lock_flav);
338 TALLOC_FREE(br_lck);
340 if (!ok) {
341 DEBUG(10,("do_lock_cancel: returning ERRcancelviolation.\n" ));
342 return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
345 if (lock_flav == WINDOWS_LOCK &&
346 fsp->current_lock_count != NO_LOCKING_COUNT) {
347 SMB_ASSERT(fsp->current_lock_count > 0);
348 fsp->current_lock_count--;
351 return NT_STATUS_OK;
354 /****************************************************************************
355 Remove any locks on this fd. Called from file_close().
356 ****************************************************************************/
358 void locking_close_file(struct messaging_context *msg_ctx,
359 files_struct *fsp)
361 struct byte_range_lock *br_lck;
363 if (!lp_locking(fsp->conn->params)) {
364 return;
367 /* If we have not outstanding locks or pending
368 * locks then we don't need to look in the lock db.
371 if (fsp->current_lock_count == 0) {
372 return;
375 br_lck = brl_get_locks(talloc_tos(),fsp);
377 if (br_lck) {
378 cancel_pending_lock_requests_by_fid(fsp, br_lck);
379 brl_close_fnum(msg_ctx, br_lck);
380 TALLOC_FREE(br_lck);
384 /****************************************************************************
385 Initialise the locking functions.
386 ****************************************************************************/
388 static bool locking_init_internal(bool read_only)
390 brl_init(read_only);
392 if (lock_db)
393 return True;
395 lock_db = db_open(NULL, lock_path("locking.tdb"),
396 lp_open_files_db_hash_size(),
397 TDB_DEFAULT|TDB_VOLATILE|TDB_CLEAR_IF_FIRST,
398 read_only?O_RDONLY:O_RDWR|O_CREAT, 0644);
400 if (!lock_db) {
401 DEBUG(0,("ERROR: Failed to initialise locking database\n"));
402 return False;
405 if (!posix_locking_init(read_only))
406 return False;
408 return True;
411 bool locking_init(void)
413 return locking_init_internal(false);
416 bool locking_init_readonly(void)
418 return locking_init_internal(true);
421 /*******************************************************************
422 Deinitialize the share_mode management.
423 ******************************************************************/
425 bool locking_end(void)
427 brl_shutdown();
428 TALLOC_FREE(lock_db);
429 return true;
432 /*******************************************************************
433 Form a static locking key for a dev/inode pair.
434 ******************************************************************/
436 static TDB_DATA locking_key(const struct file_id *id, struct file_id *tmp)
438 *tmp = *id;
439 return make_tdb_data((const uint8_t *)tmp, sizeof(*tmp));
442 /*******************************************************************
443 Print out a share mode.
444 ********************************************************************/
446 char *share_mode_str(TALLOC_CTX *ctx, int num, struct share_mode_entry *e)
448 return talloc_asprintf(ctx, "share_mode_entry[%d]: %s "
449 "pid = %s, share_access = 0x%x, private_options = 0x%x, "
450 "access_mask = 0x%x, mid = 0x%x, type= 0x%x, gen_id = %lu, "
451 "uid = %u, flags = %u, file_id %s",
452 num,
453 e->op_type == UNUSED_SHARE_MODE_ENTRY ? "UNUSED" : "",
454 procid_str_static(&e->pid),
455 e->share_access, e->private_options,
456 e->access_mask, e->op_mid, e->op_type, e->share_file_id,
457 (unsigned int)e->uid, (unsigned int)e->flags,
458 file_id_string_tos(&e->id));
461 /*******************************************************************
462 Print out a share mode table.
463 ********************************************************************/
465 static void print_share_mode_table(struct locking_data *data)
467 int num_share_modes = data->u.s.num_share_mode_entries;
468 struct share_mode_entry *shares =
469 (struct share_mode_entry *)(data + 1);
470 int i;
472 for (i = 0; i < num_share_modes; i++) {
473 struct share_mode_entry entry;
474 char *str;
477 * We need to memcpy the entry here due to alignment
478 * restrictions that are not met when directly accessing
479 * shares[i]
482 memcpy(&entry, &shares[i], sizeof(struct share_mode_entry));
483 str = share_mode_str(talloc_tos(), i, &entry);
485 DEBUG(10,("print_share_mode_table: %s\n", str ? str : ""));
486 TALLOC_FREE(str);
490 /*******************************************************************
491 Get all share mode entries for a dev/inode pair.
492 ********************************************************************/
494 static bool parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck)
496 struct locking_data *data;
497 int i;
499 if (dbuf.dsize < sizeof(struct locking_data)) {
500 smb_panic("parse_share_modes: buffer too short");
503 data = (struct locking_data *)dbuf.dptr;
505 lck->delete_on_close = data->u.s.delete_on_close;
506 lck->old_write_time = data->u.s.old_write_time;
507 lck->changed_write_time = data->u.s.changed_write_time;
508 lck->num_share_modes = data->u.s.num_share_mode_entries;
510 DEBUG(10, ("parse_share_modes: delete_on_close: %d, owrt: %s, "
511 "cwrt: %s, tok: %u, num_share_modes: %d\n",
512 lck->delete_on_close,
513 timestring(debug_ctx(),
514 convert_timespec_to_time_t(lck->old_write_time)),
515 timestring(debug_ctx(),
516 convert_timespec_to_time_t(
517 lck->changed_write_time)),
518 (unsigned int)data->u.s.delete_token_size,
519 lck->num_share_modes));
521 if ((lck->num_share_modes < 0) || (lck->num_share_modes > 1000000)) {
522 DEBUG(0, ("invalid number of share modes: %d\n",
523 lck->num_share_modes));
524 smb_panic("parse_share_modes: invalid number of share modes");
527 lck->share_modes = NULL;
529 if (lck->num_share_modes != 0) {
531 if (dbuf.dsize < (sizeof(struct locking_data) +
532 (lck->num_share_modes *
533 sizeof(struct share_mode_entry)))) {
534 smb_panic("parse_share_modes: buffer too short");
537 lck->share_modes = (struct share_mode_entry *)
538 TALLOC_MEMDUP(lck, dbuf.dptr+sizeof(*data),
539 lck->num_share_modes *
540 sizeof(struct share_mode_entry));
542 if (lck->share_modes == NULL) {
543 smb_panic("parse_share_modes: talloc failed");
547 /* Get any delete token. */
548 if (data->u.s.delete_token_size) {
549 uint8 *p = dbuf.dptr + sizeof(*data) +
550 (lck->num_share_modes *
551 sizeof(struct share_mode_entry));
553 if ((data->u.s.delete_token_size < sizeof(uid_t) + sizeof(gid_t)) ||
554 ((data->u.s.delete_token_size - sizeof(uid_t)) % sizeof(gid_t)) != 0) {
555 DEBUG(0, ("parse_share_modes: invalid token size %d\n",
556 data->u.s.delete_token_size));
557 smb_panic("parse_share_modes: invalid token size");
560 lck->delete_token = TALLOC_P(lck, UNIX_USER_TOKEN);
561 if (!lck->delete_token) {
562 smb_panic("parse_share_modes: talloc failed");
565 /* Copy out the uid and gid. */
566 memcpy(&lck->delete_token->uid, p, sizeof(uid_t));
567 p += sizeof(uid_t);
568 memcpy(&lck->delete_token->gid, p, sizeof(gid_t));
569 p += sizeof(gid_t);
571 /* Any supplementary groups ? */
572 lck->delete_token->ngroups = (data->u.s.delete_token_size > (sizeof(uid_t) + sizeof(gid_t))) ?
573 ((data->u.s.delete_token_size -
574 (sizeof(uid_t) + sizeof(gid_t)))/sizeof(gid_t)) : 0;
576 if (lck->delete_token->ngroups) {
577 /* Make this a talloc child of lck->delete_token. */
578 lck->delete_token->groups = TALLOC_ARRAY(lck->delete_token, gid_t,
579 lck->delete_token->ngroups);
580 if (!lck->delete_token) {
581 smb_panic("parse_share_modes: talloc failed");
584 for (i = 0; i < lck->delete_token->ngroups; i++) {
585 memcpy(&lck->delete_token->groups[i], p, sizeof(gid_t));
586 p += sizeof(gid_t);
590 } else {
591 lck->delete_token = NULL;
594 /* Save off the associated service path and filename. */
595 lck->servicepath = (const char *)dbuf.dptr + sizeof(*data) +
596 (lck->num_share_modes * sizeof(struct share_mode_entry)) +
597 data->u.s.delete_token_size;
599 lck->filename = (const char *)dbuf.dptr + sizeof(*data) +
600 (lck->num_share_modes * sizeof(struct share_mode_entry)) +
601 data->u.s.delete_token_size +
602 strlen(lck->servicepath) + 1;
605 * Ensure that each entry has a real process attached.
608 for (i = 0; i < lck->num_share_modes; i++) {
609 struct share_mode_entry *entry_p = &lck->share_modes[i];
610 char *str = NULL;
611 if (DEBUGLEVEL >= 10) {
612 str = share_mode_str(NULL, i, entry_p);
614 DEBUG(10,("parse_share_modes: %s\n",
615 str ? str : ""));
616 if (!process_exists(entry_p->pid)) {
617 DEBUG(10,("parse_share_modes: deleted %s\n",
618 str ? str : ""));
619 entry_p->op_type = UNUSED_SHARE_MODE_ENTRY;
620 lck->modified = True;
622 TALLOC_FREE(str);
625 return True;
628 static TDB_DATA unparse_share_modes(struct share_mode_lock *lck)
630 TDB_DATA result;
631 int num_valid = 0;
632 int i;
633 struct locking_data *data;
634 ssize_t offset;
635 ssize_t sp_len;
636 uint32 delete_token_size;
638 result.dptr = NULL;
639 result.dsize = 0;
641 for (i=0; i<lck->num_share_modes; i++) {
642 if (!is_unused_share_mode_entry(&lck->share_modes[i])) {
643 num_valid += 1;
647 if (num_valid == 0) {
648 return result;
651 sp_len = strlen(lck->servicepath);
652 delete_token_size = (lck->delete_token ?
653 (sizeof(uid_t) + sizeof(gid_t) + (lck->delete_token->ngroups*sizeof(gid_t))) : 0);
655 result.dsize = sizeof(*data) +
656 lck->num_share_modes * sizeof(struct share_mode_entry) +
657 delete_token_size +
658 sp_len + 1 +
659 strlen(lck->filename) + 1;
660 result.dptr = TALLOC_ARRAY(lck, uint8, result.dsize);
662 if (result.dptr == NULL) {
663 smb_panic("talloc failed");
666 data = (struct locking_data *)result.dptr;
667 ZERO_STRUCTP(data);
668 data->u.s.num_share_mode_entries = lck->num_share_modes;
669 data->u.s.delete_on_close = lck->delete_on_close;
670 data->u.s.old_write_time = lck->old_write_time;
671 data->u.s.changed_write_time = lck->changed_write_time;
672 data->u.s.delete_token_size = delete_token_size;
674 DEBUG(10,("unparse_share_modes: del: %d, owrt: %s cwrt: %s, tok: %u, "
675 "num: %d\n", data->u.s.delete_on_close,
676 timestring(debug_ctx(),
677 convert_timespec_to_time_t(lck->old_write_time)),
678 timestring(debug_ctx(),
679 convert_timespec_to_time_t(
680 lck->changed_write_time)),
681 (unsigned int)data->u.s.delete_token_size,
682 data->u.s.num_share_mode_entries));
684 memcpy(result.dptr + sizeof(*data), lck->share_modes,
685 sizeof(struct share_mode_entry)*lck->num_share_modes);
686 offset = sizeof(*data) +
687 sizeof(struct share_mode_entry)*lck->num_share_modes;
689 /* Store any delete on close token. */
690 if (lck->delete_token) {
691 uint8 *p = result.dptr + offset;
693 memcpy(p, &lck->delete_token->uid, sizeof(uid_t));
694 p += sizeof(uid_t);
696 memcpy(p, &lck->delete_token->gid, sizeof(gid_t));
697 p += sizeof(gid_t);
699 for (i = 0; i < lck->delete_token->ngroups; i++) {
700 memcpy(p, &lck->delete_token->groups[i], sizeof(gid_t));
701 p += sizeof(gid_t);
703 offset = p - result.dptr;
706 safe_strcpy((char *)result.dptr + offset, lck->servicepath,
707 result.dsize - offset - 1);
708 offset += sp_len + 1;
709 safe_strcpy((char *)result.dptr + offset, lck->filename,
710 result.dsize - offset - 1);
712 if (DEBUGLEVEL >= 10) {
713 print_share_mode_table(data);
716 return result;
719 static int share_mode_lock_destructor(struct share_mode_lock *lck)
721 NTSTATUS status;
722 TDB_DATA data;
724 if (!lck->modified) {
725 return 0;
728 data = unparse_share_modes(lck);
730 if (data.dptr == NULL) {
731 if (!lck->fresh) {
732 /* There has been an entry before, delete it */
734 status = lck->record->delete_rec(lck->record);
735 if (!NT_STATUS_IS_OK(status)) {
736 DEBUG(0, ("delete_rec returned %s\n",
737 nt_errstr(status)));
738 smb_panic("could not delete share entry");
741 goto done;
744 status = lck->record->store(lck->record, data, TDB_REPLACE);
745 if (!NT_STATUS_IS_OK(status)) {
746 DEBUG(0, ("store returned %s\n", nt_errstr(status)));
747 smb_panic("could not store share mode entry");
750 done:
752 return 0;
755 static bool fill_share_mode_lock(struct share_mode_lock *lck,
756 struct file_id id,
757 const char *servicepath,
758 const char *fname,
759 TDB_DATA share_mode_data,
760 const struct timespec *old_write_time)
762 /* Ensure we set every field here as the destructor must be
763 valid even if parse_share_modes fails. */
765 lck->servicepath = NULL;
766 lck->filename = NULL;
767 lck->id = id;
768 lck->num_share_modes = 0;
769 lck->share_modes = NULL;
770 lck->delete_token = NULL;
771 lck->delete_on_close = False;
772 ZERO_STRUCT(lck->old_write_time);
773 ZERO_STRUCT(lck->changed_write_time);
774 lck->fresh = False;
775 lck->modified = False;
777 lck->fresh = (share_mode_data.dptr == NULL);
779 if (lck->fresh) {
780 if (fname == NULL || servicepath == NULL
781 || old_write_time == NULL) {
782 return False;
784 lck->filename = talloc_strdup(lck, fname);
785 lck->servicepath = talloc_strdup(lck, servicepath);
786 if (lck->filename == NULL || lck->servicepath == NULL) {
787 DEBUG(0, ("talloc failed\n"));
788 return False;
790 lck->old_write_time = *old_write_time;
791 } else {
792 if (!parse_share_modes(share_mode_data, lck)) {
793 DEBUG(0, ("Could not parse share modes\n"));
794 return False;
798 return True;
801 struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
802 const struct file_id id,
803 const char *servicepath,
804 const char *fname,
805 const struct timespec *old_write_time)
807 struct share_mode_lock *lck;
808 struct file_id tmp;
809 TDB_DATA key = locking_key(&id, &tmp);
811 if (!(lck = TALLOC_P(mem_ctx, struct share_mode_lock))) {
812 DEBUG(0, ("talloc failed\n"));
813 return NULL;
816 if (!(lck->record = lock_db->fetch_locked(lock_db, lck, key))) {
817 DEBUG(3, ("Could not lock share entry\n"));
818 TALLOC_FREE(lck);
819 return NULL;
822 if (!fill_share_mode_lock(lck, id, servicepath, fname,
823 lck->record->value, old_write_time)) {
824 DEBUG(3, ("fill_share_mode_lock failed\n"));
825 TALLOC_FREE(lck);
826 return NULL;
829 talloc_set_destructor(lck, share_mode_lock_destructor);
831 return lck;
834 struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx,
835 const struct file_id id,
836 const char *servicepath,
837 const char *fname)
839 struct share_mode_lock *lck;
840 struct file_id tmp;
841 TDB_DATA key = locking_key(&id, &tmp);
842 TDB_DATA data;
844 if (!(lck = TALLOC_P(mem_ctx, struct share_mode_lock))) {
845 DEBUG(0, ("talloc failed\n"));
846 return NULL;
849 if (lock_db->fetch(lock_db, lck, key, &data) == -1) {
850 DEBUG(3, ("Could not fetch share entry\n"));
851 TALLOC_FREE(lck);
852 return NULL;
855 if (!fill_share_mode_lock(lck, id, servicepath, fname, data, NULL)) {
856 DEBUG(3, ("fill_share_mode_lock failed\n"));
857 TALLOC_FREE(lck);
858 return NULL;
861 return lck;
864 /*******************************************************************
865 Sets the service name and filename for rename.
866 At this point we emit "file renamed" messages to all
867 process id's that have this file open.
868 Based on an initial code idea from SATOH Fumiyasu <fumiya@samba.gr.jp>
869 ********************************************************************/
871 bool rename_share_filename(struct messaging_context *msg_ctx,
872 struct share_mode_lock *lck,
873 const char *servicepath,
874 const char *newname)
876 size_t sp_len;
877 size_t fn_len;
878 size_t msg_len;
879 char *frm = NULL;
880 int i;
882 DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n",
883 servicepath, newname));
886 * rename_internal_fsp() and rename_internals() add './' to
887 * head of newname if newname does not contain a '/'.
889 while (newname[0] && newname[1] && newname[0] == '.' && newname[1] == '/') {
890 newname += 2;
893 lck->servicepath = talloc_strdup(lck, servicepath);
894 lck->filename = talloc_strdup(lck, newname);
895 if (lck->filename == NULL || lck->servicepath == NULL) {
896 DEBUG(0, ("rename_share_filename: talloc failed\n"));
897 return False;
899 lck->modified = True;
901 sp_len = strlen(lck->servicepath);
902 fn_len = strlen(lck->filename);
904 msg_len = MSG_FILE_RENAMED_MIN_SIZE + sp_len + 1 + fn_len + 1;
906 /* Set up the name changed message. */
907 frm = TALLOC_ARRAY(lck, char, msg_len);
908 if (!frm) {
909 return False;
912 push_file_id_16(frm, &lck->id);
914 DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len ));
916 safe_strcpy(&frm[16], lck->servicepath, sp_len);
917 safe_strcpy(&frm[16 + sp_len + 1], lck->filename, fn_len);
919 /* Send the messages. */
920 for (i=0; i<lck->num_share_modes; i++) {
921 struct share_mode_entry *se = &lck->share_modes[i];
922 if (!is_valid_share_mode_entry(se)) {
923 continue;
925 /* But not to ourselves... */
926 if (procid_is_me(&se->pid)) {
927 continue;
930 DEBUG(10,("rename_share_filename: sending rename message to pid %s "
931 "file_id %s sharepath %s newname %s\n",
932 procid_str_static(&se->pid),
933 file_id_string_tos(&lck->id),
934 lck->servicepath, lck->filename ));
936 messaging_send_buf(msg_ctx, se->pid, MSG_SMB_FILE_RENAME,
937 (uint8 *)frm, msg_len);
940 return True;
943 void get_file_infos(struct file_id id,
944 bool *delete_on_close,
945 struct timespec *write_time)
947 struct share_mode_lock *lck;
949 if (delete_on_close) {
950 *delete_on_close = false;
953 if (write_time) {
954 ZERO_STRUCTP(write_time);
957 if (!(lck = fetch_share_mode_unlocked(talloc_tos(), id, NULL, NULL))) {
958 return;
961 if (delete_on_close) {
962 *delete_on_close = lck->delete_on_close;
965 if (write_time) {
966 struct timespec wt;
968 wt = lck->changed_write_time;
969 if (null_timespec(wt)) {
970 wt = lck->old_write_time;
973 *write_time = wt;
976 TALLOC_FREE(lck);
979 bool is_valid_share_mode_entry(const struct share_mode_entry *e)
981 int num_props = 0;
983 if (e->op_type == UNUSED_SHARE_MODE_ENTRY) {
984 /* cope with dead entries from the process not
985 existing. These should not be considered valid,
986 otherwise we end up doing zero timeout sharing
987 violation */
988 return False;
991 num_props += ((e->op_type == NO_OPLOCK) ? 1 : 0);
992 num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0);
993 num_props += (LEVEL_II_OPLOCK_TYPE(e->op_type) ? 1 : 0);
995 SMB_ASSERT(num_props <= 1);
996 return (num_props != 0);
999 bool is_deferred_open_entry(const struct share_mode_entry *e)
1001 return (e->op_type == DEFERRED_OPEN_ENTRY);
1004 bool is_unused_share_mode_entry(const struct share_mode_entry *e)
1006 return (e->op_type == UNUSED_SHARE_MODE_ENTRY);
1009 /*******************************************************************
1010 Fill a share mode entry.
1011 ********************************************************************/
1013 static void fill_share_mode_entry(struct share_mode_entry *e,
1014 files_struct *fsp,
1015 uid_t uid, uint16 mid, uint16 op_type)
1017 ZERO_STRUCTP(e);
1018 e->pid = procid_self();
1019 e->share_access = fsp->share_access;
1020 e->private_options = fsp->fh->private_options;
1021 e->access_mask = fsp->access_mask;
1022 e->op_mid = mid;
1023 e->op_type = op_type;
1024 e->time.tv_sec = fsp->open_time.tv_sec;
1025 e->time.tv_usec = fsp->open_time.tv_usec;
1026 e->id = fsp->file_id;
1027 e->share_file_id = fsp->fh->gen_id;
1028 e->uid = (uint32)uid;
1029 e->flags = fsp->posix_open ? SHARE_MODE_FLAG_POSIX_OPEN : 0;
1032 static void fill_deferred_open_entry(struct share_mode_entry *e,
1033 const struct timeval request_time,
1034 struct file_id id, uint16 mid)
1036 ZERO_STRUCTP(e);
1037 e->pid = procid_self();
1038 e->op_mid = mid;
1039 e->op_type = DEFERRED_OPEN_ENTRY;
1040 e->time.tv_sec = request_time.tv_sec;
1041 e->time.tv_usec = request_time.tv_usec;
1042 e->id = id;
1043 e->uid = (uint32)-1;
1044 e->flags = 0;
1047 static void add_share_mode_entry(struct share_mode_lock *lck,
1048 const struct share_mode_entry *entry)
1050 int i;
1052 for (i=0; i<lck->num_share_modes; i++) {
1053 struct share_mode_entry *e = &lck->share_modes[i];
1054 if (is_unused_share_mode_entry(e)) {
1055 *e = *entry;
1056 break;
1060 if (i == lck->num_share_modes) {
1061 /* No unused entry found */
1062 ADD_TO_ARRAY(lck, struct share_mode_entry, *entry,
1063 &lck->share_modes, &lck->num_share_modes);
1065 lck->modified = True;
1068 void set_share_mode(struct share_mode_lock *lck, files_struct *fsp,
1069 uid_t uid, uint16 mid, uint16 op_type, bool initial_delete_on_close_allowed)
1071 struct share_mode_entry entry;
1072 fill_share_mode_entry(&entry, fsp, uid, mid, op_type);
1073 if (initial_delete_on_close_allowed) {
1074 entry.flags |= SHARE_MODE_ALLOW_INITIAL_DELETE_ON_CLOSE;
1076 add_share_mode_entry(lck, &entry);
1079 void add_deferred_open(struct share_mode_lock *lck, uint16 mid,
1080 struct timeval request_time,
1081 struct file_id id)
1083 struct share_mode_entry entry;
1084 fill_deferred_open_entry(&entry, request_time, id, mid);
1085 add_share_mode_entry(lck, &entry);
1088 /*******************************************************************
1089 Check if two share mode entries are identical, ignoring oplock
1090 and mid info and desired_access. (Removed paranoia test - it's
1091 not automatically a logic error if they are identical. JRA.)
1092 ********************************************************************/
1094 static bool share_modes_identical(struct share_mode_entry *e1,
1095 struct share_mode_entry *e2)
1097 /* We used to check for e1->share_access == e2->share_access here
1098 as well as the other fields but 2 different DOS or FCB opens
1099 sharing the same share mode entry may validly differ in
1100 fsp->share_access field. */
1102 return (procid_equal(&e1->pid, &e2->pid) &&
1103 file_id_equal(&e1->id, &e2->id) &&
1104 e1->share_file_id == e2->share_file_id );
1107 static bool deferred_open_identical(struct share_mode_entry *e1,
1108 struct share_mode_entry *e2)
1110 return (procid_equal(&e1->pid, &e2->pid) &&
1111 (e1->op_mid == e2->op_mid) &&
1112 file_id_equal(&e1->id, &e2->id));
1115 static struct share_mode_entry *find_share_mode_entry(struct share_mode_lock *lck,
1116 struct share_mode_entry *entry)
1118 int i;
1120 for (i=0; i<lck->num_share_modes; i++) {
1121 struct share_mode_entry *e = &lck->share_modes[i];
1122 if (is_valid_share_mode_entry(entry) &&
1123 is_valid_share_mode_entry(e) &&
1124 share_modes_identical(e, entry)) {
1125 return e;
1127 if (is_deferred_open_entry(entry) &&
1128 is_deferred_open_entry(e) &&
1129 deferred_open_identical(e, entry)) {
1130 return e;
1133 return NULL;
1136 /*******************************************************************
1137 Del the share mode of a file for this process. Return the number of
1138 entries left.
1139 ********************************************************************/
1141 bool del_share_mode(struct share_mode_lock *lck, files_struct *fsp)
1143 struct share_mode_entry entry, *e;
1145 /* Don't care about the pid owner being correct here - just a search. */
1146 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1148 e = find_share_mode_entry(lck, &entry);
1149 if (e == NULL) {
1150 return False;
1153 e->op_type = UNUSED_SHARE_MODE_ENTRY;
1154 lck->modified = True;
1155 return True;
1158 void del_deferred_open_entry(struct share_mode_lock *lck, uint16 mid)
1160 struct share_mode_entry entry, *e;
1162 fill_deferred_open_entry(&entry, timeval_zero(),
1163 lck->id, mid);
1165 e = find_share_mode_entry(lck, &entry);
1166 if (e == NULL) {
1167 return;
1170 e->op_type = UNUSED_SHARE_MODE_ENTRY;
1171 lck->modified = True;
1174 /*******************************************************************
1175 Remove an oplock mid and mode entry from a share mode.
1176 ********************************************************************/
1178 bool remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
1180 struct share_mode_entry entry, *e;
1182 /* Don't care about the pid owner being correct here - just a search. */
1183 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1185 e = find_share_mode_entry(lck, &entry);
1186 if (e == NULL) {
1187 return False;
1190 e->op_mid = 0;
1191 e->op_type = NO_OPLOCK;
1192 lck->modified = True;
1193 return True;
1196 /*******************************************************************
1197 Downgrade a oplock type from exclusive to level II.
1198 ********************************************************************/
1200 bool downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
1202 struct share_mode_entry entry, *e;
1204 /* Don't care about the pid owner being correct here - just a search. */
1205 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1207 e = find_share_mode_entry(lck, &entry);
1208 if (e == NULL) {
1209 return False;
1212 e->op_type = LEVEL_II_OPLOCK;
1213 lck->modified = True;
1214 return True;
1217 /****************************************************************************
1218 Deal with the internal needs of setting the delete on close flag. Note that
1219 as the tdb locking is recursive, it is safe to call this from within
1220 open_file_ntcreate. JRA.
1221 ****************************************************************************/
1223 NTSTATUS can_set_delete_on_close(files_struct *fsp, bool delete_on_close,
1224 uint32 dosmode)
1226 if (!delete_on_close) {
1227 return NT_STATUS_OK;
1231 * Only allow delete on close for writable files.
1234 if ((dosmode & aRONLY) &&
1235 !lp_delete_readonly(SNUM(fsp->conn))) {
1236 DEBUG(10,("can_set_delete_on_close: file %s delete on close "
1237 "flag set but file attribute is readonly.\n",
1238 fsp->fsp_name ));
1239 return NT_STATUS_CANNOT_DELETE;
1243 * Only allow delete on close for writable shares.
1246 if (!CAN_WRITE(fsp->conn)) {
1247 DEBUG(10,("can_set_delete_on_close: file %s delete on "
1248 "close flag set but write access denied on share.\n",
1249 fsp->fsp_name ));
1250 return NT_STATUS_ACCESS_DENIED;
1254 * Only allow delete on close for files/directories opened with delete
1255 * intent.
1258 if (!(fsp->access_mask & DELETE_ACCESS)) {
1259 DEBUG(10,("can_set_delete_on_close: file %s delete on "
1260 "close flag set but delete access denied.\n",
1261 fsp->fsp_name ));
1262 return NT_STATUS_ACCESS_DENIED;
1265 /* Don't allow delete on close for non-empty directories. */
1266 if (fsp->is_directory) {
1267 return can_delete_directory(fsp->conn, fsp->fsp_name);
1270 return NT_STATUS_OK;
1273 /****************************************************************************
1274 Do we have an open file handle that created this entry ?
1275 ****************************************************************************/
1277 bool can_set_initial_delete_on_close(const struct share_mode_lock *lck)
1279 int i;
1281 for (i=0; i<lck->num_share_modes; i++) {
1282 if (lck->share_modes[i].flags & SHARE_MODE_ALLOW_INITIAL_DELETE_ON_CLOSE) {
1283 return True;
1286 return False;
1289 /*************************************************************************
1290 Return a talloced copy of a UNIX_USER_TOKEN. NULL on fail.
1291 (Should this be in locking.c.... ?).
1292 *************************************************************************/
1294 static UNIX_USER_TOKEN *copy_unix_token(TALLOC_CTX *ctx, UNIX_USER_TOKEN *tok)
1296 UNIX_USER_TOKEN *cpy;
1298 if (tok == NULL) {
1299 return NULL;
1302 cpy = TALLOC_P(ctx, UNIX_USER_TOKEN);
1303 if (!cpy) {
1304 return NULL;
1307 cpy->uid = tok->uid;
1308 cpy->gid = tok->gid;
1309 cpy->ngroups = tok->ngroups;
1310 if (tok->ngroups) {
1311 /* Make this a talloc child of cpy. */
1312 cpy->groups = TALLOC_ARRAY(cpy, gid_t, tok->ngroups);
1313 if (!cpy->groups) {
1314 return NULL;
1316 memcpy(cpy->groups, tok->groups, tok->ngroups * sizeof(gid_t));
1318 return cpy;
1321 /****************************************************************************
1322 Replace the delete on close token.
1323 ****************************************************************************/
1325 void set_delete_on_close_token(struct share_mode_lock *lck, UNIX_USER_TOKEN *tok)
1327 TALLOC_FREE(lck->delete_token); /* Also deletes groups... */
1329 /* Copy the new token (can be NULL). */
1330 lck->delete_token = copy_unix_token(lck, tok);
1331 lck->modified = True;
1334 /****************************************************************************
1335 Sets the delete on close flag over all share modes on this file.
1336 Modify the share mode entry for all files open
1337 on this device and inode to tell other smbds we have
1338 changed the delete on close flag. This will be noticed
1339 in the close code, the last closer will delete the file
1340 if flag is set.
1341 This makes a copy of any UNIX_USER_TOKEN into the
1342 lck entry. This function is used when the lock is already granted.
1343 ****************************************************************************/
1345 void set_delete_on_close_lck(struct share_mode_lock *lck, bool delete_on_close, UNIX_USER_TOKEN *tok)
1347 if (lck->delete_on_close != delete_on_close) {
1348 set_delete_on_close_token(lck, tok);
1349 lck->delete_on_close = delete_on_close;
1350 if (delete_on_close) {
1351 SMB_ASSERT(lck->delete_token != NULL);
1353 lck->modified = True;
1357 bool set_delete_on_close(files_struct *fsp, bool delete_on_close, UNIX_USER_TOKEN *tok)
1359 struct share_mode_lock *lck;
1361 DEBUG(10,("set_delete_on_close: %s delete on close flag for "
1362 "fnum = %d, file %s\n",
1363 delete_on_close ? "Adding" : "Removing", fsp->fnum,
1364 fsp->fsp_name ));
1366 if (fsp->is_stat) {
1367 return True;
1370 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
1371 NULL);
1372 if (lck == NULL) {
1373 return False;
1376 set_delete_on_close_lck(lck, delete_on_close, tok);
1378 if (fsp->is_directory) {
1379 send_stat_cache_delete_message(fsp->fsp_name);
1382 TALLOC_FREE(lck);
1383 return True;
1386 /****************************************************************************
1387 Sets the allow initial delete on close flag for this share mode.
1388 ****************************************************************************/
1390 bool set_allow_initial_delete_on_close(struct share_mode_lock *lck, files_struct *fsp, bool delete_on_close)
1392 struct share_mode_entry entry, *e;
1394 /* Don't care about the pid owner being correct here - just a search. */
1395 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1397 e = find_share_mode_entry(lck, &entry);
1398 if (e == NULL) {
1399 return False;
1402 if (delete_on_close) {
1403 e->flags |= SHARE_MODE_ALLOW_INITIAL_DELETE_ON_CLOSE;
1404 } else {
1405 e->flags &= ~SHARE_MODE_ALLOW_INITIAL_DELETE_ON_CLOSE;
1407 lck->modified = True;
1408 return True;
1411 bool set_write_time(struct file_id fileid, struct timespec write_time,
1412 bool overwrite)
1414 struct share_mode_lock *lck;
1416 DEBUG(5,("set_write_time: %s overwrite=%d id=%s\n",
1417 timestring(debug_ctx(),
1418 convert_timespec_to_time_t(write_time)),
1419 overwrite, file_id_string_tos(&fileid)));
1421 lck = get_share_mode_lock(NULL, fileid, NULL, NULL, NULL);
1422 if (lck == NULL) {
1423 return False;
1426 if (overwrite || null_timespec(lck->changed_write_time)) {
1427 lck->modified = True;
1428 lck->changed_write_time = write_time;
1431 TALLOC_FREE(lck);
1432 return True;
1435 struct forall_state {
1436 void (*fn)(const struct share_mode_entry *entry,
1437 const char *sharepath,
1438 const char *fname,
1439 void *private_data);
1440 void *private_data;
1443 static int traverse_fn(struct db_record *rec, void *_state)
1445 struct forall_state *state = (struct forall_state *)_state;
1446 struct locking_data *data;
1447 struct share_mode_entry *shares;
1448 const char *sharepath;
1449 const char *fname;
1450 int i;
1452 /* Ensure this is a locking_key record. */
1453 if (rec->key.dsize != sizeof(struct file_id))
1454 return 0;
1456 data = (struct locking_data *)rec->value.dptr;
1457 shares = (struct share_mode_entry *)(rec->value.dptr + sizeof(*data));
1458 sharepath = (const char *)rec->value.dptr + sizeof(*data) +
1459 data->u.s.num_share_mode_entries*sizeof(*shares) +
1460 data->u.s.delete_token_size;
1461 fname = (const char *)rec->value.dptr + sizeof(*data) +
1462 data->u.s.num_share_mode_entries*sizeof(*shares) +
1463 data->u.s.delete_token_size +
1464 strlen(sharepath) + 1;
1466 for (i=0;i<data->u.s.num_share_mode_entries;i++) {
1467 state->fn(&shares[i], sharepath, fname,
1468 state->private_data);
1470 return 0;
1473 /*******************************************************************
1474 Call the specified function on each entry under management by the
1475 share mode system.
1476 ********************************************************************/
1478 int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *,
1479 const char *, void *),
1480 void *private_data)
1482 struct forall_state state;
1484 if (lock_db == NULL)
1485 return 0;
1487 state.fn = fn;
1488 state.private_data = private_data;
1490 return lock_db->traverse_read(lock_db, traverse_fn, (void *)&state);