s3:libads/kerberos_proto.h: add GPL/Copyright header (cherry picked from commit 6bf32...
[Samba.git] / source3 / locking / locking.c
blobba363501d8cb1bf64474d82fa2695d0604904ebb
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"
48 #undef DBGC_CLASS
49 #define DBGC_CLASS DBGC_LOCKING
51 #define NO_LOCKING_COUNT (-1)
53 /* the locking database handle */
54 static struct db_context *lock_db;
56 /****************************************************************************
57 Debugging aids :-).
58 ****************************************************************************/
60 const char *lock_type_name(enum brl_type lock_type)
62 switch (lock_type) {
63 case READ_LOCK:
64 return "READ";
65 case WRITE_LOCK:
66 return "WRITE";
67 case PENDING_READ_LOCK:
68 return "PENDING_READ";
69 case PENDING_WRITE_LOCK:
70 return "PENDING_WRITE";
71 default:
72 return "other";
76 const char *lock_flav_name(enum brl_flavour lock_flav)
78 return (lock_flav == WINDOWS_LOCK) ? "WINDOWS_LOCK" : "POSIX_LOCK";
81 /****************************************************************************
82 Utility function called to see if a file region is locked.
83 Called in the read/write codepath.
84 ****************************************************************************/
86 void init_strict_lock_struct(files_struct *fsp,
87 uint64_t smblctx,
88 br_off start,
89 br_off size,
90 enum brl_type lock_type,
91 struct lock_struct *plock)
93 SMB_ASSERT(lock_type == READ_LOCK || lock_type == WRITE_LOCK);
95 plock->context.smblctx = smblctx;
96 plock->context.tid = fsp->conn->cnum;
97 plock->context.pid = sconn_server_id(fsp->conn->sconn);
98 plock->start = start;
99 plock->size = size;
100 plock->fnum = fsp->fnum;
101 plock->lock_type = lock_type;
102 plock->lock_flav = lp_posix_cifsu_locktype(fsp);
105 bool strict_lock_default(files_struct *fsp, struct lock_struct *plock)
107 int strict_locking = lp_strict_locking(fsp->conn->params);
108 bool ret = False;
110 if (plock->size == 0) {
111 return True;
114 if (!lp_locking(fsp->conn->params) || !strict_locking) {
115 return True;
118 if (strict_locking == Auto) {
119 if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (plock->lock_type == READ_LOCK || plock->lock_type == WRITE_LOCK)) {
120 DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp_str_dbg(fsp)));
121 ret = True;
122 } else if ((fsp->oplock_type == LEVEL_II_OPLOCK) &&
123 (plock->lock_type == READ_LOCK)) {
124 DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp_str_dbg(fsp)));
125 ret = True;
126 } else {
127 struct byte_range_lock *br_lck;
129 br_lck = brl_get_locks_readonly(fsp);
130 if (!br_lck) {
131 return True;
133 ret = brl_locktest(br_lck,
134 plock->context.smblctx,
135 plock->context.pid,
136 plock->start,
137 plock->size,
138 plock->lock_type,
139 plock->lock_flav);
141 } else {
142 struct byte_range_lock *br_lck;
144 br_lck = brl_get_locks_readonly(fsp);
145 if (!br_lck) {
146 return True;
148 ret = brl_locktest(br_lck,
149 plock->context.smblctx,
150 plock->context.pid,
151 plock->start,
152 plock->size,
153 plock->lock_type,
154 plock->lock_flav);
157 DEBUG(10,("strict_lock_default: flavour = %s brl start=%.0f "
158 "len=%.0f %s for fnum %d file %s\n",
159 lock_flav_name(plock->lock_flav),
160 (double)plock->start, (double)plock->size,
161 ret ? "unlocked" : "locked",
162 plock->fnum, fsp_str_dbg(fsp)));
164 return ret;
167 void strict_unlock_default(files_struct *fsp, struct lock_struct *plock)
171 /****************************************************************************
172 Find out if a lock could be granted - return who is blocking us if we can't.
173 ****************************************************************************/
175 NTSTATUS query_lock(files_struct *fsp,
176 uint64_t *psmblctx,
177 uint64_t *pcount,
178 uint64_t *poffset,
179 enum brl_type *plock_type,
180 enum brl_flavour lock_flav)
182 struct byte_range_lock *br_lck = NULL;
184 if (!fsp->can_lock) {
185 return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
188 if (!lp_locking(fsp->conn->params)) {
189 return NT_STATUS_OK;
192 br_lck = brl_get_locks_readonly(fsp);
193 if (!br_lck) {
194 return NT_STATUS_NO_MEMORY;
197 return brl_lockquery(br_lck,
198 psmblctx,
199 sconn_server_id(fsp->conn->sconn),
200 poffset,
201 pcount,
202 plock_type,
203 lock_flav);
206 static void increment_current_lock_count(files_struct *fsp,
207 enum brl_flavour lock_flav)
209 if (lock_flav == WINDOWS_LOCK &&
210 fsp->current_lock_count != NO_LOCKING_COUNT) {
211 /* blocking ie. pending, locks also count here,
212 * as this is an efficiency counter to avoid checking
213 * the lock db. on close. JRA. */
215 fsp->current_lock_count++;
216 } else {
217 /* Notice that this has had a POSIX lock request.
218 * We can't count locks after this so forget them.
220 fsp->current_lock_count = NO_LOCKING_COUNT;
224 static void decrement_current_lock_count(files_struct *fsp,
225 enum brl_flavour lock_flav)
227 if (lock_flav == WINDOWS_LOCK &&
228 fsp->current_lock_count != NO_LOCKING_COUNT) {
229 SMB_ASSERT(fsp->current_lock_count > 0);
230 fsp->current_lock_count--;
234 /****************************************************************************
235 Utility function called by locking requests.
236 ****************************************************************************/
238 struct byte_range_lock *do_lock(struct messaging_context *msg_ctx,
239 files_struct *fsp,
240 uint64_t smblctx,
241 uint64_t count,
242 uint64_t offset,
243 enum brl_type lock_type,
244 enum brl_flavour lock_flav,
245 bool blocking_lock,
246 NTSTATUS *perr,
247 uint64_t *psmblctx,
248 struct blocking_lock_record *blr)
250 struct byte_range_lock *br_lck = NULL;
252 /* silently return ok on print files as we don't do locking there */
253 if (fsp->print_file) {
254 *perr = NT_STATUS_OK;
255 return NULL;
258 if (!fsp->can_lock) {
259 *perr = fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
260 return NULL;
263 if (!lp_locking(fsp->conn->params)) {
264 *perr = NT_STATUS_OK;
265 return NULL;
268 /* NOTE! 0 byte long ranges ARE allowed and should be stored */
270 DEBUG(10,("do_lock: lock flavour %s lock type %s start=%.0f len=%.0f "
271 "blocking_lock=%s requested for fnum %d file %s\n",
272 lock_flav_name(lock_flav), lock_type_name(lock_type),
273 (double)offset, (double)count, blocking_lock ? "true" :
274 "false", fsp->fnum, fsp_str_dbg(fsp)));
276 br_lck = brl_get_locks(talloc_tos(), fsp);
277 if (!br_lck) {
278 *perr = NT_STATUS_NO_MEMORY;
279 return NULL;
282 *perr = brl_lock(msg_ctx,
283 br_lck,
284 smblctx,
285 sconn_server_id(fsp->conn->sconn),
286 offset,
287 count,
288 lock_type,
289 lock_flav,
290 blocking_lock,
291 psmblctx,
292 blr);
294 DEBUG(10, ("do_lock: returning status=%s\n", nt_errstr(*perr)));
296 increment_current_lock_count(fsp, lock_flav);
297 return br_lck;
300 /****************************************************************************
301 Utility function called by unlocking requests.
302 ****************************************************************************/
304 NTSTATUS do_unlock(struct messaging_context *msg_ctx,
305 files_struct *fsp,
306 uint64_t smblctx,
307 uint64_t count,
308 uint64_t offset,
309 enum brl_flavour lock_flav)
311 bool ok = False;
312 struct byte_range_lock *br_lck = NULL;
314 if (!fsp->can_lock) {
315 return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
318 if (!lp_locking(fsp->conn->params)) {
319 return NT_STATUS_OK;
322 DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for fnum %d file %s\n",
323 (double)offset, (double)count, fsp->fnum,
324 fsp_str_dbg(fsp)));
326 br_lck = brl_get_locks(talloc_tos(), fsp);
327 if (!br_lck) {
328 return NT_STATUS_NO_MEMORY;
331 ok = brl_unlock(msg_ctx,
332 br_lck,
333 smblctx,
334 sconn_server_id(fsp->conn->sconn),
335 offset,
336 count,
337 lock_flav);
339 TALLOC_FREE(br_lck);
341 if (!ok) {
342 DEBUG(10,("do_unlock: returning ERRlock.\n" ));
343 return NT_STATUS_RANGE_NOT_LOCKED;
346 decrement_current_lock_count(fsp, lock_flav);
347 return NT_STATUS_OK;
350 /****************************************************************************
351 Cancel any pending blocked locks.
352 ****************************************************************************/
354 NTSTATUS do_lock_cancel(files_struct *fsp,
355 uint64 smblctx,
356 uint64_t count,
357 uint64_t offset,
358 enum brl_flavour lock_flav,
359 struct blocking_lock_record *blr)
361 bool ok = False;
362 struct byte_range_lock *br_lck = NULL;
364 if (!fsp->can_lock) {
365 return fsp->is_directory ?
366 NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
369 if (!lp_locking(fsp->conn->params)) {
370 return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
373 DEBUG(10,("do_lock_cancel: cancel start=%.0f len=%.0f requested for fnum %d file %s\n",
374 (double)offset, (double)count, fsp->fnum,
375 fsp_str_dbg(fsp)));
377 br_lck = brl_get_locks(talloc_tos(), fsp);
378 if (!br_lck) {
379 return NT_STATUS_NO_MEMORY;
382 ok = brl_lock_cancel(br_lck,
383 smblctx,
384 sconn_server_id(fsp->conn->sconn),
385 offset,
386 count,
387 lock_flav,
388 blr);
390 TALLOC_FREE(br_lck);
392 if (!ok) {
393 DEBUG(10,("do_lock_cancel: returning ERRcancelviolation.\n" ));
394 return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
397 decrement_current_lock_count(fsp, lock_flav);
398 return NT_STATUS_OK;
401 /****************************************************************************
402 Remove any locks on this fd. Called from file_close().
403 ****************************************************************************/
405 void locking_close_file(struct messaging_context *msg_ctx,
406 files_struct *fsp,
407 enum file_close_type close_type)
409 struct byte_range_lock *br_lck;
411 if (!lp_locking(fsp->conn->params)) {
412 return;
415 /* If we have not outstanding locks or pending
416 * locks then we don't need to look in the lock db.
419 if (fsp->current_lock_count == 0) {
420 return;
423 br_lck = brl_get_locks(talloc_tos(),fsp);
425 if (br_lck) {
426 cancel_pending_lock_requests_by_fid(fsp, br_lck, close_type);
427 brl_close_fnum(msg_ctx, br_lck);
428 TALLOC_FREE(br_lck);
432 /****************************************************************************
433 Initialise the locking functions.
434 ****************************************************************************/
436 static bool locking_init_internal(bool read_only)
438 brl_init(read_only);
440 if (lock_db)
441 return True;
443 lock_db = db_open(NULL, lock_path("locking.tdb"),
444 lp_open_files_db_hash_size(),
445 TDB_DEFAULT|TDB_VOLATILE|TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH,
446 read_only?O_RDONLY:O_RDWR|O_CREAT, 0644);
448 if (!lock_db) {
449 DEBUG(0,("ERROR: Failed to initialise locking database\n"));
450 return False;
453 if (!posix_locking_init(read_only))
454 return False;
456 return True;
459 bool locking_init(void)
461 return locking_init_internal(false);
464 bool locking_init_readonly(void)
466 return locking_init_internal(true);
469 /*******************************************************************
470 Deinitialize the share_mode management.
471 ******************************************************************/
473 bool locking_end(void)
475 brl_shutdown();
476 TALLOC_FREE(lock_db);
477 return true;
480 /*******************************************************************
481 Form a static locking key for a dev/inode pair.
482 ******************************************************************/
484 static TDB_DATA locking_key(const struct file_id *id, struct file_id *tmp)
486 *tmp = *id;
487 return make_tdb_data((const uint8_t *)tmp, sizeof(*tmp));
490 /*******************************************************************
491 Print out a share mode.
492 ********************************************************************/
494 char *share_mode_str(TALLOC_CTX *ctx, int num, const struct share_mode_entry *e)
496 return talloc_asprintf(ctx, "share_mode_entry[%d]: %s "
497 "pid = %s, share_access = 0x%x, private_options = 0x%x, "
498 "access_mask = 0x%x, mid = 0x%llx, type= 0x%x, gen_id = %lu, "
499 "uid = %u, flags = %u, file_id %s, name_hash = 0x%x",
500 num,
501 e->op_type == UNUSED_SHARE_MODE_ENTRY ? "UNUSED" : "",
502 procid_str_static(&e->pid),
503 e->share_access, e->private_options,
504 e->access_mask, (unsigned long long)e->op_mid,
505 e->op_type, e->share_file_id,
506 (unsigned int)e->uid, (unsigned int)e->flags,
507 file_id_string_tos(&e->id),
508 (unsigned int)e->name_hash);
511 /*******************************************************************
512 Print out a share mode table.
513 ********************************************************************/
515 static void print_share_mode_table(struct locking_data *data)
517 int num_share_modes = data->u.s.num_share_mode_entries;
518 struct share_mode_entry *shares =
519 (struct share_mode_entry *)(data + 1);
520 int i;
522 for (i = 0; i < num_share_modes; i++) {
523 struct share_mode_entry entry;
524 char *str;
527 * We need to memcpy the entry here due to alignment
528 * restrictions that are not met when directly accessing
529 * shares[i]
532 memcpy(&entry, &shares[i], sizeof(struct share_mode_entry));
533 str = share_mode_str(talloc_tos(), i, &entry);
535 DEBUG(10,("print_share_mode_table: %s\n", str ? str : ""));
536 TALLOC_FREE(str);
540 static int parse_delete_tokens_list(struct share_mode_lock *lck,
541 struct locking_data *pdata,
542 const TDB_DATA dbuf)
544 uint8_t *p = dbuf.dptr + sizeof(struct locking_data) +
545 (lck->num_share_modes *
546 sizeof(struct share_mode_entry));
547 uint8_t *end_ptr = dbuf.dptr + (dbuf.dsize - 2);
548 int delete_tokens_size = 0;
549 int i;
551 lck->delete_tokens = NULL;
553 for (i = 0; i < pdata->u.s.num_delete_token_entries; i++) {
554 uint32_t token_len;
555 struct delete_token_list *pdtl;
557 if (end_ptr - p < (sizeof(uint32_t) + sizeof(uint32_t) +
558 sizeof(uid_t) + sizeof(gid_t))) {
559 DEBUG(0,("parse_delete_tokens_list: "
560 "corrupt token list (%u)",
561 (unsigned int)(end_ptr - p)));
562 smb_panic("corrupt token list");
563 return -1;
566 memcpy(&token_len, p, sizeof(token_len));
567 delete_tokens_size += token_len;
569 if (p + token_len > end_ptr || token_len < sizeof(token_len) +
570 sizeof(pdtl->name_hash) +
571 sizeof(uid_t) +
572 sizeof(gid_t)) {
573 DEBUG(0,("parse_delete_tokens_list: "
574 "invalid token length (%u)\n",
575 (unsigned int)token_len ));
576 smb_panic("invalid token length");
577 return -1;
580 p += sizeof(token_len);
582 pdtl = TALLOC_ZERO_P(lck, struct delete_token_list);
583 if (pdtl == NULL) {
584 DEBUG(0,("parse_delete_tokens_list: talloc failed"));
585 return -1;
587 /* Copy out the name_hash. */
588 memcpy(&pdtl->name_hash, p, sizeof(pdtl->name_hash));
589 p += sizeof(pdtl->name_hash);
591 pdtl->delete_token = TALLOC_ZERO_P(pdtl, struct security_unix_token);
592 if (pdtl->delete_token == NULL) {
593 DEBUG(0,("parse_delete_tokens_list: talloc failed"));
594 return -1;
597 /* Copy out the uid and gid. */
598 memcpy(&pdtl->delete_token->uid, p, sizeof(uid_t));
599 p += sizeof(uid_t);
600 memcpy(&pdtl->delete_token->gid, p, sizeof(gid_t));
601 p += sizeof(gid_t);
603 token_len -= (sizeof(token_len) + sizeof(pdtl->name_hash) +
604 sizeof(uid_t) + sizeof(gid_t));
606 /* Any supplementary groups ? */
607 if (token_len) {
608 int j;
610 if (token_len % sizeof(gid_t) != 0) {
611 DEBUG(0,("parse_delete_tokens_list: "
612 "corrupt group list (%u)",
613 (unsigned int)(token_len % sizeof(gid_t)) ));
614 smb_panic("corrupt group list");
615 return -1;
618 pdtl->delete_token->ngroups = token_len / sizeof(gid_t);
619 pdtl->delete_token->groups = TALLOC_ARRAY(pdtl->delete_token, gid_t,
620 pdtl->delete_token->ngroups);
621 if (pdtl->delete_token->groups == NULL) {
622 DEBUG(0,("parse_delete_tokens_list: talloc failed"));
623 return -1;
626 for (j = 0; j < pdtl->delete_token->ngroups; j++) {
627 memcpy(&pdtl->delete_token->groups[j], p, sizeof(gid_t));
628 p += sizeof(gid_t);
631 /* Add to the list. */
632 DLIST_ADD(lck->delete_tokens, pdtl);
635 return delete_tokens_size;
638 /*******************************************************************
639 Get all share mode entries for a dev/inode pair.
640 ********************************************************************/
642 static bool parse_share_modes(const TDB_DATA dbuf, struct share_mode_lock *lck)
644 struct locking_data data;
645 int delete_tokens_size;
646 int i;
648 if (dbuf.dsize < sizeof(struct locking_data)) {
649 smb_panic("parse_share_modes: buffer too short");
652 memcpy(&data, dbuf.dptr, sizeof(data));
654 lck->old_write_time = data.u.s.old_write_time;
655 lck->changed_write_time = data.u.s.changed_write_time;
656 lck->num_share_modes = data.u.s.num_share_mode_entries;
658 DEBUG(10, ("parse_share_modes: owrt: %s, "
659 "cwrt: %s, ntok: %u, num_share_modes: %d\n",
660 timestring(talloc_tos(),
661 convert_timespec_to_time_t(lck->old_write_time)),
662 timestring(talloc_tos(),
663 convert_timespec_to_time_t(
664 lck->changed_write_time)),
665 (unsigned int)data.u.s.num_delete_token_entries,
666 lck->num_share_modes));
668 if ((lck->num_share_modes < 0) || (lck->num_share_modes > 1000000)) {
669 DEBUG(0, ("invalid number of share modes: %d\n",
670 lck->num_share_modes));
671 smb_panic("parse_share_modes: invalid number of share modes");
674 lck->share_modes = NULL;
676 if (lck->num_share_modes != 0) {
678 if (dbuf.dsize < (sizeof(struct locking_data) +
679 (lck->num_share_modes *
680 sizeof(struct share_mode_entry)))) {
681 smb_panic("parse_share_modes: buffer too short");
684 lck->share_modes = (struct share_mode_entry *)
685 TALLOC_MEMDUP(lck,
686 dbuf.dptr+sizeof(struct locking_data),
687 lck->num_share_modes *
688 sizeof(struct share_mode_entry));
690 if (lck->share_modes == NULL) {
691 smb_panic("parse_share_modes: talloc failed");
695 /* Get any delete tokens. */
696 delete_tokens_size = parse_delete_tokens_list(lck, &data, dbuf);
697 if (delete_tokens_size < 0) {
698 smb_panic("parse_share_modes: parse_delete_tokens_list failed");
701 /* Save off the associated service path and filename. */
702 lck->servicepath = (const char *)dbuf.dptr + sizeof(struct locking_data) +
703 (lck->num_share_modes * sizeof(struct share_mode_entry)) +
704 delete_tokens_size;
706 lck->base_name = (const char *)dbuf.dptr + sizeof(struct locking_data) +
707 (lck->num_share_modes * sizeof(struct share_mode_entry)) +
708 delete_tokens_size +
709 strlen(lck->servicepath) + 1;
711 lck->stream_name = (const char *)dbuf.dptr + sizeof(struct locking_data) +
712 (lck->num_share_modes * sizeof(struct share_mode_entry)) +
713 delete_tokens_size +
714 strlen(lck->servicepath) + 1 +
715 strlen(lck->base_name) + 1;
718 * Ensure that each entry has a real process attached.
721 for (i = 0; i < lck->num_share_modes; i++) {
722 struct share_mode_entry *entry_p = &lck->share_modes[i];
723 char *str = NULL;
724 if (DEBUGLEVEL >= 10) {
725 str = share_mode_str(NULL, i, entry_p);
727 DEBUG(10,("parse_share_modes: %s\n",
728 str ? str : ""));
729 if (!serverid_exists(&entry_p->pid)) {
730 DEBUG(10,("parse_share_modes: deleted %s\n",
731 str ? str : ""));
732 entry_p->op_type = UNUSED_SHARE_MODE_ENTRY;
733 lck->modified = True;
735 TALLOC_FREE(str);
738 return True;
741 static TDB_DATA unparse_share_modes(const struct share_mode_lock *lck)
743 TDB_DATA result;
744 int num_valid = 0;
745 int i;
746 struct locking_data *data;
747 ssize_t offset;
748 ssize_t sp_len, bn_len, sn_len;
749 uint32_t delete_tokens_size = 0;
750 struct delete_token_list *pdtl = NULL;
751 uint32_t num_delete_token_entries = 0;
753 result.dptr = NULL;
754 result.dsize = 0;
756 for (i=0; i<lck->num_share_modes; i++) {
757 if (!is_unused_share_mode_entry(&lck->share_modes[i])) {
758 num_valid += 1;
762 if (num_valid == 0) {
763 return result;
766 sp_len = strlen(lck->servicepath);
767 bn_len = strlen(lck->base_name);
768 sn_len = lck->stream_name != NULL ? strlen(lck->stream_name) : 0;
770 for (pdtl = lck->delete_tokens; pdtl; pdtl = pdtl->next) {
771 num_delete_token_entries++;
772 delete_tokens_size += (sizeof(uint32_t) +
773 sizeof(uint32_t) +
774 sizeof(uid_t) +
775 sizeof(gid_t) +
776 pdtl->delete_token->ngroups*sizeof(gid_t));
779 result.dsize = sizeof(*data) +
780 lck->num_share_modes * sizeof(struct share_mode_entry) +
781 delete_tokens_size +
782 sp_len + 1 +
783 bn_len + 1 +
784 sn_len + 1;
785 result.dptr = TALLOC_ARRAY(lck, uint8, result.dsize);
787 if (result.dptr == NULL) {
788 smb_panic("talloc failed");
791 data = (struct locking_data *)result.dptr;
792 ZERO_STRUCTP(data);
793 data->u.s.num_share_mode_entries = lck->num_share_modes;
794 data->u.s.old_write_time = lck->old_write_time;
795 data->u.s.changed_write_time = lck->changed_write_time;
796 data->u.s.num_delete_token_entries = num_delete_token_entries;
798 DEBUG(10,("unparse_share_modes: owrt: %s cwrt: %s, ntok: %u, "
799 "num: %d\n",
800 timestring(talloc_tos(),
801 convert_timespec_to_time_t(lck->old_write_time)),
802 timestring(talloc_tos(),
803 convert_timespec_to_time_t(
804 lck->changed_write_time)),
805 (unsigned int)data->u.s.num_delete_token_entries,
806 data->u.s.num_share_mode_entries));
808 memcpy(result.dptr + sizeof(*data), lck->share_modes,
809 sizeof(struct share_mode_entry)*lck->num_share_modes);
810 offset = sizeof(*data) +
811 sizeof(struct share_mode_entry)*lck->num_share_modes;
813 /* Store any delete on close tokens. */
814 for (pdtl = lck->delete_tokens; pdtl; pdtl = pdtl->next) {
815 struct security_unix_token *pdt = pdtl->delete_token;
816 uint32_t token_size = sizeof(uint32_t) +
817 sizeof(uint32_t) +
818 sizeof(uid_t) +
819 sizeof(gid_t) +
820 (pdt->ngroups * sizeof(gid_t));
821 uint8_t *p = result.dptr + offset;
823 memcpy(p, &token_size, sizeof(uint32_t));
824 p += sizeof(uint32_t);
826 memcpy(p, &pdtl->name_hash, sizeof(uint32_t));
827 p += sizeof(uint32_t);
829 memcpy(p, &pdt->uid, sizeof(uid_t));
830 p += sizeof(uid_t);
832 memcpy(p, &pdt->gid, sizeof(gid_t));
833 p += sizeof(gid_t);
835 for (i = 0; i < pdt->ngroups; i++) {
836 memcpy(p, &pdt->groups[i], sizeof(gid_t));
837 p += sizeof(gid_t);
839 offset += token_size;
842 safe_strcpy((char *)result.dptr + offset, lck->servicepath,
843 result.dsize - offset - 1);
844 offset += sp_len + 1;
845 safe_strcpy((char *)result.dptr + offset, lck->base_name,
846 result.dsize - offset - 1);
847 offset += bn_len + 1;
848 safe_strcpy((char *)result.dptr + offset, lck->stream_name,
849 result.dsize - offset - 1);
851 if (DEBUGLEVEL >= 10) {
852 print_share_mode_table(data);
855 return result;
858 static int share_mode_lock_destructor(struct share_mode_lock *lck)
860 NTSTATUS status;
861 TDB_DATA data;
863 if (!lck->modified) {
864 return 0;
867 data = unparse_share_modes(lck);
869 if (data.dptr == NULL) {
870 if (!lck->fresh) {
871 /* There has been an entry before, delete it */
873 status = lck->record->delete_rec(lck->record);
874 if (!NT_STATUS_IS_OK(status)) {
875 char *errmsg;
877 DEBUG(0, ("delete_rec returned %s\n",
878 nt_errstr(status)));
880 if (asprintf(&errmsg, "could not delete share "
881 "entry: %s\n",
882 nt_errstr(status)) == -1) {
883 smb_panic("could not delete share"
884 "entry");
886 smb_panic(errmsg);
889 goto done;
892 status = lck->record->store(lck->record, data, TDB_REPLACE);
893 if (!NT_STATUS_IS_OK(status)) {
894 char *errmsg;
896 DEBUG(0, ("store returned %s\n", nt_errstr(status)));
898 if (asprintf(&errmsg, "could not store share mode entry: %s",
899 nt_errstr(status)) == -1) {
900 smb_panic("could not store share mode entry");
902 smb_panic(errmsg);
905 done:
907 return 0;
910 static bool fill_share_mode_lock(struct share_mode_lock *lck,
911 struct file_id id,
912 const char *servicepath,
913 const struct smb_filename *smb_fname,
914 TDB_DATA share_mode_data,
915 const struct timespec *old_write_time)
917 /* Ensure we set every field here as the destructor must be
918 valid even if parse_share_modes fails. */
920 lck->servicepath = NULL;
921 lck->base_name = NULL;
922 lck->stream_name = NULL;
923 lck->id = id;
924 lck->num_share_modes = 0;
925 lck->share_modes = NULL;
926 lck->delete_tokens = NULL;
927 ZERO_STRUCT(lck->old_write_time);
928 ZERO_STRUCT(lck->changed_write_time);
929 lck->fresh = False;
930 lck->modified = False;
932 lck->fresh = (share_mode_data.dptr == NULL);
934 if (lck->fresh) {
935 bool has_stream;
936 if (smb_fname == NULL || servicepath == NULL
937 || old_write_time == NULL) {
938 return False;
941 has_stream = smb_fname->stream_name != NULL;
943 lck->base_name = talloc_strdup(lck, smb_fname->base_name);
944 lck->stream_name = talloc_strdup(lck, smb_fname->stream_name);
945 lck->servicepath = talloc_strdup(lck, servicepath);
946 if (lck->base_name == NULL ||
947 (has_stream && lck->stream_name == NULL) ||
948 lck->servicepath == NULL) {
949 DEBUG(0, ("talloc failed\n"));
950 return False;
952 lck->old_write_time = *old_write_time;
953 } else {
954 if (!parse_share_modes(share_mode_data, lck)) {
955 DEBUG(0, ("Could not parse share modes\n"));
956 return False;
960 return True;
963 struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
964 const struct file_id id,
965 const char *servicepath,
966 const struct smb_filename *smb_fname,
967 const struct timespec *old_write_time)
969 struct share_mode_lock *lck;
970 struct file_id tmp;
971 TDB_DATA key = locking_key(&id, &tmp);
973 if (!(lck = TALLOC_P(mem_ctx, struct share_mode_lock))) {
974 DEBUG(0, ("talloc failed\n"));
975 return NULL;
978 if (!(lck->record = lock_db->fetch_locked(lock_db, lck, key))) {
979 DEBUG(3, ("Could not lock share entry\n"));
980 TALLOC_FREE(lck);
981 return NULL;
984 if (!fill_share_mode_lock(lck, id, servicepath, smb_fname,
985 lck->record->value, old_write_time)) {
986 DEBUG(3, ("fill_share_mode_lock failed\n"));
987 TALLOC_FREE(lck);
988 return NULL;
991 talloc_set_destructor(lck, share_mode_lock_destructor);
993 return lck;
996 struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx,
997 const struct file_id id)
999 struct share_mode_lock *lck;
1000 struct file_id tmp;
1001 TDB_DATA key = locking_key(&id, &tmp);
1002 TDB_DATA data;
1004 if (!(lck = TALLOC_P(mem_ctx, struct share_mode_lock))) {
1005 DEBUG(0, ("talloc failed\n"));
1006 return NULL;
1009 if (lock_db->fetch(lock_db, lck, key, &data) == -1) {
1010 DEBUG(3, ("Could not fetch share entry\n"));
1011 TALLOC_FREE(lck);
1012 return NULL;
1015 if (!fill_share_mode_lock(lck, id, NULL, NULL, data, NULL)) {
1016 DEBUG(10, ("fetch_share_mode_unlocked: no share_mode record "
1017 "around (file not open)\n"));
1018 TALLOC_FREE(lck);
1019 return NULL;
1022 return lck;
1025 /*******************************************************************
1026 Sets the service name and filename for rename.
1027 At this point we emit "file renamed" messages to all
1028 process id's that have this file open.
1029 Based on an initial code idea from SATOH Fumiyasu <fumiya@samba.gr.jp>
1030 ********************************************************************/
1032 bool rename_share_filename(struct messaging_context *msg_ctx,
1033 struct share_mode_lock *lck,
1034 const char *servicepath,
1035 uint32_t orig_name_hash,
1036 uint32_t new_name_hash,
1037 const struct smb_filename *smb_fname_dst)
1039 size_t sp_len;
1040 size_t bn_len;
1041 size_t sn_len;
1042 size_t msg_len;
1043 char *frm = NULL;
1044 int i;
1045 bool strip_two_chars = false;
1046 bool has_stream = smb_fname_dst->stream_name != NULL;
1048 DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n",
1049 servicepath, smb_fname_dst->base_name));
1052 * rename_internal_fsp() and rename_internals() add './' to
1053 * head of newname if newname does not contain a '/'.
1055 if (smb_fname_dst->base_name[0] &&
1056 smb_fname_dst->base_name[1] &&
1057 smb_fname_dst->base_name[0] == '.' &&
1058 smb_fname_dst->base_name[1] == '/') {
1059 strip_two_chars = true;
1062 lck->servicepath = talloc_strdup(lck, servicepath);
1063 lck->base_name = talloc_strdup(lck, smb_fname_dst->base_name +
1064 (strip_two_chars ? 2 : 0));
1065 lck->stream_name = talloc_strdup(lck, smb_fname_dst->stream_name);
1066 if (lck->base_name == NULL ||
1067 (has_stream && lck->stream_name == NULL) ||
1068 lck->servicepath == NULL) {
1069 DEBUG(0, ("rename_share_filename: talloc failed\n"));
1070 return False;
1072 lck->modified = True;
1074 sp_len = strlen(lck->servicepath);
1075 bn_len = strlen(lck->base_name);
1076 sn_len = has_stream ? strlen(lck->stream_name) : 0;
1078 msg_len = MSG_FILE_RENAMED_MIN_SIZE + sp_len + 1 + bn_len + 1 +
1079 sn_len + 1;
1081 /* Set up the name changed message. */
1082 frm = TALLOC_ARRAY(lck, char, msg_len);
1083 if (!frm) {
1084 return False;
1087 push_file_id_24(frm, &lck->id);
1089 DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len ));
1091 safe_strcpy(&frm[24], lck->servicepath, sp_len);
1092 safe_strcpy(&frm[24 + sp_len + 1], lck->base_name, bn_len);
1093 safe_strcpy(&frm[24 + sp_len + 1 + bn_len + 1], lck->stream_name,
1094 sn_len);
1096 /* Send the messages. */
1097 for (i=0; i<lck->num_share_modes; i++) {
1098 struct share_mode_entry *se = &lck->share_modes[i];
1099 if (!is_valid_share_mode_entry(se)) {
1100 continue;
1103 /* If this is a hardlink to the inode
1104 with a different name, skip this. */
1105 if (se->name_hash != orig_name_hash) {
1106 continue;
1109 se->name_hash = new_name_hash;
1111 /* But not to ourselves... */
1112 if (procid_is_me(&se->pid)) {
1113 continue;
1116 DEBUG(10,("rename_share_filename: sending rename message to "
1117 "pid %s file_id %s sharepath %s base_name %s "
1118 "stream_name %s\n",
1119 procid_str_static(&se->pid),
1120 file_id_string_tos(&lck->id),
1121 lck->servicepath, lck->base_name,
1122 has_stream ? lck->stream_name : ""));
1124 messaging_send_buf(msg_ctx, se->pid, MSG_SMB_FILE_RENAME,
1125 (uint8 *)frm, msg_len);
1128 return True;
1131 void get_file_infos(struct file_id id,
1132 uint32_t name_hash,
1133 bool *delete_on_close,
1134 struct timespec *write_time)
1136 struct share_mode_lock *lck;
1138 if (delete_on_close) {
1139 *delete_on_close = false;
1142 if (write_time) {
1143 ZERO_STRUCTP(write_time);
1146 if (!(lck = fetch_share_mode_unlocked(talloc_tos(), id))) {
1147 return;
1150 if (delete_on_close) {
1151 *delete_on_close = is_delete_on_close_set(lck, name_hash);
1154 if (write_time) {
1155 struct timespec wt;
1157 wt = lck->changed_write_time;
1158 if (null_timespec(wt)) {
1159 wt = lck->old_write_time;
1162 *write_time = wt;
1165 TALLOC_FREE(lck);
1168 bool is_valid_share_mode_entry(const struct share_mode_entry *e)
1170 int num_props = 0;
1172 if (e->op_type == UNUSED_SHARE_MODE_ENTRY) {
1173 /* cope with dead entries from the process not
1174 existing. These should not be considered valid,
1175 otherwise we end up doing zero timeout sharing
1176 violation */
1177 return False;
1180 num_props += ((e->op_type == NO_OPLOCK) ? 1 : 0);
1181 num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0);
1182 num_props += (LEVEL_II_OPLOCK_TYPE(e->op_type) ? 1 : 0);
1184 SMB_ASSERT(num_props <= 1);
1185 return (num_props != 0);
1188 bool is_deferred_open_entry(const struct share_mode_entry *e)
1190 return (e->op_type == DEFERRED_OPEN_ENTRY);
1193 bool is_unused_share_mode_entry(const struct share_mode_entry *e)
1195 return (e->op_type == UNUSED_SHARE_MODE_ENTRY);
1198 /*******************************************************************
1199 Fill a share mode entry.
1200 ********************************************************************/
1202 static void fill_share_mode_entry(struct share_mode_entry *e,
1203 files_struct *fsp,
1204 uid_t uid, uint64_t mid, uint16 op_type)
1206 ZERO_STRUCTP(e);
1207 e->pid = sconn_server_id(fsp->conn->sconn);
1208 e->share_access = fsp->share_access;
1209 e->private_options = fsp->fh->private_options;
1210 e->access_mask = fsp->access_mask;
1211 e->op_mid = mid;
1212 e->op_type = op_type;
1213 e->time.tv_sec = fsp->open_time.tv_sec;
1214 e->time.tv_usec = fsp->open_time.tv_usec;
1215 e->id = fsp->file_id;
1216 e->share_file_id = fsp->fh->gen_id;
1217 e->uid = (uint32)uid;
1218 e->flags = fsp->posix_open ? SHARE_MODE_FLAG_POSIX_OPEN : 0;
1219 e->name_hash = fsp->name_hash;
1222 static void fill_deferred_open_entry(struct share_mode_entry *e,
1223 const struct timeval request_time,
1224 struct file_id id,
1225 struct server_id pid,
1226 uint64_t mid)
1228 ZERO_STRUCTP(e);
1229 e->pid = pid;
1230 e->op_mid = mid;
1231 e->op_type = DEFERRED_OPEN_ENTRY;
1232 e->time.tv_sec = request_time.tv_sec;
1233 e->time.tv_usec = request_time.tv_usec;
1234 e->id = id;
1235 e->uid = (uint32)-1;
1236 e->flags = 0;
1239 static void add_share_mode_entry(struct share_mode_lock *lck,
1240 const struct share_mode_entry *entry)
1242 int i;
1244 for (i=0; i<lck->num_share_modes; i++) {
1245 struct share_mode_entry *e = &lck->share_modes[i];
1246 if (is_unused_share_mode_entry(e)) {
1247 *e = *entry;
1248 break;
1252 if (i == lck->num_share_modes) {
1253 /* No unused entry found */
1254 ADD_TO_ARRAY(lck, struct share_mode_entry, *entry,
1255 &lck->share_modes, &lck->num_share_modes);
1257 lck->modified = True;
1260 void set_share_mode(struct share_mode_lock *lck, files_struct *fsp,
1261 uid_t uid, uint64_t mid, uint16 op_type)
1263 struct share_mode_entry entry;
1264 fill_share_mode_entry(&entry, fsp, uid, mid, op_type);
1265 add_share_mode_entry(lck, &entry);
1268 void add_deferred_open(struct share_mode_lock *lck, uint64_t mid,
1269 struct timeval request_time,
1270 struct server_id pid, struct file_id id)
1272 struct share_mode_entry entry;
1273 fill_deferred_open_entry(&entry, request_time, id, pid, mid);
1274 add_share_mode_entry(lck, &entry);
1277 /*******************************************************************
1278 Check if two share mode entries are identical, ignoring oplock
1279 and mid info and desired_access. (Removed paranoia test - it's
1280 not automatically a logic error if they are identical. JRA.)
1281 ********************************************************************/
1283 static bool share_modes_identical(struct share_mode_entry *e1,
1284 struct share_mode_entry *e2)
1286 /* We used to check for e1->share_access == e2->share_access here
1287 as well as the other fields but 2 different DOS or FCB opens
1288 sharing the same share mode entry may validly differ in
1289 fsp->share_access field. */
1291 return (procid_equal(&e1->pid, &e2->pid) &&
1292 file_id_equal(&e1->id, &e2->id) &&
1293 e1->share_file_id == e2->share_file_id );
1296 static bool deferred_open_identical(struct share_mode_entry *e1,
1297 struct share_mode_entry *e2)
1299 return (procid_equal(&e1->pid, &e2->pid) &&
1300 (e1->op_mid == e2->op_mid) &&
1301 file_id_equal(&e1->id, &e2->id));
1304 static struct share_mode_entry *find_share_mode_entry(struct share_mode_lock *lck,
1305 struct share_mode_entry *entry)
1307 int i;
1309 for (i=0; i<lck->num_share_modes; i++) {
1310 struct share_mode_entry *e = &lck->share_modes[i];
1311 if (is_valid_share_mode_entry(entry) &&
1312 is_valid_share_mode_entry(e) &&
1313 share_modes_identical(e, entry)) {
1314 return e;
1316 if (is_deferred_open_entry(entry) &&
1317 is_deferred_open_entry(e) &&
1318 deferred_open_identical(e, entry)) {
1319 return e;
1322 return NULL;
1325 /*******************************************************************
1326 Del the share mode of a file for this process. Return the number of
1327 entries left.
1328 ********************************************************************/
1330 bool del_share_mode(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 e->op_type = UNUSED_SHARE_MODE_ENTRY;
1343 lck->modified = True;
1344 return True;
1347 void del_deferred_open_entry(struct share_mode_lock *lck, uint64_t mid,
1348 struct server_id pid)
1350 struct share_mode_entry entry, *e;
1352 fill_deferred_open_entry(&entry, timeval_zero(),
1353 lck->id, pid, mid);
1355 e = find_share_mode_entry(lck, &entry);
1356 if (e == NULL) {
1357 return;
1360 e->op_type = UNUSED_SHARE_MODE_ENTRY;
1361 lck->modified = True;
1364 /*******************************************************************
1365 Remove an oplock mid and mode entry from a share mode.
1366 ********************************************************************/
1368 bool remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
1370 struct share_mode_entry entry, *e;
1372 /* Don't care about the pid owner being correct here - just a search. */
1373 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1375 e = find_share_mode_entry(lck, &entry);
1376 if (e == NULL) {
1377 return False;
1380 if (EXCLUSIVE_OPLOCK_TYPE(e->op_type)) {
1382 * Going from exclusive or batch,
1383 * we always go through FAKE_LEVEL_II
1384 * first.
1386 if (!EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
1387 smb_panic("remove_share_oplock: logic error");
1389 e->op_type = FAKE_LEVEL_II_OPLOCK;
1390 } else {
1391 e->op_type = NO_OPLOCK;
1393 lck->modified = True;
1394 return True;
1397 /*******************************************************************
1398 Downgrade a oplock type from exclusive to level II.
1399 ********************************************************************/
1401 bool downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
1403 struct share_mode_entry entry, *e;
1405 /* Don't care about the pid owner being correct here - just a search. */
1406 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1408 e = find_share_mode_entry(lck, &entry);
1409 if (e == NULL) {
1410 return False;
1413 e->op_type = LEVEL_II_OPLOCK;
1414 lck->modified = True;
1415 return True;
1418 /****************************************************************************
1419 Check if setting delete on close is allowed on this fsp.
1420 ****************************************************************************/
1422 NTSTATUS can_set_delete_on_close(files_struct *fsp, uint32 dosmode)
1425 * Only allow delete on close for writable files.
1428 if ((dosmode & FILE_ATTRIBUTE_READONLY) &&
1429 !lp_delete_readonly(SNUM(fsp->conn))) {
1430 DEBUG(10,("can_set_delete_on_close: file %s delete on close "
1431 "flag set but file attribute is readonly.\n",
1432 fsp_str_dbg(fsp)));
1433 return NT_STATUS_CANNOT_DELETE;
1437 * Only allow delete on close for writable shares.
1440 if (!CAN_WRITE(fsp->conn)) {
1441 DEBUG(10,("can_set_delete_on_close: file %s delete on "
1442 "close flag set but write access denied on share.\n",
1443 fsp_str_dbg(fsp)));
1444 return NT_STATUS_ACCESS_DENIED;
1448 * Only allow delete on close for files/directories opened with delete
1449 * intent.
1452 if (!(fsp->access_mask & DELETE_ACCESS)) {
1453 DEBUG(10,("can_set_delete_on_close: file %s delete on "
1454 "close flag set but delete access denied.\n",
1455 fsp_str_dbg(fsp)));
1456 return NT_STATUS_ACCESS_DENIED;
1459 /* Don't allow delete on close for non-empty directories. */
1460 if (fsp->is_directory) {
1461 SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name));
1462 return can_delete_directory(fsp->conn,
1463 fsp->fsp_name->base_name);
1466 return NT_STATUS_OK;
1469 /*************************************************************************
1470 Return a talloced copy of a struct security_unix_token. NULL on fail.
1471 (Should this be in locking.c.... ?).
1472 *************************************************************************/
1474 static struct security_unix_token *copy_unix_token(TALLOC_CTX *ctx, const struct security_unix_token *tok)
1476 struct security_unix_token *cpy;
1478 cpy = TALLOC_P(ctx, struct security_unix_token);
1479 if (!cpy) {
1480 return NULL;
1483 cpy->uid = tok->uid;
1484 cpy->gid = tok->gid;
1485 cpy->ngroups = tok->ngroups;
1486 if (tok->ngroups) {
1487 /* Make this a talloc child of cpy. */
1488 cpy->groups = TALLOC_ARRAY(cpy, gid_t, tok->ngroups);
1489 if (!cpy->groups) {
1490 return NULL;
1492 memcpy(cpy->groups, tok->groups, tok->ngroups * sizeof(gid_t));
1494 return cpy;
1497 /****************************************************************************
1498 Adds a delete on close token.
1499 ****************************************************************************/
1501 static bool add_delete_on_close_token(struct share_mode_lock *lck,
1502 uint32_t name_hash,
1503 const struct security_unix_token *tok)
1505 struct delete_token_list *dtl;
1507 dtl = TALLOC_ZERO_P(lck, struct delete_token_list);
1508 if (dtl == NULL) {
1509 return false;
1512 dtl->name_hash = name_hash;
1513 dtl->delete_token = copy_unix_token(lck, tok);
1514 if (dtl->delete_token == NULL) {
1515 TALLOC_FREE(dtl);
1516 return false;
1518 DLIST_ADD(lck->delete_tokens, dtl);
1519 lck->modified = true;
1520 return true;
1523 /****************************************************************************
1524 Sets the delete on close flag over all share modes on this file.
1525 Modify the share mode entry for all files open
1526 on this device and inode to tell other smbds we have
1527 changed the delete on close flag. This will be noticed
1528 in the close code, the last closer will delete the file
1529 if flag is set.
1530 This makes a copy of any struct security_unix_token into the
1531 lck entry. This function is used when the lock is already granted.
1532 ****************************************************************************/
1534 void set_delete_on_close_lck(files_struct *fsp,
1535 struct share_mode_lock *lck,
1536 bool delete_on_close,
1537 const struct security_unix_token *tok)
1539 struct delete_token_list *dtl;
1540 bool ret;
1542 if (delete_on_close) {
1543 SMB_ASSERT(tok != NULL);
1544 } else {
1545 SMB_ASSERT(tok == NULL);
1548 for (dtl = lck->delete_tokens; dtl; dtl = dtl->next) {
1549 if (dtl->name_hash == fsp->name_hash) {
1550 lck->modified = true;
1551 if (delete_on_close == false) {
1552 /* Delete this entry. */
1553 DLIST_REMOVE(lck->delete_tokens, dtl);
1554 TALLOC_FREE(dtl);
1555 return;
1557 /* Replace this token with the
1558 given tok. */
1559 TALLOC_FREE(dtl->delete_token);
1560 dtl->delete_token = copy_unix_token(dtl, tok);
1561 SMB_ASSERT(dtl->delete_token != NULL);
1565 if (!delete_on_close) {
1566 /* Nothing to delete - not found. */
1567 return;
1570 ret = add_delete_on_close_token(lck, fsp->name_hash, tok);
1571 SMB_ASSERT(ret);
1574 bool set_delete_on_close(files_struct *fsp, bool delete_on_close, const struct security_unix_token *tok)
1576 struct share_mode_lock *lck;
1578 DEBUG(10,("set_delete_on_close: %s delete on close flag for "
1579 "fnum = %d, file %s\n",
1580 delete_on_close ? "Adding" : "Removing", fsp->fnum,
1581 fsp_str_dbg(fsp)));
1583 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
1584 NULL);
1585 if (lck == NULL) {
1586 return False;
1589 set_delete_on_close_lck(fsp, lck, delete_on_close,
1590 delete_on_close ? tok : NULL);
1592 if (fsp->is_directory) {
1593 SMB_ASSERT(!is_ntfs_stream_smb_fname(fsp->fsp_name));
1594 send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
1595 fsp->fsp_name->base_name);
1598 TALLOC_FREE(lck);
1600 fsp->delete_on_close = delete_on_close;
1602 return True;
1605 const struct security_unix_token *get_delete_on_close_token(struct share_mode_lock *lck, uint32_t name_hash)
1607 struct delete_token_list *dtl;
1609 DEBUG(10,("get_delete_on_close_token: name_hash = 0x%x\n",
1610 (unsigned int)name_hash ));
1612 for (dtl = lck->delete_tokens; dtl; dtl = dtl->next) {
1613 DEBUG(10,("get_delete_on_close_token: dtl->name_hash = 0x%x\n",
1614 (unsigned int)dtl->name_hash ));
1615 if (dtl->name_hash == name_hash) {
1616 return dtl->delete_token;
1619 return NULL;
1622 bool is_delete_on_close_set(struct share_mode_lock *lck, uint32_t name_hash)
1624 return (get_delete_on_close_token(lck, name_hash) != NULL);
1627 bool set_sticky_write_time(struct file_id fileid, struct timespec write_time)
1629 struct share_mode_lock *lck;
1631 DEBUG(5,("set_sticky_write_time: %s id=%s\n",
1632 timestring(talloc_tos(),
1633 convert_timespec_to_time_t(write_time)),
1634 file_id_string_tos(&fileid)));
1636 lck = get_share_mode_lock(NULL, fileid, NULL, NULL, NULL);
1637 if (lck == NULL) {
1638 return False;
1641 if (timespec_compare(&lck->changed_write_time, &write_time) != 0) {
1642 lck->modified = True;
1643 lck->changed_write_time = write_time;
1646 TALLOC_FREE(lck);
1647 return True;
1650 bool set_write_time(struct file_id fileid, struct timespec write_time)
1652 struct share_mode_lock *lck;
1654 DEBUG(5,("set_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->old_write_time, &write_time) != 0) {
1665 lck->modified = True;
1666 lck->old_write_time = write_time;
1669 TALLOC_FREE(lck);
1670 return True;
1674 struct forall_state {
1675 void (*fn)(const struct share_mode_entry *entry,
1676 const char *sharepath,
1677 const char *fname,
1678 void *private_data);
1679 void *private_data;
1682 static int traverse_fn(struct db_record *rec, void *_state)
1684 struct forall_state *state = (struct forall_state *)_state;
1685 struct locking_data *data;
1686 struct share_mode_entry *shares;
1687 const char *sharepath;
1688 const char *fname;
1689 const char *del_tokens;
1690 uint32_t total_del_token_size = 0;
1691 int i;
1693 /* Ensure this is a locking_key record. */
1694 if (rec->key.dsize != sizeof(struct file_id))
1695 return 0;
1697 data = (struct locking_data *)rec->value.dptr;
1698 shares = (struct share_mode_entry *)(rec->value.dptr + sizeof(*data));
1699 del_tokens = (const char *)rec->value.dptr + sizeof(*data) +
1700 data->u.s.num_share_mode_entries*sizeof(*shares);
1702 for (i = 0; i < data->u.s.num_delete_token_entries; i++) {
1703 uint32_t del_token_size;
1704 memcpy(&del_token_size, del_tokens, sizeof(uint32_t));
1705 total_del_token_size += del_token_size;
1706 del_tokens += del_token_size;
1709 sharepath = (const char *)rec->value.dptr + sizeof(*data) +
1710 data->u.s.num_share_mode_entries*sizeof(*shares) +
1711 total_del_token_size;
1712 fname = (const char *)rec->value.dptr + sizeof(*data) +
1713 data->u.s.num_share_mode_entries*sizeof(*shares) +
1714 total_del_token_size +
1715 strlen(sharepath) + 1;
1717 for (i=0;i<data->u.s.num_share_mode_entries;i++) {
1718 state->fn(&shares[i], sharepath, fname,
1719 state->private_data);
1721 return 0;
1724 /*******************************************************************
1725 Call the specified function on each entry under management by the
1726 share mode system.
1727 ********************************************************************/
1729 int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *,
1730 const char *, void *),
1731 void *private_data)
1733 struct forall_state state;
1735 if (lock_db == NULL)
1736 return 0;
1738 state.fn = fn;
1739 state.private_data = private_data;
1741 return lock_db->traverse_read(lock_db, traverse_fn, (void *)&state);