s3:include: implement trans_oob() as wrapper to smb_buffer_oob()
[Samba/gebeck_regimport.git] / source3 / locking / locking.c
blob38d8c090a68b7af01b630a8939f0bdd5c3d35668
1 /*
2 Unix SMB/CIFS implementation.
3 Locking functions
4 Copyright (C) Andrew Tridgell 1992-2000
5 Copyright (C) Jeremy Allison 1992-2006
6 Copyright (C) Volker Lendecke 2005
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 Revision History:
23 12 aug 96: Erik.Devriendt@te6.siemens.be
24 added support for shared memory implementation of share mode locking
26 May 1997. Jeremy Allison (jallison@whistle.com). Modified share mode
27 locking to deal with multiple share modes per open file.
29 September 1997. Jeremy Allison (jallison@whistle.com). Added oplock
30 support.
32 rewrtten completely to use new tdb code. Tridge, Dec '99
34 Added POSIX locking support. Jeremy Allison (jeremy@valinux.com), Apr. 2000.
35 Added Unix Extensions POSIX locking support. Jeremy Allison Mar 2006.
38 #include "includes.h"
39 #include "system/filesys.h"
40 #include "locking/proto.h"
41 #include "smbd/globals.h"
42 #include "dbwrap/dbwrap.h"
43 #include "dbwrap/dbwrap_open.h"
44 #include "../libcli/security/security.h"
45 #include "serverid.h"
46 #include "messages.h"
47 #include "util_tdb.h"
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 uint32_t token_len;
556 struct delete_token_list *pdtl;
558 if (end_ptr - p < (sizeof(uint32_t) + sizeof(uint32_t) +
559 sizeof(uid_t) + sizeof(gid_t))) {
560 DEBUG(0,("parse_delete_tokens_list: "
561 "corrupt token list (%u)",
562 (unsigned int)(end_ptr - p)));
563 smb_panic("corrupt token list");
564 return -1;
567 memcpy(&token_len, p, sizeof(token_len));
568 delete_tokens_size += token_len;
570 if (p + token_len > end_ptr || token_len < sizeof(token_len) +
571 sizeof(pdtl->name_hash) +
572 sizeof(uid_t) +
573 sizeof(gid_t)) {
574 DEBUG(0,("parse_delete_tokens_list: "
575 "invalid token length (%u)\n",
576 (unsigned int)token_len ));
577 smb_panic("invalid token length");
578 return -1;
581 p += sizeof(token_len);
583 pdtl = talloc_zero(lck, struct delete_token_list);
584 if (pdtl == NULL) {
585 DEBUG(0,("parse_delete_tokens_list: talloc failed"));
586 return -1;
588 /* Copy out the name_hash. */
589 memcpy(&pdtl->name_hash, p, sizeof(pdtl->name_hash));
590 p += sizeof(pdtl->name_hash);
592 pdtl->delete_token = talloc_zero(pdtl, struct security_unix_token);
593 if (pdtl->delete_token == NULL) {
594 DEBUG(0,("parse_delete_tokens_list: talloc failed"));
595 return -1;
598 /* Copy out the uid and gid. */
599 memcpy(&pdtl->delete_token->uid, p, sizeof(uid_t));
600 p += sizeof(uid_t);
601 memcpy(&pdtl->delete_token->gid, p, sizeof(gid_t));
602 p += sizeof(gid_t);
604 token_len -= (sizeof(token_len) + sizeof(pdtl->name_hash) +
605 sizeof(uid_t) + sizeof(gid_t));
607 /* Any supplementary groups ? */
608 if (token_len) {
609 int j;
611 if (token_len % sizeof(gid_t) != 0) {
612 DEBUG(0,("parse_delete_tokens_list: "
613 "corrupt group list (%u)",
614 (unsigned int)(token_len % sizeof(gid_t)) ));
615 smb_panic("corrupt group list");
616 return -1;
619 pdtl->delete_token->ngroups = token_len / sizeof(gid_t);
620 pdtl->delete_token->groups = talloc_array(pdtl->delete_token, gid_t,
621 pdtl->delete_token->ngroups);
622 if (pdtl->delete_token->groups == NULL) {
623 DEBUG(0,("parse_delete_tokens_list: talloc failed"));
624 return -1;
627 for (j = 0; j < pdtl->delete_token->ngroups; j++) {
628 memcpy(&pdtl->delete_token->groups[j], p, sizeof(gid_t));
629 p += sizeof(gid_t);
632 /* Add to the list. */
633 DLIST_ADD(lck->delete_tokens, pdtl);
636 return delete_tokens_size;
639 /*******************************************************************
640 Get all share mode entries for a dev/inode pair.
641 ********************************************************************/
643 static bool parse_share_modes(const TDB_DATA dbuf, struct share_mode_lock *lck)
645 struct locking_data data;
646 int delete_tokens_size;
647 int i;
649 if (dbuf.dsize < sizeof(struct locking_data)) {
650 smb_panic("parse_share_modes: buffer too short");
653 memcpy(&data, dbuf.dptr, sizeof(data));
655 lck->old_write_time = data.u.s.old_write_time;
656 lck->changed_write_time = data.u.s.changed_write_time;
657 lck->num_share_modes = data.u.s.num_share_mode_entries;
659 DEBUG(10, ("parse_share_modes: owrt: %s, "
660 "cwrt: %s, ntok: %u, num_share_modes: %d\n",
661 timestring(talloc_tos(),
662 convert_timespec_to_time_t(lck->old_write_time)),
663 timestring(talloc_tos(),
664 convert_timespec_to_time_t(
665 lck->changed_write_time)),
666 (unsigned int)data.u.s.num_delete_token_entries,
667 lck->num_share_modes));
669 if ((lck->num_share_modes < 0) || (lck->num_share_modes > 1000000)) {
670 DEBUG(0, ("invalid number of share modes: %d\n",
671 lck->num_share_modes));
672 smb_panic("parse_share_modes: invalid number of share modes");
675 lck->share_modes = NULL;
677 if (lck->num_share_modes != 0) {
679 if (dbuf.dsize < (sizeof(struct locking_data) +
680 (lck->num_share_modes *
681 sizeof(struct share_mode_entry)))) {
682 smb_panic("parse_share_modes: buffer too short");
685 lck->share_modes = (struct share_mode_entry *)
686 talloc_memdup(lck,
687 dbuf.dptr+sizeof(struct locking_data),
688 lck->num_share_modes *
689 sizeof(struct share_mode_entry));
691 if (lck->share_modes == NULL) {
692 smb_panic("parse_share_modes: talloc failed");
696 /* Get any delete tokens. */
697 delete_tokens_size = parse_delete_tokens_list(lck, &data, dbuf);
698 if (delete_tokens_size < 0) {
699 smb_panic("parse_share_modes: parse_delete_tokens_list failed");
702 /* Save off the associated service path and filename. */
703 lck->servicepath = (const char *)dbuf.dptr + sizeof(struct locking_data) +
704 (lck->num_share_modes * sizeof(struct share_mode_entry)) +
705 delete_tokens_size;
707 lck->base_name = (const char *)dbuf.dptr + sizeof(struct locking_data) +
708 (lck->num_share_modes * sizeof(struct share_mode_entry)) +
709 delete_tokens_size +
710 strlen(lck->servicepath) + 1;
712 lck->stream_name = (const char *)dbuf.dptr + sizeof(struct locking_data) +
713 (lck->num_share_modes * sizeof(struct share_mode_entry)) +
714 delete_tokens_size +
715 strlen(lck->servicepath) + 1 +
716 strlen(lck->base_name) + 1;
719 * Ensure that each entry has a real process attached.
722 for (i = 0; i < lck->num_share_modes; i++) {
723 struct share_mode_entry *entry_p = &lck->share_modes[i];
724 char *str = NULL;
725 if (DEBUGLEVEL >= 10) {
726 str = share_mode_str(NULL, i, entry_p);
728 DEBUG(10,("parse_share_modes: %s\n",
729 str ? str : ""));
730 if (!serverid_exists(&entry_p->pid)) {
731 DEBUG(10,("parse_share_modes: deleted %s\n",
732 str ? str : ""));
733 entry_p->op_type = UNUSED_SHARE_MODE_ENTRY;
734 lck->modified = True;
736 TALLOC_FREE(str);
739 return True;
742 static TDB_DATA unparse_share_modes(const struct share_mode_lock *lck)
744 TDB_DATA result;
745 int num_valid = 0;
746 int i;
747 struct locking_data *data;
748 ssize_t offset;
749 ssize_t sp_len, bn_len, sn_len;
750 uint32_t delete_tokens_size = 0;
751 struct delete_token_list *pdtl = NULL;
752 uint32_t num_delete_token_entries = 0;
754 result.dptr = NULL;
755 result.dsize = 0;
757 for (i=0; i<lck->num_share_modes; i++) {
758 if (!is_unused_share_mode_entry(&lck->share_modes[i])) {
759 num_valid += 1;
763 if (num_valid == 0) {
764 return result;
767 sp_len = strlen(lck->servicepath);
768 bn_len = strlen(lck->base_name);
769 sn_len = lck->stream_name != NULL ? strlen(lck->stream_name) : 0;
771 for (pdtl = lck->delete_tokens; pdtl; pdtl = pdtl->next) {
772 num_delete_token_entries++;
773 delete_tokens_size += (sizeof(uint32_t) +
774 sizeof(uint32_t) +
775 sizeof(uid_t) +
776 sizeof(gid_t) +
777 pdtl->delete_token->ngroups*sizeof(gid_t));
780 result.dsize = sizeof(*data) +
781 lck->num_share_modes * sizeof(struct share_mode_entry) +
782 delete_tokens_size +
783 sp_len + 1 +
784 bn_len + 1 +
785 sn_len + 1;
786 result.dptr = talloc_array(lck, uint8, result.dsize);
788 if (result.dptr == NULL) {
789 smb_panic("talloc failed");
792 data = (struct locking_data *)result.dptr;
793 ZERO_STRUCTP(data);
794 data->u.s.num_share_mode_entries = lck->num_share_modes;
795 data->u.s.old_write_time = lck->old_write_time;
796 data->u.s.changed_write_time = lck->changed_write_time;
797 data->u.s.num_delete_token_entries = num_delete_token_entries;
799 DEBUG(10,("unparse_share_modes: owrt: %s cwrt: %s, ntok: %u, "
800 "num: %d\n",
801 timestring(talloc_tos(),
802 convert_timespec_to_time_t(lck->old_write_time)),
803 timestring(talloc_tos(),
804 convert_timespec_to_time_t(
805 lck->changed_write_time)),
806 (unsigned int)data->u.s.num_delete_token_entries,
807 data->u.s.num_share_mode_entries));
809 memcpy(result.dptr + sizeof(*data), lck->share_modes,
810 sizeof(struct share_mode_entry)*lck->num_share_modes);
811 offset = sizeof(*data) +
812 sizeof(struct share_mode_entry)*lck->num_share_modes;
814 /* Store any delete on close tokens. */
815 for (pdtl = lck->delete_tokens; pdtl; pdtl = pdtl->next) {
816 struct security_unix_token *pdt = pdtl->delete_token;
817 uint32_t token_size = sizeof(uint32_t) +
818 sizeof(uint32_t) +
819 sizeof(uid_t) +
820 sizeof(gid_t) +
821 (pdt->ngroups * sizeof(gid_t));
822 uint8_t *p = result.dptr + offset;
824 memcpy(p, &token_size, sizeof(uint32_t));
825 p += sizeof(uint32_t);
827 memcpy(p, &pdtl->name_hash, sizeof(uint32_t));
828 p += sizeof(uint32_t);
830 memcpy(p, &pdt->uid, sizeof(uid_t));
831 p += sizeof(uid_t);
833 memcpy(p, &pdt->gid, sizeof(gid_t));
834 p += sizeof(gid_t);
836 for (i = 0; i < pdt->ngroups; i++) {
837 memcpy(p, &pdt->groups[i], sizeof(gid_t));
838 p += sizeof(gid_t);
840 offset += token_size;
843 strlcpy((char *)result.dptr + offset,
844 lck->servicepath ? lck->servicepath : "",
845 result.dsize - offset);
846 offset += sp_len + 1;
847 strlcpy((char *)result.dptr + offset,
848 lck->base_name ? lck->base_name : "",
849 result.dsize - offset);
850 offset += bn_len + 1;
851 strlcpy((char *)result.dptr + offset,
852 lck->stream_name ? lck->stream_name : "",
853 result.dsize - offset);
855 if (DEBUGLEVEL >= 10) {
856 print_share_mode_table(data);
859 return result;
862 static int share_mode_lock_destructor(struct share_mode_lock *lck)
864 NTSTATUS status;
865 TDB_DATA data;
867 if (!lck->modified) {
868 return 0;
871 data = unparse_share_modes(lck);
873 if (data.dptr == NULL) {
874 if (!lck->fresh) {
875 /* There has been an entry before, delete it */
877 status = dbwrap_record_delete(lck->record);
878 if (!NT_STATUS_IS_OK(status)) {
879 char *errmsg;
881 DEBUG(0, ("delete_rec returned %s\n",
882 nt_errstr(status)));
884 if (asprintf(&errmsg, "could not delete share "
885 "entry: %s\n",
886 nt_errstr(status)) == -1) {
887 smb_panic("could not delete share"
888 "entry");
890 smb_panic(errmsg);
893 goto done;
896 status = dbwrap_record_store(lck->record, data, TDB_REPLACE);
897 if (!NT_STATUS_IS_OK(status)) {
898 char *errmsg;
900 DEBUG(0, ("store returned %s\n", nt_errstr(status)));
902 if (asprintf(&errmsg, "could not store share mode entry: %s",
903 nt_errstr(status)) == -1) {
904 smb_panic("could not store share mode entry");
906 smb_panic(errmsg);
909 done:
911 return 0;
914 static bool fill_share_mode_lock(struct share_mode_lock *lck,
915 struct file_id id,
916 const char *servicepath,
917 const struct smb_filename *smb_fname,
918 TDB_DATA share_mode_data,
919 const struct timespec *old_write_time)
921 /* Ensure we set every field here as the destructor must be
922 valid even if parse_share_modes fails. */
924 lck->servicepath = NULL;
925 lck->base_name = NULL;
926 lck->stream_name = NULL;
927 lck->id = id;
928 lck->num_share_modes = 0;
929 lck->share_modes = NULL;
930 lck->delete_tokens = NULL;
931 ZERO_STRUCT(lck->old_write_time);
932 ZERO_STRUCT(lck->changed_write_time);
933 lck->fresh = False;
934 lck->modified = False;
936 lck->fresh = (share_mode_data.dptr == NULL);
938 if (lck->fresh) {
939 bool has_stream;
940 if (smb_fname == NULL || servicepath == NULL
941 || old_write_time == NULL) {
942 return False;
945 has_stream = smb_fname->stream_name != NULL;
947 lck->base_name = talloc_strdup(lck, smb_fname->base_name);
948 lck->stream_name = talloc_strdup(lck, smb_fname->stream_name);
949 lck->servicepath = talloc_strdup(lck, servicepath);
950 if (lck->base_name == NULL ||
951 (has_stream && lck->stream_name == NULL) ||
952 lck->servicepath == NULL) {
953 DEBUG(0, ("talloc failed\n"));
954 return False;
956 lck->old_write_time = *old_write_time;
957 } else {
958 if (!parse_share_modes(share_mode_data, lck)) {
959 DEBUG(0, ("Could not parse share modes\n"));
960 return False;
964 return True;
967 struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
968 const struct file_id id,
969 const char *servicepath,
970 const struct smb_filename *smb_fname,
971 const struct timespec *old_write_time)
973 struct share_mode_lock *lck;
974 struct file_id tmp;
975 TDB_DATA key = locking_key(&id, &tmp);
976 TDB_DATA value;
978 if (!(lck = talloc(mem_ctx, struct share_mode_lock))) {
979 DEBUG(0, ("talloc failed\n"));
980 return NULL;
983 if (!(lck->record = dbwrap_fetch_locked(lock_db, lck, key))) {
984 DEBUG(3, ("Could not lock share entry\n"));
985 TALLOC_FREE(lck);
986 return NULL;
989 value = dbwrap_record_get_value(lck->record);
991 if (!fill_share_mode_lock(lck, id, servicepath, smb_fname,
992 value, old_write_time)) {
993 DEBUG(3, ("fill_share_mode_lock failed\n"));
994 TALLOC_FREE(lck);
995 return NULL;
998 talloc_set_destructor(lck, share_mode_lock_destructor);
1000 return lck;
1003 struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx,
1004 const struct file_id id)
1006 struct share_mode_lock *lck;
1007 struct file_id tmp;
1008 TDB_DATA key = locking_key(&id, &tmp);
1009 TDB_DATA data;
1010 NTSTATUS status;
1012 if (!(lck = talloc(mem_ctx, struct share_mode_lock))) {
1013 DEBUG(0, ("talloc failed\n"));
1014 return NULL;
1017 status = dbwrap_fetch(lock_db, lck, key, &data);
1018 if (!NT_STATUS_IS_OK(status)) {
1019 DEBUG(3, ("Could not fetch share entry\n"));
1020 TALLOC_FREE(lck);
1021 return NULL;
1024 if (!fill_share_mode_lock(lck, id, NULL, NULL, data, NULL)) {
1025 DEBUG(10, ("fetch_share_mode_unlocked: no share_mode record "
1026 "around (file not open)\n"));
1027 TALLOC_FREE(lck);
1028 return NULL;
1031 return lck;
1034 /*******************************************************************
1035 Sets the service name and filename for rename.
1036 At this point we emit "file renamed" messages to all
1037 process id's that have this file open.
1038 Based on an initial code idea from SATOH Fumiyasu <fumiya@samba.gr.jp>
1039 ********************************************************************/
1041 bool rename_share_filename(struct messaging_context *msg_ctx,
1042 struct share_mode_lock *lck,
1043 const char *servicepath,
1044 uint32_t orig_name_hash,
1045 uint32_t new_name_hash,
1046 const struct smb_filename *smb_fname_dst)
1048 size_t sp_len;
1049 size_t bn_len;
1050 size_t sn_len;
1051 size_t msg_len;
1052 char *frm = NULL;
1053 int i;
1054 bool strip_two_chars = false;
1055 bool has_stream = smb_fname_dst->stream_name != NULL;
1057 DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n",
1058 servicepath, smb_fname_dst->base_name));
1061 * rename_internal_fsp() and rename_internals() add './' to
1062 * head of newname if newname does not contain a '/'.
1064 if (smb_fname_dst->base_name[0] &&
1065 smb_fname_dst->base_name[1] &&
1066 smb_fname_dst->base_name[0] == '.' &&
1067 smb_fname_dst->base_name[1] == '/') {
1068 strip_two_chars = true;
1071 lck->servicepath = talloc_strdup(lck, servicepath);
1072 lck->base_name = talloc_strdup(lck, smb_fname_dst->base_name +
1073 (strip_two_chars ? 2 : 0));
1074 lck->stream_name = talloc_strdup(lck, smb_fname_dst->stream_name);
1075 if (lck->base_name == NULL ||
1076 (has_stream && lck->stream_name == NULL) ||
1077 lck->servicepath == NULL) {
1078 DEBUG(0, ("rename_share_filename: talloc failed\n"));
1079 return False;
1081 lck->modified = True;
1083 sp_len = strlen(lck->servicepath);
1084 bn_len = strlen(lck->base_name);
1085 sn_len = has_stream ? strlen(lck->stream_name) : 0;
1087 msg_len = MSG_FILE_RENAMED_MIN_SIZE + sp_len + 1 + bn_len + 1 +
1088 sn_len + 1;
1090 /* Set up the name changed message. */
1091 frm = talloc_array(lck, char, msg_len);
1092 if (!frm) {
1093 return False;
1096 push_file_id_24(frm, &lck->id);
1098 DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len ));
1100 strlcpy(&frm[24],
1101 lck->servicepath ? lck->servicepath : "",
1102 sp_len+1);
1103 strlcpy(&frm[24 + sp_len + 1],
1104 lck->base_name ? lck->base_name : "",
1105 bn_len+1);
1106 strlcpy(&frm[24 + sp_len + 1 + bn_len + 1],
1107 lck->stream_name ? lck->stream_name : "",
1108 sn_len+1);
1110 /* Send the messages. */
1111 for (i=0; i<lck->num_share_modes; i++) {
1112 struct share_mode_entry *se = &lck->share_modes[i];
1113 if (!is_valid_share_mode_entry(se)) {
1114 continue;
1117 /* If this is a hardlink to the inode
1118 with a different name, skip this. */
1119 if (se->name_hash != orig_name_hash) {
1120 continue;
1123 se->name_hash = new_name_hash;
1125 /* But not to ourselves... */
1126 if (procid_is_me(&se->pid)) {
1127 continue;
1130 DEBUG(10,("rename_share_filename: sending rename message to "
1131 "pid %s file_id %s sharepath %s base_name %s "
1132 "stream_name %s\n",
1133 procid_str_static(&se->pid),
1134 file_id_string_tos(&lck->id),
1135 lck->servicepath, lck->base_name,
1136 has_stream ? lck->stream_name : ""));
1138 messaging_send_buf(msg_ctx, se->pid, MSG_SMB_FILE_RENAME,
1139 (uint8 *)frm, msg_len);
1142 return True;
1145 void get_file_infos(struct file_id id,
1146 uint32_t name_hash,
1147 bool *delete_on_close,
1148 struct timespec *write_time)
1150 struct share_mode_lock *lck;
1152 if (delete_on_close) {
1153 *delete_on_close = false;
1156 if (write_time) {
1157 ZERO_STRUCTP(write_time);
1160 if (!(lck = fetch_share_mode_unlocked(talloc_tos(), id))) {
1161 return;
1164 if (delete_on_close) {
1165 *delete_on_close = is_delete_on_close_set(lck, name_hash);
1168 if (write_time) {
1169 struct timespec wt;
1171 wt = lck->changed_write_time;
1172 if (null_timespec(wt)) {
1173 wt = lck->old_write_time;
1176 *write_time = wt;
1179 TALLOC_FREE(lck);
1182 bool is_valid_share_mode_entry(const struct share_mode_entry *e)
1184 int num_props = 0;
1186 if (e->op_type == UNUSED_SHARE_MODE_ENTRY) {
1187 /* cope with dead entries from the process not
1188 existing. These should not be considered valid,
1189 otherwise we end up doing zero timeout sharing
1190 violation */
1191 return False;
1194 num_props += ((e->op_type == NO_OPLOCK) ? 1 : 0);
1195 num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0);
1196 num_props += (LEVEL_II_OPLOCK_TYPE(e->op_type) ? 1 : 0);
1198 SMB_ASSERT(num_props <= 1);
1199 return (num_props != 0);
1202 bool is_deferred_open_entry(const struct share_mode_entry *e)
1204 return (e->op_type == DEFERRED_OPEN_ENTRY);
1207 bool is_unused_share_mode_entry(const struct share_mode_entry *e)
1209 return (e->op_type == UNUSED_SHARE_MODE_ENTRY);
1212 /*******************************************************************
1213 Fill a share mode entry.
1214 ********************************************************************/
1216 static void fill_share_mode_entry(struct share_mode_entry *e,
1217 files_struct *fsp,
1218 uid_t uid, uint64_t mid, uint16 op_type)
1220 ZERO_STRUCTP(e);
1221 e->pid = sconn_server_id(fsp->conn->sconn);
1222 e->share_access = fsp->share_access;
1223 e->private_options = fsp->fh->private_options;
1224 e->access_mask = fsp->access_mask;
1225 e->op_mid = mid;
1226 e->op_type = op_type;
1227 e->time.tv_sec = fsp->open_time.tv_sec;
1228 e->time.tv_usec = fsp->open_time.tv_usec;
1229 e->id = fsp->file_id;
1230 e->share_file_id = fsp->fh->gen_id;
1231 e->uid = (uint32)uid;
1232 e->flags = fsp->posix_open ? SHARE_MODE_FLAG_POSIX_OPEN : 0;
1233 e->name_hash = fsp->name_hash;
1236 static void fill_deferred_open_entry(struct share_mode_entry *e,
1237 const struct timeval request_time,
1238 struct file_id id,
1239 struct server_id pid,
1240 uint64_t mid)
1242 ZERO_STRUCTP(e);
1243 e->pid = pid;
1244 e->op_mid = mid;
1245 e->op_type = DEFERRED_OPEN_ENTRY;
1246 e->time.tv_sec = request_time.tv_sec;
1247 e->time.tv_usec = request_time.tv_usec;
1248 e->id = id;
1249 e->uid = (uint32)-1;
1250 e->flags = 0;
1253 static void add_share_mode_entry(struct share_mode_lock *lck,
1254 const struct share_mode_entry *entry)
1256 int i;
1258 for (i=0; i<lck->num_share_modes; i++) {
1259 struct share_mode_entry *e = &lck->share_modes[i];
1260 if (is_unused_share_mode_entry(e)) {
1261 *e = *entry;
1262 break;
1266 if (i == lck->num_share_modes) {
1267 /* No unused entry found */
1268 ADD_TO_ARRAY(lck, struct share_mode_entry, *entry,
1269 &lck->share_modes, &lck->num_share_modes);
1271 lck->modified = True;
1274 void set_share_mode(struct share_mode_lock *lck, files_struct *fsp,
1275 uid_t uid, uint64_t mid, uint16 op_type)
1277 struct share_mode_entry entry;
1278 fill_share_mode_entry(&entry, fsp, uid, mid, op_type);
1279 add_share_mode_entry(lck, &entry);
1282 void add_deferred_open(struct share_mode_lock *lck, uint64_t mid,
1283 struct timeval request_time,
1284 struct server_id pid, struct file_id id)
1286 struct share_mode_entry entry;
1287 fill_deferred_open_entry(&entry, request_time, id, pid, mid);
1288 add_share_mode_entry(lck, &entry);
1291 /*******************************************************************
1292 Check if two share mode entries are identical, ignoring oplock
1293 and mid info and desired_access. (Removed paranoia test - it's
1294 not automatically a logic error if they are identical. JRA.)
1295 ********************************************************************/
1297 static bool share_modes_identical(struct share_mode_entry *e1,
1298 struct share_mode_entry *e2)
1300 /* We used to check for e1->share_access == e2->share_access here
1301 as well as the other fields but 2 different DOS or FCB opens
1302 sharing the same share mode entry may validly differ in
1303 fsp->share_access field. */
1305 return (procid_equal(&e1->pid, &e2->pid) &&
1306 file_id_equal(&e1->id, &e2->id) &&
1307 e1->share_file_id == e2->share_file_id );
1310 static bool deferred_open_identical(struct share_mode_entry *e1,
1311 struct share_mode_entry *e2)
1313 return (procid_equal(&e1->pid, &e2->pid) &&
1314 (e1->op_mid == e2->op_mid) &&
1315 file_id_equal(&e1->id, &e2->id));
1318 static struct share_mode_entry *find_share_mode_entry(struct share_mode_lock *lck,
1319 struct share_mode_entry *entry)
1321 int i;
1323 for (i=0; i<lck->num_share_modes; i++) {
1324 struct share_mode_entry *e = &lck->share_modes[i];
1325 if (is_valid_share_mode_entry(entry) &&
1326 is_valid_share_mode_entry(e) &&
1327 share_modes_identical(e, entry)) {
1328 return e;
1330 if (is_deferred_open_entry(entry) &&
1331 is_deferred_open_entry(e) &&
1332 deferred_open_identical(e, entry)) {
1333 return e;
1336 return NULL;
1339 /*******************************************************************
1340 Del the share mode of a file for this process. Return the number of
1341 entries left.
1342 ********************************************************************/
1344 bool del_share_mode(struct share_mode_lock *lck, files_struct *fsp)
1346 struct share_mode_entry entry, *e;
1348 /* Don't care about the pid owner being correct here - just a search. */
1349 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1351 e = find_share_mode_entry(lck, &entry);
1352 if (e == NULL) {
1353 return False;
1356 e->op_type = UNUSED_SHARE_MODE_ENTRY;
1357 lck->modified = True;
1358 return True;
1361 void del_deferred_open_entry(struct share_mode_lock *lck, uint64_t mid,
1362 struct server_id pid)
1364 struct share_mode_entry entry, *e;
1366 fill_deferred_open_entry(&entry, timeval_zero(),
1367 lck->id, pid, mid);
1369 e = find_share_mode_entry(lck, &entry);
1370 if (e == NULL) {
1371 return;
1374 e->op_type = UNUSED_SHARE_MODE_ENTRY;
1375 lck->modified = True;
1378 /*******************************************************************
1379 Remove an oplock mid and mode entry from a share mode.
1380 ********************************************************************/
1382 bool remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
1384 struct share_mode_entry entry, *e;
1386 /* Don't care about the pid owner being correct here - just a search. */
1387 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1389 e = find_share_mode_entry(lck, &entry);
1390 if (e == NULL) {
1391 return False;
1394 if (EXCLUSIVE_OPLOCK_TYPE(e->op_type)) {
1396 * Going from exclusive or batch,
1397 * we always go through FAKE_LEVEL_II
1398 * first.
1400 if (!EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1401 smb_panic("remove_share_oplock: logic error");
1403 e->op_type = FAKE_LEVEL_II_OPLOCK;
1404 } else {
1405 e->op_type = NO_OPLOCK;
1407 lck->modified = True;
1408 return True;
1411 /*******************************************************************
1412 Downgrade a oplock type from exclusive to level II.
1413 ********************************************************************/
1415 bool downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
1417 struct share_mode_entry entry, *e;
1419 /* Don't care about the pid owner being correct here - just a search. */
1420 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1422 e = find_share_mode_entry(lck, &entry);
1423 if (e == NULL) {
1424 return False;
1427 e->op_type = LEVEL_II_OPLOCK;
1428 lck->modified = True;
1429 return True;
1432 /****************************************************************************
1433 Check if setting delete on close is allowed on this fsp.
1434 ****************************************************************************/
1436 NTSTATUS can_set_delete_on_close(files_struct *fsp, uint32 dosmode)
1439 * Only allow delete on close for writable files.
1442 if ((dosmode & FILE_ATTRIBUTE_READONLY) &&
1443 !lp_delete_readonly(SNUM(fsp->conn))) {
1444 DEBUG(10,("can_set_delete_on_close: file %s delete on close "
1445 "flag set but file attribute is readonly.\n",
1446 fsp_str_dbg(fsp)));
1447 return NT_STATUS_CANNOT_DELETE;
1451 * Only allow delete on close for writable shares.
1454 if (!CAN_WRITE(fsp->conn)) {
1455 DEBUG(10,("can_set_delete_on_close: file %s delete on "
1456 "close flag set but write access denied on share.\n",
1457 fsp_str_dbg(fsp)));
1458 return NT_STATUS_ACCESS_DENIED;
1462 * Only allow delete on close for files/directories opened with delete
1463 * intent.
1466 if (!(fsp->access_mask & DELETE_ACCESS)) {
1467 DEBUG(10,("can_set_delete_on_close: file %s delete on "
1468 "close flag set but delete access denied.\n",
1469 fsp_str_dbg(fsp)));
1470 return NT_STATUS_ACCESS_DENIED;
1473 /* Don't allow delete on close for non-empty directories. */
1474 if (fsp->is_directory) {
1475 SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name));
1477 /* Or the root of a share. */
1478 if (ISDOT(fsp->fsp_name->base_name)) {
1479 DEBUG(10,("can_set_delete_on_close: can't set delete on "
1480 "close for the root of a share.\n"));
1481 return NT_STATUS_ACCESS_DENIED;
1484 return can_delete_directory(fsp->conn,
1485 fsp->fsp_name->base_name);
1488 return NT_STATUS_OK;
1491 /*************************************************************************
1492 Return a talloced copy of a struct security_unix_token. NULL on fail.
1493 (Should this be in locking.c.... ?).
1494 *************************************************************************/
1496 static struct security_unix_token *copy_unix_token(TALLOC_CTX *ctx, const struct security_unix_token *tok)
1498 struct security_unix_token *cpy;
1500 cpy = talloc(ctx, struct security_unix_token);
1501 if (!cpy) {
1502 return NULL;
1505 cpy->uid = tok->uid;
1506 cpy->gid = tok->gid;
1507 cpy->ngroups = tok->ngroups;
1508 if (tok->ngroups) {
1509 /* Make this a talloc child of cpy. */
1510 cpy->groups = (gid_t *)talloc_memdup(
1511 cpy, tok->groups, tok->ngroups * sizeof(gid_t));
1512 if (!cpy->groups) {
1513 TALLOC_FREE(cpy);
1514 return NULL;
1517 return cpy;
1520 /****************************************************************************
1521 Adds a delete on close token.
1522 ****************************************************************************/
1524 static bool add_delete_on_close_token(struct share_mode_lock *lck,
1525 uint32_t name_hash,
1526 const struct security_unix_token *tok)
1528 struct delete_token_list *dtl;
1530 dtl = talloc_zero(lck, struct delete_token_list);
1531 if (dtl == NULL) {
1532 return false;
1535 dtl->name_hash = name_hash;
1536 dtl->delete_token = copy_unix_token(lck, tok);
1537 if (dtl->delete_token == NULL) {
1538 TALLOC_FREE(dtl);
1539 return false;
1541 DLIST_ADD(lck->delete_tokens, dtl);
1542 lck->modified = true;
1543 return true;
1546 /****************************************************************************
1547 Sets the delete on close flag over all share modes on this file.
1548 Modify the share mode entry for all files open
1549 on this device and inode to tell other smbds we have
1550 changed the delete on close flag. This will be noticed
1551 in the close code, the last closer will delete the file
1552 if flag is set.
1553 This makes a copy of any struct security_unix_token into the
1554 lck entry. This function is used when the lock is already granted.
1555 ****************************************************************************/
1557 void set_delete_on_close_lck(files_struct *fsp,
1558 struct share_mode_lock *lck,
1559 bool delete_on_close,
1560 const struct security_unix_token *tok)
1562 struct delete_token_list *dtl;
1563 bool ret;
1565 if (delete_on_close) {
1566 SMB_ASSERT(tok != NULL);
1567 } else {
1568 SMB_ASSERT(tok == NULL);
1571 for (dtl = lck->delete_tokens; dtl; dtl = dtl->next) {
1572 if (dtl->name_hash == fsp->name_hash) {
1573 lck->modified = true;
1574 if (delete_on_close == false) {
1575 /* Delete this entry. */
1576 DLIST_REMOVE(lck->delete_tokens, dtl);
1577 TALLOC_FREE(dtl);
1578 return;
1580 /* Replace this token with the
1581 given tok. */
1582 TALLOC_FREE(dtl->delete_token);
1583 dtl->delete_token = copy_unix_token(dtl, tok);
1584 SMB_ASSERT(dtl->delete_token != NULL);
1588 if (!delete_on_close) {
1589 /* Nothing to delete - not found. */
1590 return;
1593 ret = add_delete_on_close_token(lck, fsp->name_hash, tok);
1594 SMB_ASSERT(ret);
1597 bool set_delete_on_close(files_struct *fsp, bool delete_on_close, const struct security_unix_token *tok)
1599 struct share_mode_lock *lck;
1601 DEBUG(10,("set_delete_on_close: %s delete on close flag for "
1602 "fnum = %d, file %s\n",
1603 delete_on_close ? "Adding" : "Removing", fsp->fnum,
1604 fsp_str_dbg(fsp)));
1606 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
1607 NULL);
1608 if (lck == NULL) {
1609 return False;
1612 set_delete_on_close_lck(fsp, lck, delete_on_close,
1613 delete_on_close ? tok : NULL);
1615 if (fsp->is_directory) {
1616 SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name));
1617 send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
1618 fsp->fsp_name->base_name);
1621 TALLOC_FREE(lck);
1623 fsp->delete_on_close = delete_on_close;
1625 return True;
1628 const struct security_unix_token *get_delete_on_close_token(struct share_mode_lock *lck, uint32_t name_hash)
1630 struct delete_token_list *dtl;
1632 DEBUG(10,("get_delete_on_close_token: name_hash = 0x%x\n",
1633 (unsigned int)name_hash ));
1635 for (dtl = lck->delete_tokens; dtl; dtl = dtl->next) {
1636 DEBUG(10,("get_delete_on_close_token: dtl->name_hash = 0x%x\n",
1637 (unsigned int)dtl->name_hash ));
1638 if (dtl->name_hash == name_hash) {
1639 return dtl->delete_token;
1642 return NULL;
1645 bool is_delete_on_close_set(struct share_mode_lock *lck, uint32_t name_hash)
1647 return (get_delete_on_close_token(lck, name_hash) != NULL);
1650 bool set_sticky_write_time(struct file_id fileid, struct timespec write_time)
1652 struct share_mode_lock *lck;
1654 DEBUG(5,("set_sticky_write_time: %s id=%s\n",
1655 timestring(talloc_tos(),
1656 convert_timespec_to_time_t(write_time)),
1657 file_id_string_tos(&fileid)));
1659 lck = get_share_mode_lock(NULL, fileid, NULL, NULL, NULL);
1660 if (lck == NULL) {
1661 return False;
1664 if (timespec_compare(&lck->changed_write_time, &write_time) != 0) {
1665 lck->modified = True;
1666 lck->changed_write_time = write_time;
1669 TALLOC_FREE(lck);
1670 return True;
1673 bool set_write_time(struct file_id fileid, struct timespec write_time)
1675 struct share_mode_lock *lck;
1677 DEBUG(5,("set_write_time: %s id=%s\n",
1678 timestring(talloc_tos(),
1679 convert_timespec_to_time_t(write_time)),
1680 file_id_string_tos(&fileid)));
1682 lck = get_share_mode_lock(NULL, fileid, NULL, NULL, NULL);
1683 if (lck == NULL) {
1684 return False;
1687 if (timespec_compare(&lck->old_write_time, &write_time) != 0) {
1688 lck->modified = True;
1689 lck->old_write_time = write_time;
1692 TALLOC_FREE(lck);
1693 return True;
1697 struct forall_state {
1698 void (*fn)(const struct share_mode_entry *entry,
1699 const char *sharepath,
1700 const char *fname,
1701 void *private_data);
1702 void *private_data;
1705 static int traverse_fn(struct db_record *rec, void *_state)
1707 struct forall_state *state = (struct forall_state *)_state;
1708 struct locking_data *data;
1709 struct share_mode_entry *shares;
1710 const char *sharepath;
1711 const char *fname;
1712 const char *del_tokens;
1713 uint32_t total_del_token_size = 0;
1714 int i;
1715 TDB_DATA key;
1716 TDB_DATA value;
1718 key = dbwrap_record_get_key(rec);
1719 value = dbwrap_record_get_value(rec);
1721 /* Ensure this is a locking_key record. */
1722 if (key.dsize != sizeof(struct file_id))
1723 return 0;
1725 data = (struct locking_data *)value.dptr;
1726 shares = (struct share_mode_entry *)(value.dptr + sizeof(*data));
1727 del_tokens = (const char *)value.dptr + sizeof(*data) +
1728 data->u.s.num_share_mode_entries*sizeof(*shares);
1730 for (i = 0; i < data->u.s.num_delete_token_entries; i++) {
1731 uint32_t del_token_size;
1732 memcpy(&del_token_size, del_tokens, sizeof(uint32_t));
1733 total_del_token_size += del_token_size;
1734 del_tokens += del_token_size;
1737 sharepath = (const char *)value.dptr + sizeof(*data) +
1738 data->u.s.num_share_mode_entries*sizeof(*shares) +
1739 total_del_token_size;
1740 fname = (const char *)value.dptr + sizeof(*data) +
1741 data->u.s.num_share_mode_entries*sizeof(*shares) +
1742 total_del_token_size +
1743 strlen(sharepath) + 1;
1745 for (i=0;i<data->u.s.num_share_mode_entries;i++) {
1746 state->fn(&shares[i], sharepath, fname,
1747 state->private_data);
1749 return 0;
1752 /*******************************************************************
1753 Call the specified function on each entry under management by the
1754 share mode system.
1755 ********************************************************************/
1757 int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *,
1758 const char *, void *),
1759 void *private_data)
1761 struct forall_state state;
1762 NTSTATUS status;
1763 int count;
1765 if (lock_db == NULL)
1766 return 0;
1768 state.fn = fn;
1769 state.private_data = private_data;
1771 status = dbwrap_traverse_read(lock_db, traverse_fn, (void *)&state,
1772 &count);
1774 if (!NT_STATUS_IS_OK(status)) {
1775 return -1;
1776 } else {
1777 return count;