2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1992-2000
5 Copyright (C) Jeremy Allison 1992-2000
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 2 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, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 12 aug 96: Erik.Devriendt@te6.siemens.be
25 added support for shared memory implementation of share mode locking
27 May 1997. Jeremy Allison (jallison@whistle.com). Modified share mode
28 locking to deal with multiple share modes per open file.
30 September 1997. Jeremy Allison (jallison@whistle.com). Added oplock
33 rewrtten completely to use new tdb code. Tridge, Dec '99
35 Added POSIX locking support. Jeremy Allison (jeremy@valinux.com), Apr. 2000.
42 #define DBGC_CLASS DBGC_LOCKING
44 /* the locking database handle */
45 static TDB_CONTEXT *tdb;
47 /****************************************************************************
49 ****************************************************************************/
51 static const char *lock_type_name(enum brl_type lock_type)
53 return (lock_type == READ_LOCK) ? "READ" : "WRITE";
56 /****************************************************************************
57 Utility function called to see if a file region is locked.
58 ****************************************************************************/
60 BOOL is_locked(files_struct *fsp,connection_struct *conn,
61 SMB_BIG_UINT count,SMB_BIG_UINT offset,
62 enum brl_type lock_type)
64 int snum = SNUM(conn);
65 int strict_locking = lp_strict_locking(snum);
71 if (!lp_locking(snum) || !strict_locking)
74 if (strict_locking == Auto) {
75 if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (lock_type == READ_LOCK || lock_type == WRITE_LOCK)) {
76 DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp->fsp_name ));
78 } else if ((fsp->oplock_type == LEVEL_II_OPLOCK) &&
79 (lock_type == READ_LOCK)) {
80 DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp->fsp_name ));
83 ret = !brl_locktest(fsp->dev, fsp->inode, fsp->fnum,
84 global_smbpid, procid_self(), conn->cnum,
85 offset, count, lock_type);
88 ret = !brl_locktest(fsp->dev, fsp->inode, fsp->fnum,
89 global_smbpid, procid_self(), conn->cnum,
90 offset, count, lock_type);
93 DEBUG(10,("is_locked: brl start=%.0f len=%.0f %s for file %s\n",
94 (double)offset, (double)count, ret ? "locked" : "unlocked",
98 * There is no lock held by an SMB daemon, check to
99 * see if there is a POSIX lock from a UNIX or NFS process.
102 if(!ret && lp_posix_locking(snum)) {
103 ret = is_posix_locked(fsp, offset, count, lock_type);
105 DEBUG(10,("is_locked: posix start=%.0f len=%.0f %s for file %s\n",
106 (double)offset, (double)count, ret ? "locked" : "unlocked",
113 /****************************************************************************
114 Utility function called by locking requests.
115 ****************************************************************************/
117 static NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
118 SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type, BOOL *my_lock_ctx)
120 NTSTATUS status = NT_STATUS_LOCK_NOT_GRANTED;
122 if (!lp_locking(SNUM(conn)))
125 /* NOTE! 0 byte long ranges ARE allowed and should be stored */
127 DEBUG(10,("do_lock: lock type %s start=%.0f len=%.0f requested for file %s\n",
128 lock_type_name(lock_type), (double)offset, (double)count, fsp->fsp_name ));
130 if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) {
131 status = brl_lock(fsp->dev, fsp->inode, fsp->fnum,
132 lock_pid, procid_self(), conn->cnum,
134 lock_type, my_lock_ctx);
136 if (NT_STATUS_IS_OK(status) && lp_posix_locking(SNUM(conn))) {
139 * Try and get a POSIX lock on this range.
140 * Note that this is ok if it is a read lock
141 * overlapping on a different fd. JRA.
144 if (!set_posix_lock(fsp, offset, count, lock_type)) {
145 if (errno == EACCES || errno == EAGAIN)
146 status = NT_STATUS_FILE_LOCK_CONFLICT;
148 status = map_nt_error_from_unix(errno);
151 * We failed to map - we must now remove the brl
154 (void)brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
155 lock_pid, procid_self(), conn->cnum,
156 offset, count, False,
165 /****************************************************************************
166 Utility function called by locking requests. This is *DISGUSTING*. It also
167 appears to be "What Windows Does" (tm). Andrew, ever wonder why Windows 2000
168 is so slow on the locking tests...... ? This is the reason. Much though I hate
169 it, we need this. JRA.
170 ****************************************************************************/
172 NTSTATUS do_lock_spin(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
173 SMB_BIG_UINT count,SMB_BIG_UINT offset,enum brl_type lock_type, BOOL *my_lock_ctx)
175 int j, maxj = lp_lock_spin_count();
176 int sleeptime = lp_lock_sleep_time();
177 NTSTATUS status, ret;
182 ret = NT_STATUS_OK; /* to keep dumb compilers happy */
184 for (j = 0; j < maxj; j++) {
185 status = do_lock(fsp, conn, lock_pid, count, offset, lock_type, my_lock_ctx);
186 if (!NT_STATUS_EQUAL(status, NT_STATUS_LOCK_NOT_GRANTED) &&
187 !NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
190 /* if we do fail then return the first error code we got */
193 /* Don't spin if we blocked ourselves. */
198 sys_usleep(sleeptime);
203 /* Struct passed to brl_unlock. */
204 struct posix_unlock_data_struct {
210 /****************************************************************************
211 Function passed to brl_unlock to allow POSIX unlock to be done first.
212 ****************************************************************************/
214 static void posix_unlock(void *pre_data)
216 struct posix_unlock_data_struct *pdata = (struct posix_unlock_data_struct *)pre_data;
218 if (lp_posix_locking(SNUM(pdata->fsp->conn)))
219 release_posix_lock(pdata->fsp, pdata->offset, pdata->count);
222 /****************************************************************************
223 Utility function called by unlocking requests.
224 ****************************************************************************/
226 NTSTATUS do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
227 SMB_BIG_UINT count,SMB_BIG_UINT offset)
230 struct posix_unlock_data_struct posix_data;
232 if (!lp_locking(SNUM(conn)))
235 if (!OPEN_FSP(fsp) || !fsp->can_lock || (fsp->conn != conn)) {
236 return NT_STATUS_INVALID_HANDLE;
239 DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for file %s\n",
240 (double)offset, (double)count, fsp->fsp_name ));
243 * Remove the existing lock record from the tdb lockdb
244 * before looking at POSIX locks. If this record doesn't
245 * match then don't bother looking to remove POSIX locks.
248 posix_data.fsp = fsp;
249 posix_data.offset = offset;
250 posix_data.count = count;
252 ok = brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
253 lock_pid, procid_self(), conn->cnum, offset, count,
254 False, posix_unlock, (void *)&posix_data);
257 DEBUG(10,("do_unlock: returning ERRlock.\n" ));
258 return NT_STATUS_RANGE_NOT_LOCKED;
263 /****************************************************************************
264 Remove any locks on this fd. Called from file_close().
265 ****************************************************************************/
267 void locking_close_file(files_struct *fsp)
269 struct process_id pid = procid_self();
271 if (!lp_locking(SNUM(fsp->conn)))
275 * Just release all the brl locks, no need to release individually.
278 brl_close(fsp->dev, fsp->inode, pid, fsp->conn->cnum, fsp->fnum);
280 if(lp_posix_locking(SNUM(fsp->conn))) {
283 * Release all the POSIX locks.
285 posix_locking_close_file(fsp);
290 /****************************************************************************
291 Initialise the locking functions.
292 ****************************************************************************/
294 static int open_read_only;
296 BOOL locking_init(int read_only)
303 tdb = tdb_open_log(lock_path("locking.tdb"),
304 SMB_OPEN_DATABASE_TDB_HASH_SIZE, TDB_DEFAULT|(read_only?0x0:TDB_CLEAR_IF_FIRST),
305 read_only?O_RDONLY:O_RDWR|O_CREAT,
309 DEBUG(0,("ERROR: Failed to initialise locking database\n"));
313 if (!posix_locking_init(read_only))
316 open_read_only = read_only;
321 /*******************************************************************
322 Deinitialize the share_mode management.
323 ******************************************************************/
325 BOOL locking_end(void)
329 brl_shutdown(open_read_only);
331 if (tdb_close(tdb) != 0)
338 /*******************************************************************
339 Form a static locking key for a dev/inode pair.
340 ******************************************************************/
342 /* key and data records in the tdb locking database */
348 /*******************************************************************
349 Form a static locking key for a dev/inode pair.
350 ******************************************************************/
352 static TDB_DATA locking_key(SMB_DEV_T dev, SMB_INO_T inode)
354 static struct locking_key key;
357 memset(&key, '\0', sizeof(key));
360 kbuf.dptr = (char *)&key;
361 kbuf.dsize = sizeof(key);
365 /*******************************************************************
366 Print out a share mode.
367 ********************************************************************/
369 char *share_mode_str(int num, struct share_mode_entry *e)
371 static pstring share_str;
373 slprintf(share_str, sizeof(share_str)-1, "share_mode_entry[%d]: %s "
374 "pid = %s, share_access = 0x%x, private_options = 0x%x, "
375 "access_mask = 0x%x, mid = 0x%x, type= 0x%x, file_id = %lu, "
376 "dev = 0x%x, inode = %.0f",
378 e->op_type == UNUSED_SHARE_MODE_ENTRY ? "UNUSED" : "",
379 procid_str_static(&e->pid),
380 e->share_access, e->private_options,
381 e->access_mask, e->op_mid, e->op_type, e->share_file_id,
382 (unsigned int)e->dev, (double)e->inode );
387 /*******************************************************************
388 Print out a share mode table.
389 ********************************************************************/
391 static void print_share_mode_table(struct locking_data *data)
393 int num_share_modes = data->u.s.num_share_mode_entries;
394 struct share_mode_entry *shares =
395 (struct share_mode_entry *)(data + 1);
398 for (i = 0; i < num_share_modes; i++) {
399 struct share_mode_entry entry;
401 memcpy(&entry, &shares[i], sizeof(struct share_mode_entry));
402 DEBUG(10,("print_share_mode_table: %s\n",
403 share_mode_str(i, &entry)));
407 /*******************************************************************
408 Get all share mode entries for a dev/inode pair.
409 ********************************************************************/
411 static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck)
413 struct locking_data *data;
416 if (dbuf.dsize < sizeof(struct locking_data)) {
417 smb_panic("PANIC: parse_share_modes: buffer too short.\n");
420 data = (struct locking_data *)dbuf.dptr;
422 lck->delete_on_close = data->u.s.delete_on_close;
423 lck->initial_delete_on_close = data->u.s.initial_delete_on_close;
424 lck->num_share_modes = data->u.s.num_share_mode_entries;
426 DEBUG(10, ("parse_share_modes: delete_on_close: %d, "
427 "initial_delete_on_close: %d, "
428 "num_share_modes: %d\n",
429 lck->delete_on_close,
430 lck->initial_delete_on_close,
431 lck->num_share_modes));
433 if ((lck->num_share_modes < 0) || (lck->num_share_modes > 1000000)) {
434 DEBUG(0, ("invalid number of share modes: %d\n",
435 lck->num_share_modes));
436 smb_panic("PANIC: invalid number of share modes");
439 lck->share_modes = NULL;
441 if (lck->num_share_modes != 0) {
443 if (dbuf.dsize < (sizeof(struct locking_data) +
444 (lck->num_share_modes *
445 sizeof(struct share_mode_entry)))) {
446 smb_panic("PANIC: parse_share_modes: buffer too short.\n");
449 lck->share_modes = talloc_memdup(lck, dbuf.dptr+sizeof(*data),
450 lck->num_share_modes *
451 sizeof(struct share_mode_entry));
453 if (lck->share_modes == NULL) {
454 smb_panic("talloc failed\n");
458 /* Get any delete token. */
459 if (data->u.s.delete_token_size) {
460 /* Each uid/gid is stored as a 4 byte value. */
462 uint32 *p = (uint32 *)(dbuf.dptr + sizeof(*data) +
463 (lck->num_share_modes *
464 sizeof(struct share_mode_entry)));
466 if ((data->u.s.delete_token_size < 8) || (data->u.s.delete_token_size % 4) != 0) {
467 DEBUG(0, ("parse_share_modes: invalid token size %d\n",
468 data->u.s.delete_token_size));
469 smb_panic("parse_share_modes: invalid token size\n");
472 lck->delete_token = TALLOC_P(lck, UNIX_USER_TOKEN);
473 if (!lck->delete_token) {
474 smb_panic("talloc failed\n");
477 /* Copy out the uid and gid. */
478 memcpy(&val, p++, 4);
479 lck->delete_token->uid = (uid_t)val;
480 memcpy(&val, p++, 4);
481 lck->delete_token->gid = (gid_t)val;
483 /* Any supplementary groups ? */
484 lck->delete_token->ngroups = (data->u.s.delete_token_size > 8) ?
485 ((data->u.s.delete_token_size - 8)/4) : 0;
486 if (lck->delete_token->ngroups) {
487 /* Make this a talloc child of lck->delete_token. */
488 lck->delete_token->groups = TALLOC_ARRAY(lck->delete_token, gid_t,
489 lck->delete_token->ngroups);
490 if (!lck->delete_token) {
491 smb_panic("talloc failed\n");
494 for (i = 0; i < lck->delete_token->ngroups; i++) {
495 memcpy(&val, p++, 4);
496 lck->delete_token->groups[i] = (gid_t)val;
501 lck->delete_token = NULL;
504 /* Save off the associated service path and filename. */
505 lck->servicepath = talloc_strdup(lck, dbuf.dptr + sizeof(*data) +
506 (lck->num_share_modes *
507 sizeof(struct share_mode_entry)) +
508 data->u.s.delete_token_size );
510 lck->filename = talloc_strdup(lck, dbuf.dptr + sizeof(*data) +
511 (lck->num_share_modes *
512 sizeof(struct share_mode_entry)) +
513 data->u.s.delete_token_size +
514 strlen(lck->servicepath) + 1 );
517 * Ensure that each entry has a real process attached.
520 for (i = 0; i < lck->num_share_modes; i++) {
521 struct share_mode_entry *entry_p = &lck->share_modes[i];
522 DEBUG(10,("parse_share_modes: %s\n",
523 share_mode_str(i, entry_p) ));
524 if (!process_exists(entry_p->pid)) {
525 DEBUG(10,("parse_share_modes: deleted %s\n",
526 share_mode_str(i, entry_p) ));
527 entry_p->op_type = UNUSED_SHARE_MODE_ENTRY;
528 lck->modified = True;
535 static TDB_DATA unparse_share_modes(struct share_mode_lock *lck)
540 struct locking_data *data;
543 uint32 delete_token_size;
548 for (i=0; i<lck->num_share_modes; i++) {
549 if (!is_unused_share_mode_entry(&lck->share_modes[i])) {
554 if (num_valid == 0) {
558 sp_len = strlen(lck->servicepath);
559 delete_token_size = (lck->delete_token ?
560 (8 + (lck->delete_token->ngroups*4)) : 0);
562 result.dsize = sizeof(*data) +
563 lck->num_share_modes * sizeof(struct share_mode_entry) +
566 strlen(lck->filename) + 1;
567 result.dptr = talloc_size(lck, result.dsize);
569 if (result.dptr == NULL) {
570 smb_panic("talloc failed\n");
573 data = (struct locking_data *)result.dptr;
575 data->u.s.num_share_mode_entries = lck->num_share_modes;
576 data->u.s.delete_on_close = lck->delete_on_close;
577 data->u.s.initial_delete_on_close = lck->initial_delete_on_close;
578 data->u.s.delete_token_size = delete_token_size;
579 DEBUG(10, ("unparse_share_modes: del: %d, initial del %d, tok = %u, num: %d\n",
580 data->u.s.delete_on_close,
581 data->u.s.initial_delete_on_close,
582 (unsigned int)data->u.s.delete_token_size,
583 data->u.s.num_share_mode_entries));
584 memcpy(result.dptr + sizeof(*data), lck->share_modes,
585 sizeof(struct share_mode_entry)*lck->num_share_modes);
586 offset = sizeof(*data) +
587 sizeof(struct share_mode_entry)*lck->num_share_modes;
589 /* Store any delete on close token. */
590 if (lck->delete_token) {
592 uint32 *p = (uint32 *)(result.dptr + offset);
594 val = (uint32)lck->delete_token->uid;
595 memcpy(p++, &val, 4);
597 val = (uint32)lck->delete_token->uid;
598 memcpy(p++, &val, 4);
600 for (i = 0; i < lck->delete_token->ngroups; i++) {
601 val = (uint32)lck->delete_token->groups[i];
602 memcpy(p++, &val, 4);
604 offset = ((char *)p - result.dptr);
607 safe_strcpy(result.dptr + offset, lck->servicepath,
608 result.dsize - offset - 1);
609 offset += sp_len + 1;
610 safe_strcpy(result.dptr + offset, lck->filename,
611 result.dsize - offset - 1);
613 if (DEBUGLEVEL >= 10) {
614 print_share_mode_table(data);
620 static int share_mode_lock_destructor(void *p)
622 struct share_mode_lock *lck =
623 talloc_get_type_abort(p, struct share_mode_lock);
624 TDB_DATA key = locking_key(lck->dev, lck->ino);
627 if (!lck->modified) {
631 data = unparse_share_modes(lck);
633 if (data.dptr == NULL) {
635 /* There has been an entry before, delete it */
636 if (tdb_delete(tdb, key) == -1) {
637 smb_panic("Could not delete share entry\n");
643 if (tdb_store(tdb, key, data, TDB_REPLACE) == -1) {
644 smb_panic("Could not store share mode entry\n");
648 tdb_chainunlock(tdb, key);
653 struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
654 SMB_DEV_T dev, SMB_INO_T ino,
655 const char *servicepath,
658 struct share_mode_lock *lck;
659 TDB_DATA key = locking_key(dev, ino);
662 lck = TALLOC_P(mem_ctx, struct share_mode_lock);
664 DEBUG(0, ("talloc failed\n"));
668 /* Ensure we set every field here as the destructor must be
669 valid even if parse_share_modes fails. */
671 lck->servicepath = NULL;
672 lck->filename = NULL;
675 lck->num_share_modes = 0;
676 lck->share_modes = NULL;
677 lck->delete_token = NULL;
678 lck->delete_on_close = False;
679 lck->initial_delete_on_close = False;
681 lck->modified = False;
683 if (tdb_chainlock(tdb, key) != 0) {
684 DEBUG(3, ("Could not lock share entry\n"));
689 /* We must set the destructor immediately after the chainlock
690 ensure the lock is cleaned up on any of the error return
693 talloc_set_destructor(lck, share_mode_lock_destructor);
695 data = tdb_fetch(tdb, key);
696 lck->fresh = (data.dptr == NULL);
700 if (fname == NULL || servicepath == NULL) {
704 lck->filename = talloc_strdup(lck, fname);
705 lck->servicepath = talloc_strdup(lck, servicepath);
706 if (lck->filename == NULL || lck->servicepath == NULL) {
707 DEBUG(0, ("talloc failed\n"));
712 if (!parse_share_modes(data, lck)) {
713 DEBUG(0, ("Could not parse share modes\n"));
715 SAFE_FREE(data.dptr);
720 SAFE_FREE(data.dptr);
725 /*******************************************************************
726 Sets the service name and filename for rename.
727 At this point we emit "file renamed" messages to all
728 process id's that have this file open.
729 Based on an initial code idea from SATOH Fumiyasu <fumiya@samba.gr.jp>
730 ********************************************************************/
732 BOOL rename_share_filename(struct share_mode_lock *lck,
733 const char *servicepath,
746 DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n",
747 servicepath, newname));
750 * rename_internal_fsp() and rename_internals() add './' to
751 * head of newname if newname does not contain a '/'.
753 while (newname[0] && newname[1] && newname[0] == '.' && newname[1] == '/') {
757 lck->servicepath = talloc_strdup(lck, servicepath);
758 lck->filename = talloc_strdup(lck, newname);
759 if (lck->filename == NULL || lck->servicepath == NULL) {
760 DEBUG(0, ("rename_share_filename: talloc failed\n"));
763 lck->modified = True;
765 sp_len = strlen(lck->servicepath);
766 fn_len = strlen(lck->filename);
768 msg_len = MSG_FILE_RENAMED_MIN_SIZE + sp_len + 1 + fn_len + 1;
770 /* Set up the name changed message. */
771 frm = TALLOC(lck, msg_len);
776 SDEV_T_VAL(frm,0,lck->dev);
777 SINO_T_VAL(frm,8,lck->ino);
779 DEBUG(10,("rename_share_filename: msg_len = %d\n", msg_len ));
781 safe_strcpy(&frm[16], lck->servicepath, sp_len);
782 safe_strcpy(&frm[16 + sp_len + 1], lck->filename, fn_len);
784 /* Send the messages. */
785 for (i=0; i<lck->num_share_modes; i++) {
786 struct share_mode_entry *se = &lck->share_modes[i];
787 if (!is_valid_share_mode_entry(se)) {
790 /* But not to ourselves... */
791 if (procid_is_me(&se->pid)) {
795 DEBUG(10,("rename_share_filename: sending rename message to pid %u "
796 "dev %x, inode %.0f sharepath %s newname %s\n",
797 (unsigned int)procid_to_pid(&se->pid),
798 (unsigned int)lck->dev, (double)lck->ino,
799 lck->servicepath, lck->filename ));
802 message_send_pid(se->pid, MSG_SMB_FILE_RENAME,
810 BOOL get_delete_on_close_flag(SMB_DEV_T dev, SMB_INO_T inode)
813 struct share_mode_lock *lck = get_share_mode_lock(NULL, dev, inode, NULL, NULL);
817 result = lck->delete_on_close;
822 BOOL is_valid_share_mode_entry(const struct share_mode_entry *e)
826 num_props += ((e->op_type == NO_OPLOCK) ? 1 : 0);
827 num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0);
828 num_props += (LEVEL_II_OPLOCK_TYPE(e->op_type) ? 1 : 0);
830 SMB_ASSERT(num_props <= 1);
831 return (num_props != 0);
834 BOOL is_deferred_open_entry(const struct share_mode_entry *e)
836 return (e->op_type == DEFERRED_OPEN_ENTRY);
839 BOOL is_unused_share_mode_entry(const struct share_mode_entry *e)
841 return (e->op_type == UNUSED_SHARE_MODE_ENTRY);
844 /*******************************************************************
845 Fill a share mode entry.
846 ********************************************************************/
848 static void fill_share_mode_entry(struct share_mode_entry *e,
850 uint16 mid, uint16 op_type)
853 e->pid = procid_self();
854 e->share_access = fsp->share_access;
855 e->private_options = fsp->fh->private_options;
856 e->access_mask = fsp->access_mask;
858 e->op_type = op_type;
859 e->time.tv_sec = fsp->open_time.tv_sec;
860 e->time.tv_usec = fsp->open_time.tv_usec;
861 e->share_file_id = fsp->file_id;
863 e->inode = fsp->inode;
866 static void fill_deferred_open_entry(struct share_mode_entry *e,
867 const struct timeval request_time,
868 SMB_DEV_T dev, SMB_INO_T ino, uint16 mid)
871 e->pid = procid_self();
873 e->op_type = DEFERRED_OPEN_ENTRY;
874 e->time.tv_sec = request_time.tv_sec;
875 e->time.tv_usec = request_time.tv_usec;
880 static void add_share_mode_entry(struct share_mode_lock *lck,
881 const struct share_mode_entry *entry)
885 for (i=0; i<lck->num_share_modes; i++) {
886 struct share_mode_entry *e = &lck->share_modes[i];
887 if (is_unused_share_mode_entry(e)) {
893 if (i == lck->num_share_modes) {
894 /* No unused entry found */
895 ADD_TO_ARRAY(lck, struct share_mode_entry, *entry,
896 &lck->share_modes, &lck->num_share_modes);
898 lck->modified = True;
901 void set_share_mode(struct share_mode_lock *lck, files_struct *fsp,
902 uint16 mid, uint16 op_type)
904 struct share_mode_entry entry;
905 fill_share_mode_entry(&entry, fsp, mid, op_type);
906 add_share_mode_entry(lck, &entry);
909 void add_deferred_open(struct share_mode_lock *lck, uint16 mid,
910 struct timeval request_time,
911 SMB_DEV_T dev, SMB_INO_T ino)
913 struct share_mode_entry entry;
914 fill_deferred_open_entry(&entry, request_time, dev, ino, mid);
915 add_share_mode_entry(lck, &entry);
918 /*******************************************************************
919 Check if two share mode entries are identical, ignoring oplock
920 and mid info and desired_access.
921 ********************************************************************/
923 static BOOL share_modes_identical(struct share_mode_entry *e1,
924 struct share_mode_entry *e2)
926 #if 1 /* JRA PARANOIA TEST - REMOVE LATER */
927 if (procid_equal(&e1->pid, &e2->pid) &&
928 e1->share_file_id == e2->share_file_id &&
929 e1->dev == e2->dev &&
930 e1->inode == e2->inode &&
931 (e1->share_access) != (e2->share_access)) {
932 DEBUG(0,("PANIC: share_modes_identical: share_mode "
933 "mismatch (e1 = 0x%x, e2 = 0x%x). Logic error.\n",
934 (unsigned int)e1->share_access,
935 (unsigned int)e2->share_access ));
936 smb_panic("PANIC: share_modes_identical logic error.\n");
940 return (procid_equal(&e1->pid, &e2->pid) &&
941 (e1->share_access) == (e2->share_access) &&
942 e1->dev == e2->dev &&
943 e1->inode == e2->inode &&
944 e1->share_file_id == e2->share_file_id );
947 static BOOL deferred_open_identical(struct share_mode_entry *e1,
948 struct share_mode_entry *e2)
950 return (procid_equal(&e1->pid, &e2->pid) &&
951 (e1->op_mid == e2->op_mid) &&
952 (e1->dev == e2->dev) &&
953 (e1->inode == e2->inode));
956 static struct share_mode_entry *find_share_mode_entry(struct share_mode_lock *lck,
957 struct share_mode_entry *entry)
961 for (i=0; i<lck->num_share_modes; i++) {
962 struct share_mode_entry *e = &lck->share_modes[i];
963 if (is_valid_share_mode_entry(entry) &&
964 is_valid_share_mode_entry(e) &&
965 share_modes_identical(e, entry)) {
968 if (is_deferred_open_entry(entry) &&
969 is_deferred_open_entry(e) &&
970 deferred_open_identical(e, entry)) {
977 /*******************************************************************
978 Del the share mode of a file for this process. Return the number of
980 ********************************************************************/
982 BOOL del_share_mode(struct share_mode_lock *lck, files_struct *fsp)
984 struct share_mode_entry entry, *e;
986 fill_share_mode_entry(&entry, fsp, 0, 0);
988 e = find_share_mode_entry(lck, &entry);
993 e->op_type = UNUSED_SHARE_MODE_ENTRY;
994 lck->modified = True;
998 void del_deferred_open_entry(struct share_mode_lock *lck, uint16 mid)
1000 struct share_mode_entry entry, *e;
1002 fill_deferred_open_entry(&entry, timeval_zero(),
1003 lck->dev, lck->ino, mid);
1005 e = find_share_mode_entry(lck, &entry);
1010 e->op_type = UNUSED_SHARE_MODE_ENTRY;
1011 lck->modified = True;
1014 /*******************************************************************
1015 Remove an oplock mid and mode entry from a share mode.
1016 ********************************************************************/
1018 BOOL remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
1020 struct share_mode_entry entry, *e;
1022 fill_share_mode_entry(&entry, fsp, 0, 0);
1024 e = find_share_mode_entry(lck, &entry);
1030 e->op_type = NO_OPLOCK;
1031 lck->modified = True;
1035 /*******************************************************************
1036 Downgrade a oplock type from exclusive to level II.
1037 ********************************************************************/
1039 BOOL downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
1041 struct share_mode_entry entry, *e;
1043 fill_share_mode_entry(&entry, fsp, 0, 0);
1045 e = find_share_mode_entry(lck, &entry);
1050 e->op_type = LEVEL_II_OPLOCK;
1051 lck->modified = True;
1055 /****************************************************************************
1056 Deal with the internal needs of setting the delete on close flag. Note that
1057 as the tdb locking is recursive, it is safe to call this from within
1058 open_file_shared. JRA.
1059 ****************************************************************************/
1061 NTSTATUS can_set_delete_on_close(files_struct *fsp, BOOL delete_on_close,
1064 if (!delete_on_close) {
1065 return NT_STATUS_OK;
1069 * Only allow delete on close for writable files.
1072 if ((dosmode & aRONLY) &&
1073 !lp_delete_readonly(SNUM(fsp->conn))) {
1074 DEBUG(10,("can_set_delete_on_close: file %s delete on close "
1075 "flag set but file attribute is readonly.\n",
1077 return NT_STATUS_CANNOT_DELETE;
1081 * Only allow delete on close for writable shares.
1084 if (!CAN_WRITE(fsp->conn)) {
1085 DEBUG(10,("can_set_delete_on_close: file %s delete on "
1086 "close flag set but write access denied on share.\n",
1088 return NT_STATUS_ACCESS_DENIED;
1092 * Only allow delete on close for files/directories opened with delete
1096 if (!(fsp->access_mask & DELETE_ACCESS)) {
1097 DEBUG(10,("can_set_delete_on_close: file %s delete on "
1098 "close flag set but delete access denied.\n",
1100 return NT_STATUS_ACCESS_DENIED;
1103 return NT_STATUS_OK;
1106 /*************************************************************************
1107 Return a talloced copy of a UNIX_USER_TOKEN. NULL on fail.
1108 (Should this be in locking.c.... ?).
1109 *************************************************************************/
1111 static UNIX_USER_TOKEN *copy_unix_token(TALLOC_CTX *ctx, UNIX_USER_TOKEN *tok)
1113 UNIX_USER_TOKEN *cpy;
1119 cpy = TALLOC_P(ctx, UNIX_USER_TOKEN);
1124 cpy->uid = tok->uid;
1125 cpy->gid = tok->gid;
1126 cpy->ngroups = tok->ngroups;
1128 /* Make this a talloc child of cpy. */
1129 cpy->groups = TALLOC_ARRAY(cpy, gid_t, tok->ngroups);
1133 memcpy(cpy->groups, tok->groups, tok->ngroups * sizeof(gid_t));
1138 /****************************************************************************
1139 Replace the delete on close token.
1140 ****************************************************************************/
1142 void set_delete_on_close_token(struct share_mode_lock *lck, UNIX_USER_TOKEN *tok)
1144 /* Ensure there's no token. */
1145 if (lck->delete_token) {
1146 talloc_free(lck->delete_token); /* Also deletes groups... */
1147 lck->delete_token = NULL;
1150 /* Copy the new token (can be NULL). */
1151 lck->delete_token = copy_unix_token(lck, tok);
1152 lck->modified = True;
1155 /****************************************************************************
1156 Sets the delete on close flag over all share modes on this file.
1157 Modify the share mode entry for all files open
1158 on this device and inode to tell other smbds we have
1159 changed the delete on close flag. This will be noticed
1160 in the close code, the last closer will delete the file
1162 Note that setting this to any value clears the initial_delete_on_close flag.
1163 If delete_on_close is True this makes a copy of any UNIX_USER_TOKEN into the
1165 ****************************************************************************/
1167 BOOL set_delete_on_close(files_struct *fsp, BOOL delete_on_close, UNIX_USER_TOKEN *tok)
1169 struct share_mode_lock *lck;
1171 DEBUG(10,("set_delete_on_close: %s delete on close flag for "
1172 "fnum = %d, file %s\n",
1173 delete_on_close ? "Adding" : "Removing", fsp->fnum,
1180 lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL);
1185 if (lck->delete_on_close != delete_on_close) {
1186 set_delete_on_close_token(lck, tok);
1187 lck->delete_on_close = delete_on_close;
1188 if (delete_on_close) {
1189 SMB_ASSERT(lck->delete_token != NULL);
1191 lck->modified = True;
1194 if (lck->initial_delete_on_close) {
1195 lck->initial_delete_on_close = False;
1196 lck->modified = True;
1203 static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf,
1206 struct locking_data *data;
1207 struct share_mode_entry *shares;
1208 const char *sharepath;
1211 void (*traverse_callback)(struct share_mode_entry *, const char *, const char *) = state;
1213 /* Ensure this is a locking_key record. */
1214 if (kbuf.dsize != sizeof(struct locking_key))
1217 data = (struct locking_data *)dbuf.dptr;
1218 shares = (struct share_mode_entry *)(dbuf.dptr + sizeof(*data));
1219 sharepath = dbuf.dptr + sizeof(*data) +
1220 data->u.s.num_share_mode_entries*sizeof(*shares) +
1221 data->u.s.delete_token_size;
1222 fname = dbuf.dptr + sizeof(*data) +
1223 data->u.s.num_share_mode_entries*sizeof(*shares) +
1224 data->u.s.delete_token_size +
1225 strlen(sharepath) + 1;
1227 for (i=0;i<data->u.s.num_share_mode_entries;i++) {
1228 traverse_callback(&shares[i], sharepath, fname);
1233 /*******************************************************************
1234 Call the specified function on each entry under management by the
1236 ********************************************************************/
1238 int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *, const char *))
1242 return tdb_traverse(tdb, traverse_fn, fn);