Convert parse_delete_tokens_list() and unparse_share_modes() to use ndr encoding...
[Samba.git] / source3 / locking / locking.c
blobe04de795aaa76c08eaa4ab118ebefbc085734820
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.h"
43 #include "../libcli/security/security.h"
44 #include "serverid.h"
45 #include "messages.h"
46 #include "util_tdb.h"
47 #include "../librpc/gen_ndr/ndr_security.h"
49 #undef DBGC_CLASS
50 #define DBGC_CLASS DBGC_LOCKING
52 #define NO_LOCKING_COUNT (-1)
54 /* the locking database handle */
55 static struct db_context *lock_db;
57 /****************************************************************************
58 Debugging aids :-).
59 ****************************************************************************/
61 const char *lock_type_name(enum brl_type lock_type)
63 switch (lock_type) {
64 case READ_LOCK:
65 return "READ";
66 case WRITE_LOCK:
67 return "WRITE";
68 case PENDING_READ_LOCK:
69 return "PENDING_READ";
70 case PENDING_WRITE_LOCK:
71 return "PENDING_WRITE";
72 default:
73 return "other";
77 const char *lock_flav_name(enum brl_flavour lock_flav)
79 return (lock_flav == WINDOWS_LOCK) ? "WINDOWS_LOCK" : "POSIX_LOCK";
82 /****************************************************************************
83 Utility function called to see if a file region is locked.
84 Called in the read/write codepath.
85 ****************************************************************************/
87 void init_strict_lock_struct(files_struct *fsp,
88 uint64_t smblctx,
89 br_off start,
90 br_off size,
91 enum brl_type lock_type,
92 struct lock_struct *plock)
94 SMB_ASSERT(lock_type == READ_LOCK || lock_type == WRITE_LOCK);
96 plock->context.smblctx = smblctx;
97 plock->context.tid = fsp->conn->cnum;
98 plock->context.pid = sconn_server_id(fsp->conn->sconn);
99 plock->start = start;
100 plock->size = size;
101 plock->fnum = fsp->fnum;
102 plock->lock_type = lock_type;
103 plock->lock_flav = lp_posix_cifsu_locktype(fsp);
106 bool strict_lock_default(files_struct *fsp, struct lock_struct *plock)
108 int strict_locking = lp_strict_locking(fsp->conn->params);
109 bool ret = False;
111 if (plock->size == 0) {
112 return True;
115 if (!lp_locking(fsp->conn->params) || !strict_locking) {
116 return True;
119 if (strict_locking == Auto) {
120 if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (plock->lock_type == READ_LOCK || plock->lock_type == WRITE_LOCK)) {
121 DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp_str_dbg(fsp)));
122 ret = True;
123 } else if ((fsp->oplock_type == LEVEL_II_OPLOCK) &&
124 (plock->lock_type == READ_LOCK)) {
125 DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp_str_dbg(fsp)));
126 ret = True;
127 } else {
128 struct byte_range_lock *br_lck;
130 br_lck = brl_get_locks_readonly(fsp);
131 if (!br_lck) {
132 return True;
134 ret = brl_locktest(br_lck,
135 plock->context.smblctx,
136 plock->context.pid,
137 plock->start,
138 plock->size,
139 plock->lock_type,
140 plock->lock_flav);
142 } else {
143 struct byte_range_lock *br_lck;
145 br_lck = brl_get_locks_readonly(fsp);
146 if (!br_lck) {
147 return True;
149 ret = brl_locktest(br_lck,
150 plock->context.smblctx,
151 plock->context.pid,
152 plock->start,
153 plock->size,
154 plock->lock_type,
155 plock->lock_flav);
158 DEBUG(10,("strict_lock_default: flavour = %s brl start=%.0f "
159 "len=%.0f %s for fnum %d file %s\n",
160 lock_flav_name(plock->lock_flav),
161 (double)plock->start, (double)plock->size,
162 ret ? "unlocked" : "locked",
163 plock->fnum, fsp_str_dbg(fsp)));
165 return ret;
168 void strict_unlock_default(files_struct *fsp, struct lock_struct *plock)
172 /****************************************************************************
173 Find out if a lock could be granted - return who is blocking us if we can't.
174 ****************************************************************************/
176 NTSTATUS query_lock(files_struct *fsp,
177 uint64_t *psmblctx,
178 uint64_t *pcount,
179 uint64_t *poffset,
180 enum brl_type *plock_type,
181 enum brl_flavour lock_flav)
183 struct byte_range_lock *br_lck = NULL;
185 if (!fsp->can_lock) {
186 return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
189 if (!lp_locking(fsp->conn->params)) {
190 return NT_STATUS_OK;
193 br_lck = brl_get_locks_readonly(fsp);
194 if (!br_lck) {
195 return NT_STATUS_NO_MEMORY;
198 return brl_lockquery(br_lck,
199 psmblctx,
200 sconn_server_id(fsp->conn->sconn),
201 poffset,
202 pcount,
203 plock_type,
204 lock_flav);
207 static void increment_current_lock_count(files_struct *fsp,
208 enum brl_flavour lock_flav)
210 if (lock_flav == WINDOWS_LOCK &&
211 fsp->current_lock_count != NO_LOCKING_COUNT) {
212 /* blocking ie. pending, locks also count here,
213 * as this is an efficiency counter to avoid checking
214 * the lock db. on close. JRA. */
216 fsp->current_lock_count++;
217 } else {
218 /* Notice that this has had a POSIX lock request.
219 * We can't count locks after this so forget them.
221 fsp->current_lock_count = NO_LOCKING_COUNT;
225 static void decrement_current_lock_count(files_struct *fsp,
226 enum brl_flavour lock_flav)
228 if (lock_flav == WINDOWS_LOCK &&
229 fsp->current_lock_count != NO_LOCKING_COUNT) {
230 SMB_ASSERT(fsp->current_lock_count > 0);
231 fsp->current_lock_count--;
235 /****************************************************************************
236 Utility function called by locking requests.
237 ****************************************************************************/
239 struct byte_range_lock *do_lock(struct messaging_context *msg_ctx,
240 files_struct *fsp,
241 uint64_t smblctx,
242 uint64_t count,
243 uint64_t offset,
244 enum brl_type lock_type,
245 enum brl_flavour lock_flav,
246 bool blocking_lock,
247 NTSTATUS *perr,
248 uint64_t *psmblctx,
249 struct blocking_lock_record *blr)
251 struct byte_range_lock *br_lck = NULL;
253 /* silently return ok on print files as we don't do locking there */
254 if (fsp->print_file) {
255 *perr = NT_STATUS_OK;
256 return NULL;
259 if (!fsp->can_lock) {
260 *perr = fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
261 return NULL;
264 if (!lp_locking(fsp->conn->params)) {
265 *perr = NT_STATUS_OK;
266 return NULL;
269 /* NOTE! 0 byte long ranges ARE allowed and should be stored */
271 DEBUG(10,("do_lock: lock flavour %s lock type %s start=%.0f len=%.0f "
272 "blocking_lock=%s requested for fnum %d file %s\n",
273 lock_flav_name(lock_flav), lock_type_name(lock_type),
274 (double)offset, (double)count, blocking_lock ? "true" :
275 "false", fsp->fnum, fsp_str_dbg(fsp)));
277 br_lck = brl_get_locks(talloc_tos(), fsp);
278 if (!br_lck) {
279 *perr = NT_STATUS_NO_MEMORY;
280 return NULL;
283 *perr = brl_lock(msg_ctx,
284 br_lck,
285 smblctx,
286 sconn_server_id(fsp->conn->sconn),
287 offset,
288 count,
289 lock_type,
290 lock_flav,
291 blocking_lock,
292 psmblctx,
293 blr);
295 DEBUG(10, ("do_lock: returning status=%s\n", nt_errstr(*perr)));
297 increment_current_lock_count(fsp, lock_flav);
298 return br_lck;
301 /****************************************************************************
302 Utility function called by unlocking requests.
303 ****************************************************************************/
305 NTSTATUS do_unlock(struct messaging_context *msg_ctx,
306 files_struct *fsp,
307 uint64_t smblctx,
308 uint64_t count,
309 uint64_t offset,
310 enum brl_flavour lock_flav)
312 bool ok = False;
313 struct byte_range_lock *br_lck = NULL;
315 if (!fsp->can_lock) {
316 return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
319 if (!lp_locking(fsp->conn->params)) {
320 return NT_STATUS_OK;
323 DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for fnum %d file %s\n",
324 (double)offset, (double)count, fsp->fnum,
325 fsp_str_dbg(fsp)));
327 br_lck = brl_get_locks(talloc_tos(), fsp);
328 if (!br_lck) {
329 return NT_STATUS_NO_MEMORY;
332 ok = brl_unlock(msg_ctx,
333 br_lck,
334 smblctx,
335 sconn_server_id(fsp->conn->sconn),
336 offset,
337 count,
338 lock_flav);
340 TALLOC_FREE(br_lck);
342 if (!ok) {
343 DEBUG(10,("do_unlock: returning ERRlock.\n" ));
344 return NT_STATUS_RANGE_NOT_LOCKED;
347 decrement_current_lock_count(fsp, lock_flav);
348 return NT_STATUS_OK;
351 /****************************************************************************
352 Cancel any pending blocked locks.
353 ****************************************************************************/
355 NTSTATUS do_lock_cancel(files_struct *fsp,
356 uint64 smblctx,
357 uint64_t count,
358 uint64_t offset,
359 enum brl_flavour lock_flav,
360 struct blocking_lock_record *blr)
362 bool ok = False;
363 struct byte_range_lock *br_lck = NULL;
365 if (!fsp->can_lock) {
366 return fsp->is_directory ?
367 NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
370 if (!lp_locking(fsp->conn->params)) {
371 return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
374 DEBUG(10,("do_lock_cancel: cancel start=%.0f len=%.0f requested for fnum %d file %s\n",
375 (double)offset, (double)count, fsp->fnum,
376 fsp_str_dbg(fsp)));
378 br_lck = brl_get_locks(talloc_tos(), fsp);
379 if (!br_lck) {
380 return NT_STATUS_NO_MEMORY;
383 ok = brl_lock_cancel(br_lck,
384 smblctx,
385 sconn_server_id(fsp->conn->sconn),
386 offset,
387 count,
388 lock_flav,
389 blr);
391 TALLOC_FREE(br_lck);
393 if (!ok) {
394 DEBUG(10,("do_lock_cancel: returning ERRcancelviolation.\n" ));
395 return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
398 decrement_current_lock_count(fsp, lock_flav);
399 return NT_STATUS_OK;
402 /****************************************************************************
403 Remove any locks on this fd. Called from file_close().
404 ****************************************************************************/
406 void locking_close_file(struct messaging_context *msg_ctx,
407 files_struct *fsp,
408 enum file_close_type close_type)
410 struct byte_range_lock *br_lck;
412 if (!lp_locking(fsp->conn->params)) {
413 return;
416 /* If we have not outstanding locks or pending
417 * locks then we don't need to look in the lock db.
420 if (fsp->current_lock_count == 0) {
421 return;
424 br_lck = brl_get_locks(talloc_tos(),fsp);
426 if (br_lck) {
427 cancel_pending_lock_requests_by_fid(fsp, br_lck, close_type);
428 brl_close_fnum(msg_ctx, br_lck);
429 TALLOC_FREE(br_lck);
433 /****************************************************************************
434 Initialise the locking functions.
435 ****************************************************************************/
437 static bool locking_init_internal(bool read_only)
439 brl_init(read_only);
441 if (lock_db)
442 return True;
444 lock_db = db_open(NULL, lock_path("locking.tdb"),
445 lp_open_files_db_hash_size(),
446 TDB_DEFAULT|TDB_VOLATILE|TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH,
447 read_only?O_RDONLY:O_RDWR|O_CREAT, 0644);
449 if (!lock_db) {
450 DEBUG(0,("ERROR: Failed to initialise locking database\n"));
451 return False;
454 if (!posix_locking_init(read_only))
455 return False;
457 return True;
460 bool locking_init(void)
462 return locking_init_internal(false);
465 bool locking_init_readonly(void)
467 return locking_init_internal(true);
470 /*******************************************************************
471 Deinitialize the share_mode management.
472 ******************************************************************/
474 bool locking_end(void)
476 brl_shutdown();
477 TALLOC_FREE(lock_db);
478 return true;
481 /*******************************************************************
482 Form a static locking key for a dev/inode pair.
483 ******************************************************************/
485 static TDB_DATA locking_key(const struct file_id *id, struct file_id *tmp)
487 *tmp = *id;
488 return make_tdb_data((const uint8_t *)tmp, sizeof(*tmp));
491 /*******************************************************************
492 Print out a share mode.
493 ********************************************************************/
495 char *share_mode_str(TALLOC_CTX *ctx, int num, const struct share_mode_entry *e)
497 return talloc_asprintf(ctx, "share_mode_entry[%d]: %s "
498 "pid = %s, share_access = 0x%x, private_options = 0x%x, "
499 "access_mask = 0x%x, mid = 0x%llx, type= 0x%x, gen_id = %lu, "
500 "uid = %u, flags = %u, file_id %s, name_hash = 0x%x",
501 num,
502 e->op_type == UNUSED_SHARE_MODE_ENTRY ? "UNUSED" : "",
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 Print out a share mode table.
514 ********************************************************************/
516 static void print_share_mode_table(struct locking_data *data)
518 int num_share_modes = data->u.s.num_share_mode_entries;
519 struct share_mode_entry *shares =
520 (struct share_mode_entry *)(data + 1);
521 int i;
523 for (i = 0; i < num_share_modes; i++) {
524 struct share_mode_entry entry;
525 char *str;
528 * We need to memcpy the entry here due to alignment
529 * restrictions that are not met when directly accessing
530 * shares[i]
533 memcpy(&entry, &shares[i], sizeof(struct share_mode_entry));
534 str = share_mode_str(talloc_tos(), i, &entry);
536 DEBUG(10,("print_share_mode_table: %s\n", str ? str : ""));
537 TALLOC_FREE(str);
541 static int parse_delete_tokens_list(struct share_mode_lock *lck,
542 struct locking_data *pdata,
543 const TDB_DATA dbuf)
545 uint8_t *p = dbuf.dptr + sizeof(struct locking_data) +
546 (lck->num_share_modes *
547 sizeof(struct share_mode_entry));
548 uint8_t *end_ptr = dbuf.dptr + (dbuf.dsize - 2);
549 int delete_tokens_size = 0;
550 int i;
552 lck->delete_tokens = NULL;
554 for (i = 0; i < pdata->u.s.num_delete_token_entries; i++) {
555 DATA_BLOB blob;
556 enum ndr_err_code ndr_err;
557 struct delete_token_list *pdtl;
558 size_t token_len = 0;
560 pdtl = TALLOC_ZERO_P(lck, struct delete_token_list);
561 if (pdtl == NULL) {
562 DEBUG(0,("parse_delete_tokens_list: talloc failed"));
563 return -1;
565 /* Copy out the name_hash. */
566 memcpy(&pdtl->name_hash, p, sizeof(pdtl->name_hash));
567 p += sizeof(pdtl->name_hash);
568 delete_tokens_size += sizeof(pdtl->name_hash);
570 pdtl->delete_token = TALLOC_ZERO_P(pdtl, struct security_unix_token);
571 if (pdtl->delete_token == NULL) {
572 DEBUG(0,("parse_delete_tokens_list: talloc failed"));
573 return -1;
576 if (p >= end_ptr) {
577 DEBUG(0,("parse_delete_tokens_list: corrupt data"));
578 return -1;
581 blob.data = p;
582 blob.length = end_ptr - p;
584 ndr_err = ndr_pull_struct_blob(&blob,
585 pdtl,
586 pdtl->delete_token,
587 (ndr_pull_flags_fn_t)ndr_pull_security_unix_token);
588 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
589 DEBUG(1, ("parse_delete_tokens_list: "
590 "ndr_pull_share_mode_data failed\n"));
591 return -1;
594 token_len = ndr_size_security_unix_token(pdtl->delete_token, 0);
596 p += token_len;
597 delete_tokens_size += token_len;
599 /* Add to the list. */
600 DLIST_ADD(lck->delete_tokens, pdtl);
603 return delete_tokens_size;
606 /*******************************************************************
607 Get all share mode entries for a dev/inode pair.
608 ********************************************************************/
610 static bool parse_share_modes(const TDB_DATA dbuf, struct share_mode_lock *lck)
612 struct locking_data data;
613 int delete_tokens_size;
614 int i;
616 if (dbuf.dsize < sizeof(struct locking_data)) {
617 smb_panic("parse_share_modes: buffer too short");
620 memcpy(&data, dbuf.dptr, sizeof(data));
622 lck->old_write_time = data.u.s.old_write_time;
623 lck->changed_write_time = data.u.s.changed_write_time;
624 lck->num_share_modes = data.u.s.num_share_mode_entries;
626 DEBUG(10, ("parse_share_modes: owrt: %s, "
627 "cwrt: %s, ntok: %u, num_share_modes: %d\n",
628 timestring(talloc_tos(),
629 convert_timespec_to_time_t(lck->old_write_time)),
630 timestring(talloc_tos(),
631 convert_timespec_to_time_t(
632 lck->changed_write_time)),
633 (unsigned int)data.u.s.num_delete_token_entries,
634 lck->num_share_modes));
636 if ((lck->num_share_modes < 0) || (lck->num_share_modes > 1000000)) {
637 DEBUG(0, ("invalid number of share modes: %d\n",
638 lck->num_share_modes));
639 smb_panic("parse_share_modes: invalid number of share modes");
642 lck->share_modes = NULL;
644 if (lck->num_share_modes != 0) {
646 if (dbuf.dsize < (sizeof(struct locking_data) +
647 (lck->num_share_modes *
648 sizeof(struct share_mode_entry)))) {
649 smb_panic("parse_share_modes: buffer too short");
652 lck->share_modes = (struct share_mode_entry *)
653 TALLOC_MEMDUP(lck,
654 dbuf.dptr+sizeof(struct locking_data),
655 lck->num_share_modes *
656 sizeof(struct share_mode_entry));
658 if (lck->share_modes == NULL) {
659 smb_panic("parse_share_modes: talloc failed");
663 /* Get any delete tokens. */
664 delete_tokens_size = parse_delete_tokens_list(lck, &data, dbuf);
665 if (delete_tokens_size < 0) {
666 smb_panic("parse_share_modes: parse_delete_tokens_list failed");
669 /* Save off the associated service path and filename. */
670 lck->servicepath = (const char *)dbuf.dptr + sizeof(struct locking_data) +
671 (lck->num_share_modes * sizeof(struct share_mode_entry)) +
672 delete_tokens_size;
674 lck->base_name = (const char *)dbuf.dptr + sizeof(struct locking_data) +
675 (lck->num_share_modes * sizeof(struct share_mode_entry)) +
676 delete_tokens_size +
677 strlen(lck->servicepath) + 1;
679 lck->stream_name = (const char *)dbuf.dptr + sizeof(struct locking_data) +
680 (lck->num_share_modes * sizeof(struct share_mode_entry)) +
681 delete_tokens_size +
682 strlen(lck->servicepath) + 1 +
683 strlen(lck->base_name) + 1;
686 * Ensure that each entry has a real process attached.
689 for (i = 0; i < lck->num_share_modes; i++) {
690 struct share_mode_entry *entry_p = &lck->share_modes[i];
691 char *str = NULL;
692 if (DEBUGLEVEL >= 10) {
693 str = share_mode_str(NULL, i, entry_p);
695 DEBUG(10,("parse_share_modes: %s\n",
696 str ? str : ""));
697 if (!serverid_exists(&entry_p->pid)) {
698 DEBUG(10,("parse_share_modes: deleted %s\n",
699 str ? str : ""));
700 entry_p->op_type = UNUSED_SHARE_MODE_ENTRY;
701 lck->modified = True;
703 TALLOC_FREE(str);
706 return True;
709 static TDB_DATA unparse_share_modes(const struct share_mode_lock *lck)
711 TDB_DATA result;
712 int num_valid = 0;
713 int i;
714 struct locking_data *data;
715 ssize_t offset;
716 ssize_t sp_len, bn_len, sn_len;
717 uint32_t delete_tokens_size = 0;
718 struct delete_token_list *pdtl = NULL;
719 uint32_t num_delete_token_entries = 0;
721 result.dptr = NULL;
722 result.dsize = 0;
724 for (i=0; i<lck->num_share_modes; i++) {
725 if (!is_unused_share_mode_entry(&lck->share_modes[i])) {
726 num_valid += 1;
730 if (num_valid == 0) {
731 return result;
734 sp_len = strlen(lck->servicepath);
735 bn_len = strlen(lck->base_name);
736 sn_len = lck->stream_name != NULL ? strlen(lck->stream_name) : 0;
738 for (pdtl = lck->delete_tokens; pdtl; pdtl = pdtl->next) {
739 num_delete_token_entries++;
740 delete_tokens_size += sizeof(uint32_t) +
741 ndr_size_security_unix_token(pdtl->delete_token, 0);
744 result.dsize = sizeof(*data) +
745 lck->num_share_modes * sizeof(struct share_mode_entry) +
746 delete_tokens_size +
747 sp_len + 1 +
748 bn_len + 1 +
749 sn_len + 1;
750 result.dptr = TALLOC_ARRAY(lck, uint8, result.dsize);
752 if (result.dptr == NULL) {
753 smb_panic("talloc failed");
756 data = (struct locking_data *)result.dptr;
757 ZERO_STRUCTP(data);
758 data->u.s.num_share_mode_entries = lck->num_share_modes;
759 data->u.s.old_write_time = lck->old_write_time;
760 data->u.s.changed_write_time = lck->changed_write_time;
761 data->u.s.num_delete_token_entries = num_delete_token_entries;
763 DEBUG(10,("unparse_share_modes: owrt: %s cwrt: %s, ntok: %u, "
764 "num: %d\n",
765 timestring(talloc_tos(),
766 convert_timespec_to_time_t(lck->old_write_time)),
767 timestring(talloc_tos(),
768 convert_timespec_to_time_t(
769 lck->changed_write_time)),
770 (unsigned int)data->u.s.num_delete_token_entries,
771 data->u.s.num_share_mode_entries));
773 memcpy(result.dptr + sizeof(*data), lck->share_modes,
774 sizeof(struct share_mode_entry)*lck->num_share_modes);
775 offset = sizeof(*data) +
776 sizeof(struct share_mode_entry)*lck->num_share_modes;
778 /* Store any delete on close tokens. */
779 for (pdtl = lck->delete_tokens; pdtl; pdtl = pdtl->next) {
780 struct security_unix_token *pdt = pdtl->delete_token;
781 uint8_t *p = result.dptr + offset;
782 DATA_BLOB blob;
783 enum ndr_err_code ndr_err;
785 memcpy(p, &pdtl->name_hash, sizeof(uint32_t));
786 p += sizeof(uint32_t);
787 offset += sizeof(uint32_t);
789 ndr_err = ndr_push_struct_blob(&blob,
790 talloc_tos(),
791 pdt,
792 (ndr_push_flags_fn_t)ndr_push_security_unix_token);
794 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
795 smb_panic("ndr_push_security_unix_token failed");
798 /* We know we have space here as we counted above. */
799 memcpy(p, blob.data, blob.length);
800 offset += blob.length;
801 TALLOC_FREE(blob.data);
804 safe_strcpy((char *)result.dptr + offset, lck->servicepath,
805 result.dsize - offset - 1);
806 offset += sp_len + 1;
807 safe_strcpy((char *)result.dptr + offset, lck->base_name,
808 result.dsize - offset - 1);
809 offset += bn_len + 1;
810 safe_strcpy((char *)result.dptr + offset, lck->stream_name,
811 result.dsize - offset - 1);
813 if (DEBUGLEVEL >= 10) {
814 print_share_mode_table(data);
817 return result;
820 static int share_mode_lock_destructor(struct share_mode_lock *lck)
822 NTSTATUS status;
823 TDB_DATA data;
825 if (!lck->modified) {
826 return 0;
829 data = unparse_share_modes(lck);
831 if (data.dptr == NULL) {
832 if (!lck->fresh) {
833 /* There has been an entry before, delete it */
835 status = lck->record->delete_rec(lck->record);
836 if (!NT_STATUS_IS_OK(status)) {
837 char *errmsg;
839 DEBUG(0, ("delete_rec returned %s\n",
840 nt_errstr(status)));
842 if (asprintf(&errmsg, "could not delete share "
843 "entry: %s\n",
844 nt_errstr(status)) == -1) {
845 smb_panic("could not delete share"
846 "entry");
848 smb_panic(errmsg);
851 goto done;
854 status = lck->record->store(lck->record, data, TDB_REPLACE);
855 if (!NT_STATUS_IS_OK(status)) {
856 char *errmsg;
858 DEBUG(0, ("store returned %s\n", nt_errstr(status)));
860 if (asprintf(&errmsg, "could not store share mode entry: %s",
861 nt_errstr(status)) == -1) {
862 smb_panic("could not store share mode entry");
864 smb_panic(errmsg);
867 done:
869 return 0;
872 static bool fill_share_mode_lock(struct share_mode_lock *lck,
873 struct file_id id,
874 const char *servicepath,
875 const struct smb_filename *smb_fname,
876 TDB_DATA share_mode_data,
877 const struct timespec *old_write_time)
879 /* Ensure we set every field here as the destructor must be
880 valid even if parse_share_modes fails. */
882 lck->servicepath = NULL;
883 lck->base_name = NULL;
884 lck->stream_name = NULL;
885 lck->id = id;
886 lck->num_share_modes = 0;
887 lck->share_modes = NULL;
888 lck->delete_tokens = NULL;
889 ZERO_STRUCT(lck->old_write_time);
890 ZERO_STRUCT(lck->changed_write_time);
891 lck->fresh = False;
892 lck->modified = False;
894 lck->fresh = (share_mode_data.dptr == NULL);
896 if (lck->fresh) {
897 bool has_stream;
898 if (smb_fname == NULL || servicepath == NULL
899 || old_write_time == NULL) {
900 return False;
903 has_stream = smb_fname->stream_name != NULL;
905 lck->base_name = talloc_strdup(lck, smb_fname->base_name);
906 lck->stream_name = talloc_strdup(lck, smb_fname->stream_name);
907 lck->servicepath = talloc_strdup(lck, servicepath);
908 if (lck->base_name == NULL ||
909 (has_stream && lck->stream_name == NULL) ||
910 lck->servicepath == NULL) {
911 DEBUG(0, ("talloc failed\n"));
912 return False;
914 lck->old_write_time = *old_write_time;
915 } else {
916 if (!parse_share_modes(share_mode_data, lck)) {
917 DEBUG(0, ("Could not parse share modes\n"));
918 return False;
922 return True;
925 struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
926 const struct file_id id,
927 const char *servicepath,
928 const struct smb_filename *smb_fname,
929 const struct timespec *old_write_time)
931 struct share_mode_lock *lck;
932 struct file_id tmp;
933 TDB_DATA key = locking_key(&id, &tmp);
935 if (!(lck = TALLOC_P(mem_ctx, struct share_mode_lock))) {
936 DEBUG(0, ("talloc failed\n"));
937 return NULL;
940 if (!(lck->record = lock_db->fetch_locked(lock_db, lck, key))) {
941 DEBUG(3, ("Could not lock share entry\n"));
942 TALLOC_FREE(lck);
943 return NULL;
946 if (!fill_share_mode_lock(lck, id, servicepath, smb_fname,
947 lck->record->value, old_write_time)) {
948 DEBUG(3, ("fill_share_mode_lock failed\n"));
949 TALLOC_FREE(lck);
950 return NULL;
953 talloc_set_destructor(lck, share_mode_lock_destructor);
955 return lck;
958 struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx,
959 const struct file_id id)
961 struct share_mode_lock *lck;
962 struct file_id tmp;
963 TDB_DATA key = locking_key(&id, &tmp);
964 TDB_DATA data;
966 if (!(lck = TALLOC_P(mem_ctx, struct share_mode_lock))) {
967 DEBUG(0, ("talloc failed\n"));
968 return NULL;
971 if (lock_db->fetch(lock_db, lck, key, &data) == -1) {
972 DEBUG(3, ("Could not fetch share entry\n"));
973 TALLOC_FREE(lck);
974 return NULL;
977 if (!fill_share_mode_lock(lck, id, NULL, NULL, data, NULL)) {
978 DEBUG(10, ("fetch_share_mode_unlocked: no share_mode record "
979 "around (file not open)\n"));
980 TALLOC_FREE(lck);
981 return NULL;
984 return lck;
987 /*******************************************************************
988 Sets the service name and filename for rename.
989 At this point we emit "file renamed" messages to all
990 process id's that have this file open.
991 Based on an initial code idea from SATOH Fumiyasu <fumiya@samba.gr.jp>
992 ********************************************************************/
994 bool rename_share_filename(struct messaging_context *msg_ctx,
995 struct share_mode_lock *lck,
996 const char *servicepath,
997 uint32_t orig_name_hash,
998 uint32_t new_name_hash,
999 const struct smb_filename *smb_fname_dst)
1001 size_t sp_len;
1002 size_t bn_len;
1003 size_t sn_len;
1004 size_t msg_len;
1005 char *frm = NULL;
1006 int i;
1007 bool strip_two_chars = false;
1008 bool has_stream = smb_fname_dst->stream_name != NULL;
1010 DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n",
1011 servicepath, smb_fname_dst->base_name));
1014 * rename_internal_fsp() and rename_internals() add './' to
1015 * head of newname if newname does not contain a '/'.
1017 if (smb_fname_dst->base_name[0] &&
1018 smb_fname_dst->base_name[1] &&
1019 smb_fname_dst->base_name[0] == '.' &&
1020 smb_fname_dst->base_name[1] == '/') {
1021 strip_two_chars = true;
1024 lck->servicepath = talloc_strdup(lck, servicepath);
1025 lck->base_name = talloc_strdup(lck, smb_fname_dst->base_name +
1026 (strip_two_chars ? 2 : 0));
1027 lck->stream_name = talloc_strdup(lck, smb_fname_dst->stream_name);
1028 if (lck->base_name == NULL ||
1029 (has_stream && lck->stream_name == NULL) ||
1030 lck->servicepath == NULL) {
1031 DEBUG(0, ("rename_share_filename: talloc failed\n"));
1032 return False;
1034 lck->modified = True;
1036 sp_len = strlen(lck->servicepath);
1037 bn_len = strlen(lck->base_name);
1038 sn_len = has_stream ? strlen(lck->stream_name) : 0;
1040 msg_len = MSG_FILE_RENAMED_MIN_SIZE + sp_len + 1 + bn_len + 1 +
1041 sn_len + 1;
1043 /* Set up the name changed message. */
1044 frm = TALLOC_ARRAY(lck, char, msg_len);
1045 if (!frm) {
1046 return False;
1049 push_file_id_24(frm, &lck->id);
1051 DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len ));
1053 safe_strcpy(&frm[24], lck->servicepath, sp_len);
1054 safe_strcpy(&frm[24 + sp_len + 1], lck->base_name, bn_len);
1055 safe_strcpy(&frm[24 + sp_len + 1 + bn_len + 1], lck->stream_name,
1056 sn_len);
1058 /* Send the messages. */
1059 for (i=0; i<lck->num_share_modes; i++) {
1060 struct share_mode_entry *se = &lck->share_modes[i];
1061 if (!is_valid_share_mode_entry(se)) {
1062 continue;
1065 /* If this is a hardlink to the inode
1066 with a different name, skip this. */
1067 if (se->name_hash != orig_name_hash) {
1068 continue;
1071 se->name_hash = new_name_hash;
1073 /* But not to ourselves... */
1074 if (procid_is_me(&se->pid)) {
1075 continue;
1078 DEBUG(10,("rename_share_filename: sending rename message to "
1079 "pid %s file_id %s sharepath %s base_name %s "
1080 "stream_name %s\n",
1081 procid_str_static(&se->pid),
1082 file_id_string_tos(&lck->id),
1083 lck->servicepath, lck->base_name,
1084 has_stream ? lck->stream_name : ""));
1086 messaging_send_buf(msg_ctx, se->pid, MSG_SMB_FILE_RENAME,
1087 (uint8 *)frm, msg_len);
1090 return True;
1093 void get_file_infos(struct file_id id,
1094 uint32_t name_hash,
1095 bool *delete_on_close,
1096 struct timespec *write_time)
1098 struct share_mode_lock *lck;
1100 if (delete_on_close) {
1101 *delete_on_close = false;
1104 if (write_time) {
1105 ZERO_STRUCTP(write_time);
1108 if (!(lck = fetch_share_mode_unlocked(talloc_tos(), id))) {
1109 return;
1112 if (delete_on_close) {
1113 *delete_on_close = is_delete_on_close_set(lck, name_hash);
1116 if (write_time) {
1117 struct timespec wt;
1119 wt = lck->changed_write_time;
1120 if (null_timespec(wt)) {
1121 wt = lck->old_write_time;
1124 *write_time = wt;
1127 TALLOC_FREE(lck);
1130 bool is_valid_share_mode_entry(const struct share_mode_entry *e)
1132 int num_props = 0;
1134 if (e->op_type == UNUSED_SHARE_MODE_ENTRY) {
1135 /* cope with dead entries from the process not
1136 existing. These should not be considered valid,
1137 otherwise we end up doing zero timeout sharing
1138 violation */
1139 return False;
1142 num_props += ((e->op_type == NO_OPLOCK) ? 1 : 0);
1143 num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0);
1144 num_props += (LEVEL_II_OPLOCK_TYPE(e->op_type) ? 1 : 0);
1146 SMB_ASSERT(num_props <= 1);
1147 return (num_props != 0);
1150 bool is_deferred_open_entry(const struct share_mode_entry *e)
1152 return (e->op_type == DEFERRED_OPEN_ENTRY);
1155 bool is_unused_share_mode_entry(const struct share_mode_entry *e)
1157 return (e->op_type == UNUSED_SHARE_MODE_ENTRY);
1160 /*******************************************************************
1161 Fill a share mode entry.
1162 ********************************************************************/
1164 static void fill_share_mode_entry(struct share_mode_entry *e,
1165 files_struct *fsp,
1166 uid_t uid, uint64_t mid, uint16 op_type)
1168 ZERO_STRUCTP(e);
1169 e->pid = sconn_server_id(fsp->conn->sconn);
1170 e->share_access = fsp->share_access;
1171 e->private_options = fsp->fh->private_options;
1172 e->access_mask = fsp->access_mask;
1173 e->op_mid = mid;
1174 e->op_type = op_type;
1175 e->time.tv_sec = fsp->open_time.tv_sec;
1176 e->time.tv_usec = fsp->open_time.tv_usec;
1177 e->id = fsp->file_id;
1178 e->share_file_id = fsp->fh->gen_id;
1179 e->uid = (uint32)uid;
1180 e->flags = fsp->posix_open ? SHARE_MODE_FLAG_POSIX_OPEN : 0;
1181 e->name_hash = fsp->name_hash;
1184 static void fill_deferred_open_entry(struct share_mode_entry *e,
1185 const struct timeval request_time,
1186 struct file_id id,
1187 struct server_id pid,
1188 uint64_t mid)
1190 ZERO_STRUCTP(e);
1191 e->pid = pid;
1192 e->op_mid = mid;
1193 e->op_type = DEFERRED_OPEN_ENTRY;
1194 e->time.tv_sec = request_time.tv_sec;
1195 e->time.tv_usec = request_time.tv_usec;
1196 e->id = id;
1197 e->uid = (uint32)-1;
1198 e->flags = 0;
1201 static void add_share_mode_entry(struct share_mode_lock *lck,
1202 const struct share_mode_entry *entry)
1204 int i;
1206 for (i=0; i<lck->num_share_modes; i++) {
1207 struct share_mode_entry *e = &lck->share_modes[i];
1208 if (is_unused_share_mode_entry(e)) {
1209 *e = *entry;
1210 break;
1214 if (i == lck->num_share_modes) {
1215 /* No unused entry found */
1216 ADD_TO_ARRAY(lck, struct share_mode_entry, *entry,
1217 &lck->share_modes, &lck->num_share_modes);
1219 lck->modified = True;
1222 void set_share_mode(struct share_mode_lock *lck, files_struct *fsp,
1223 uid_t uid, uint64_t mid, uint16 op_type)
1225 struct share_mode_entry entry;
1226 fill_share_mode_entry(&entry, fsp, uid, mid, op_type);
1227 add_share_mode_entry(lck, &entry);
1230 void add_deferred_open(struct share_mode_lock *lck, uint64_t mid,
1231 struct timeval request_time,
1232 struct server_id pid, struct file_id id)
1234 struct share_mode_entry entry;
1235 fill_deferred_open_entry(&entry, request_time, id, pid, mid);
1236 add_share_mode_entry(lck, &entry);
1239 /*******************************************************************
1240 Check if two share mode entries are identical, ignoring oplock
1241 and mid info and desired_access. (Removed paranoia test - it's
1242 not automatically a logic error if they are identical. JRA.)
1243 ********************************************************************/
1245 static bool share_modes_identical(struct share_mode_entry *e1,
1246 struct share_mode_entry *e2)
1248 /* We used to check for e1->share_access == e2->share_access here
1249 as well as the other fields but 2 different DOS or FCB opens
1250 sharing the same share mode entry may validly differ in
1251 fsp->share_access field. */
1253 return (procid_equal(&e1->pid, &e2->pid) &&
1254 file_id_equal(&e1->id, &e2->id) &&
1255 e1->share_file_id == e2->share_file_id );
1258 static bool deferred_open_identical(struct share_mode_entry *e1,
1259 struct share_mode_entry *e2)
1261 return (procid_equal(&e1->pid, &e2->pid) &&
1262 (e1->op_mid == e2->op_mid) &&
1263 file_id_equal(&e1->id, &e2->id));
1266 static struct share_mode_entry *find_share_mode_entry(struct share_mode_lock *lck,
1267 struct share_mode_entry *entry)
1269 int i;
1271 for (i=0; i<lck->num_share_modes; i++) {
1272 struct share_mode_entry *e = &lck->share_modes[i];
1273 if (is_valid_share_mode_entry(entry) &&
1274 is_valid_share_mode_entry(e) &&
1275 share_modes_identical(e, entry)) {
1276 return e;
1278 if (is_deferred_open_entry(entry) &&
1279 is_deferred_open_entry(e) &&
1280 deferred_open_identical(e, entry)) {
1281 return e;
1284 return NULL;
1287 /*******************************************************************
1288 Del the share mode of a file for this process. Return the number of
1289 entries left.
1290 ********************************************************************/
1292 bool del_share_mode(struct share_mode_lock *lck, files_struct *fsp)
1294 struct share_mode_entry entry, *e;
1296 /* Don't care about the pid owner being correct here - just a search. */
1297 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1299 e = find_share_mode_entry(lck, &entry);
1300 if (e == NULL) {
1301 return False;
1304 e->op_type = UNUSED_SHARE_MODE_ENTRY;
1305 lck->modified = True;
1306 return True;
1309 void del_deferred_open_entry(struct share_mode_lock *lck, uint64_t mid,
1310 struct server_id pid)
1312 struct share_mode_entry entry, *e;
1314 fill_deferred_open_entry(&entry, timeval_zero(),
1315 lck->id, pid, mid);
1317 e = find_share_mode_entry(lck, &entry);
1318 if (e == NULL) {
1319 return;
1322 e->op_type = UNUSED_SHARE_MODE_ENTRY;
1323 lck->modified = True;
1326 /*******************************************************************
1327 Remove an oplock mid and mode entry from a share mode.
1328 ********************************************************************/
1330 bool remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
1332 struct share_mode_entry entry, *e;
1334 /* Don't care about the pid owner being correct here - just a search. */
1335 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1337 e = find_share_mode_entry(lck, &entry);
1338 if (e == NULL) {
1339 return False;
1342 if (EXCLUSIVE_OPLOCK_TYPE(e->op_type)) {
1344 * Going from exclusive or batch,
1345 * we always go through FAKE_LEVEL_II
1346 * first.
1348 if (!EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1349 smb_panic("remove_share_oplock: logic error");
1351 e->op_type = FAKE_LEVEL_II_OPLOCK;
1352 } else {
1353 e->op_type = NO_OPLOCK;
1355 lck->modified = True;
1356 return True;
1359 /*******************************************************************
1360 Downgrade a oplock type from exclusive to level II.
1361 ********************************************************************/
1363 bool downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
1365 struct share_mode_entry entry, *e;
1367 /* Don't care about the pid owner being correct here - just a search. */
1368 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1370 e = find_share_mode_entry(lck, &entry);
1371 if (e == NULL) {
1372 return False;
1375 e->op_type = LEVEL_II_OPLOCK;
1376 lck->modified = True;
1377 return True;
1380 /****************************************************************************
1381 Check if setting delete on close is allowed on this fsp.
1382 ****************************************************************************/
1384 NTSTATUS can_set_delete_on_close(files_struct *fsp, uint32 dosmode)
1387 * Only allow delete on close for writable files.
1390 if ((dosmode & FILE_ATTRIBUTE_READONLY) &&
1391 !lp_delete_readonly(SNUM(fsp->conn))) {
1392 DEBUG(10,("can_set_delete_on_close: file %s delete on close "
1393 "flag set but file attribute is readonly.\n",
1394 fsp_str_dbg(fsp)));
1395 return NT_STATUS_CANNOT_DELETE;
1399 * Only allow delete on close for writable shares.
1402 if (!CAN_WRITE(fsp->conn)) {
1403 DEBUG(10,("can_set_delete_on_close: file %s delete on "
1404 "close flag set but write access denied on share.\n",
1405 fsp_str_dbg(fsp)));
1406 return NT_STATUS_ACCESS_DENIED;
1410 * Only allow delete on close for files/directories opened with delete
1411 * intent.
1414 if (!(fsp->access_mask & DELETE_ACCESS)) {
1415 DEBUG(10,("can_set_delete_on_close: file %s delete on "
1416 "close flag set but delete access denied.\n",
1417 fsp_str_dbg(fsp)));
1418 return NT_STATUS_ACCESS_DENIED;
1421 /* Don't allow delete on close for non-empty directories. */
1422 if (fsp->is_directory) {
1423 SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name));
1425 /* Or the root of a share. */
1426 if (ISDOT(fsp->fsp_name->base_name)) {
1427 DEBUG(10,("can_set_delete_on_close: can't set delete on "
1428 "close for the root of a share.\n"));
1429 return NT_STATUS_ACCESS_DENIED;
1432 return can_delete_directory(fsp->conn,
1433 fsp->fsp_name->base_name);
1436 return NT_STATUS_OK;
1439 /*************************************************************************
1440 Return a talloced copy of a struct security_unix_token. NULL on fail.
1441 (Should this be in locking.c.... ?).
1442 *************************************************************************/
1444 static struct security_unix_token *copy_unix_token(TALLOC_CTX *ctx, const struct security_unix_token *tok)
1446 struct security_unix_token *cpy;
1448 cpy = TALLOC_P(ctx, struct security_unix_token);
1449 if (!cpy) {
1450 return NULL;
1453 cpy->uid = tok->uid;
1454 cpy->gid = tok->gid;
1455 cpy->ngroups = tok->ngroups;
1456 if (tok->ngroups) {
1457 /* Make this a talloc child of cpy. */
1458 cpy->groups = TALLOC_ARRAY(cpy, gid_t, tok->ngroups);
1459 if (!cpy->groups) {
1460 return NULL;
1462 memcpy(cpy->groups, tok->groups, tok->ngroups * sizeof(gid_t));
1464 return cpy;
1467 /****************************************************************************
1468 Adds a delete on close token.
1469 ****************************************************************************/
1471 static bool add_delete_on_close_token(struct share_mode_lock *lck,
1472 uint32_t name_hash,
1473 const struct security_unix_token *tok)
1475 struct delete_token_list *dtl;
1477 dtl = TALLOC_ZERO_P(lck, struct delete_token_list);
1478 if (dtl == NULL) {
1479 return false;
1482 dtl->name_hash = name_hash;
1483 dtl->delete_token = copy_unix_token(dtl, tok);
1484 if (dtl->delete_token == NULL) {
1485 TALLOC_FREE(dtl);
1486 return false;
1488 DLIST_ADD(lck->delete_tokens, dtl);
1489 lck->modified = true;
1490 return true;
1493 /****************************************************************************
1494 Sets the delete on close flag over all share modes on this file.
1495 Modify the share mode entry for all files open
1496 on this device and inode to tell other smbds we have
1497 changed the delete on close flag. This will be noticed
1498 in the close code, the last closer will delete the file
1499 if flag is set.
1500 This makes a copy of any struct security_unix_token into the
1501 lck entry. This function is used when the lock is already granted.
1502 ****************************************************************************/
1504 void set_delete_on_close_lck(files_struct *fsp,
1505 struct share_mode_lock *lck,
1506 bool delete_on_close,
1507 const struct security_unix_token *tok)
1509 struct delete_token_list *dtl;
1510 bool ret;
1512 if (delete_on_close) {
1513 SMB_ASSERT(tok != NULL);
1514 } else {
1515 SMB_ASSERT(tok == NULL);
1518 for (dtl = lck->delete_tokens; dtl; dtl = dtl->next) {
1519 if (dtl->name_hash == fsp->name_hash) {
1520 lck->modified = true;
1521 if (delete_on_close == false) {
1522 /* Delete this entry. */
1523 DLIST_REMOVE(lck->delete_tokens, dtl);
1524 TALLOC_FREE(dtl);
1525 } else {
1526 /* Replace this token with the
1527 given tok. */
1528 TALLOC_FREE(dtl->delete_token);
1529 dtl->delete_token = copy_unix_token(dtl, tok);
1530 SMB_ASSERT(dtl->delete_token != NULL);
1532 return;
1536 if (!delete_on_close) {
1537 /* Nothing to delete - not found. */
1538 return;
1541 ret = add_delete_on_close_token(lck, fsp->name_hash, tok);
1542 SMB_ASSERT(ret);
1545 bool set_delete_on_close(files_struct *fsp, bool delete_on_close, const struct security_unix_token *tok)
1547 struct share_mode_lock *lck;
1549 DEBUG(10,("set_delete_on_close: %s delete on close flag for "
1550 "fnum = %d, file %s\n",
1551 delete_on_close ? "Adding" : "Removing", fsp->fnum,
1552 fsp_str_dbg(fsp)));
1554 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
1555 NULL);
1556 if (lck == NULL) {
1557 return False;
1560 set_delete_on_close_lck(fsp, lck, delete_on_close,
1561 delete_on_close ? tok : NULL);
1563 if (fsp->is_directory) {
1564 SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name));
1565 send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
1566 fsp->fsp_name->base_name);
1569 TALLOC_FREE(lck);
1571 fsp->delete_on_close = delete_on_close;
1573 return True;
1576 const struct security_unix_token *get_delete_on_close_token(struct share_mode_lock *lck, uint32_t name_hash)
1578 struct delete_token_list *dtl;
1580 DEBUG(10,("get_delete_on_close_token: name_hash = 0x%x\n",
1581 (unsigned int)name_hash ));
1583 for (dtl = lck->delete_tokens; dtl; dtl = dtl->next) {
1584 DEBUG(10,("get_delete_on_close_token: dtl->name_hash = 0x%x\n",
1585 (unsigned int)dtl->name_hash ));
1586 if (dtl->name_hash == name_hash) {
1587 return dtl->delete_token;
1590 return NULL;
1593 bool is_delete_on_close_set(struct share_mode_lock *lck, uint32_t name_hash)
1595 return (get_delete_on_close_token(lck, name_hash) != NULL);
1598 bool set_sticky_write_time(struct file_id fileid, struct timespec write_time)
1600 struct share_mode_lock *lck;
1602 DEBUG(5,("set_sticky_write_time: %s id=%s\n",
1603 timestring(talloc_tos(),
1604 convert_timespec_to_time_t(write_time)),
1605 file_id_string_tos(&fileid)));
1607 lck = get_share_mode_lock(NULL, fileid, NULL, NULL, NULL);
1608 if (lck == NULL) {
1609 return False;
1612 if (timespec_compare(&lck->changed_write_time, &write_time) != 0) {
1613 lck->modified = True;
1614 lck->changed_write_time = write_time;
1617 TALLOC_FREE(lck);
1618 return True;
1621 bool set_write_time(struct file_id fileid, struct timespec write_time)
1623 struct share_mode_lock *lck;
1625 DEBUG(5,("set_write_time: %s id=%s\n",
1626 timestring(talloc_tos(),
1627 convert_timespec_to_time_t(write_time)),
1628 file_id_string_tos(&fileid)));
1630 lck = get_share_mode_lock(NULL, fileid, NULL, NULL, NULL);
1631 if (lck == NULL) {
1632 return False;
1635 if (timespec_compare(&lck->old_write_time, &write_time) != 0) {
1636 lck->modified = True;
1637 lck->old_write_time = write_time;
1640 TALLOC_FREE(lck);
1641 return True;
1645 struct forall_state {
1646 void (*fn)(const struct share_mode_entry *entry,
1647 const char *sharepath,
1648 const char *fname,
1649 void *private_data);
1650 void *private_data;
1653 static int traverse_fn(struct db_record *rec, void *_state)
1655 struct forall_state *state = (struct forall_state *)_state;
1656 struct locking_data *data;
1657 struct share_mode_entry *shares;
1658 const char *sharepath;
1659 const char *fname;
1660 const char *del_tokens;
1661 uint32_t total_del_token_size = 0;
1662 int i;
1664 /* Ensure this is a locking_key record. */
1665 if (rec->key.dsize != sizeof(struct file_id))
1666 return 0;
1668 data = (struct locking_data *)rec->value.dptr;
1669 shares = (struct share_mode_entry *)(rec->value.dptr + sizeof(*data));
1670 del_tokens = (const char *)rec->value.dptr + sizeof(*data) +
1671 data->u.s.num_share_mode_entries*sizeof(*shares);
1673 for (i = 0; i < data->u.s.num_delete_token_entries; i++) {
1674 uint32_t del_token_size;
1675 memcpy(&del_token_size, del_tokens, sizeof(uint32_t));
1676 total_del_token_size += del_token_size;
1677 del_tokens += del_token_size;
1680 sharepath = (const char *)rec->value.dptr + sizeof(*data) +
1681 data->u.s.num_share_mode_entries*sizeof(*shares) +
1682 total_del_token_size;
1683 fname = (const char *)rec->value.dptr + sizeof(*data) +
1684 data->u.s.num_share_mode_entries*sizeof(*shares) +
1685 total_del_token_size +
1686 strlen(sharepath) + 1;
1688 for (i=0;i<data->u.s.num_share_mode_entries;i++) {
1689 state->fn(&shares[i], sharepath, fname,
1690 state->private_data);
1692 return 0;
1695 /*******************************************************************
1696 Call the specified function on each entry under management by the
1697 share mode system.
1698 ********************************************************************/
1700 int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *,
1701 const char *, void *),
1702 void *private_data)
1704 struct forall_state state;
1706 if (lock_db == NULL)
1707 return 0;
1709 state.fn = fn;
1710 state.private_data = private_data;
1712 return lock_db->traverse_read(lock_db, traverse_fn, (void *)&state);