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 char *p = dbuf.dptr + sizeof(*data) +
461 (lck->num_share_modes *
462 sizeof(struct share_mode_entry));
464 if ((data->u.s.delete_token_size < sizeof(uid_t) + sizeof(gid_t)) ||
465 ((data->u.s.delete_token_size - sizeof(uid_t)) % sizeof(gid_t)) != 0) {
466 DEBUG(0, ("parse_share_modes: invalid token size %d\n",
467 data->u.s.delete_token_size));
468 smb_panic("parse_share_modes: invalid token size\n");
471 lck->delete_token = TALLOC_P(lck, UNIX_USER_TOKEN);
472 if (!lck->delete_token) {
473 smb_panic("talloc failed\n");
476 /* Copy out the uid and gid. */
477 memcpy(&lck->delete_token->uid, p, sizeof(uid_t));
479 memcpy(&lck->delete_token->gid, p, sizeof(gid_t));
482 /* Any supplementary groups ? */
483 lck->delete_token->ngroups = (data->u.s.delete_token_size > (sizeof(uid_t) + sizeof(gid_t))) ?
484 ((data->u.s.delete_token_size -
485 (sizeof(uid_t) + sizeof(gid_t)))/sizeof(gid_t)) : 0;
487 if (lck->delete_token->ngroups) {
488 /* Make this a talloc child of lck->delete_token. */
489 lck->delete_token->groups = TALLOC_ARRAY(lck->delete_token, gid_t,
490 lck->delete_token->ngroups);
491 if (!lck->delete_token) {
492 smb_panic("talloc failed\n");
495 for (i = 0; i < lck->delete_token->ngroups; i++) {
496 memcpy(&lck->delete_token->groups[i], p, sizeof(gid_t));
502 lck->delete_token = NULL;
505 /* Save off the associated service path and filename. */
506 lck->servicepath = talloc_strdup(lck, dbuf.dptr + sizeof(*data) +
507 (lck->num_share_modes *
508 sizeof(struct share_mode_entry)) +
509 data->u.s.delete_token_size );
511 lck->filename = talloc_strdup(lck, dbuf.dptr + sizeof(*data) +
512 (lck->num_share_modes *
513 sizeof(struct share_mode_entry)) +
514 data->u.s.delete_token_size +
515 strlen(lck->servicepath) + 1 );
518 * Ensure that each entry has a real process attached.
521 for (i = 0; i < lck->num_share_modes; i++) {
522 struct share_mode_entry *entry_p = &lck->share_modes[i];
523 DEBUG(10,("parse_share_modes: %s\n",
524 share_mode_str(i, entry_p) ));
525 if (!process_exists(entry_p->pid)) {
526 DEBUG(10,("parse_share_modes: deleted %s\n",
527 share_mode_str(i, entry_p) ));
528 entry_p->op_type = UNUSED_SHARE_MODE_ENTRY;
529 lck->modified = True;
536 static TDB_DATA unparse_share_modes(struct share_mode_lock *lck)
541 struct locking_data *data;
544 uint32 delete_token_size;
549 for (i=0; i<lck->num_share_modes; i++) {
550 if (!is_unused_share_mode_entry(&lck->share_modes[i])) {
555 if (num_valid == 0) {
559 sp_len = strlen(lck->servicepath);
560 delete_token_size = (lck->delete_token ?
561 (sizeof(uid_t) + sizeof(gid_t) + (lck->delete_token->ngroups*sizeof(gid_t))) : 0);
563 result.dsize = sizeof(*data) +
564 lck->num_share_modes * sizeof(struct share_mode_entry) +
567 strlen(lck->filename) + 1;
568 result.dptr = talloc_size(lck, result.dsize);
570 if (result.dptr == NULL) {
571 smb_panic("talloc failed\n");
574 data = (struct locking_data *)result.dptr;
576 data->u.s.num_share_mode_entries = lck->num_share_modes;
577 data->u.s.delete_on_close = lck->delete_on_close;
578 data->u.s.initial_delete_on_close = lck->initial_delete_on_close;
579 data->u.s.delete_token_size = delete_token_size;
580 DEBUG(10, ("unparse_share_modes: del: %d, initial del %d, tok = %u, num: %d\n",
581 data->u.s.delete_on_close,
582 data->u.s.initial_delete_on_close,
583 (unsigned int)data->u.s.delete_token_size,
584 data->u.s.num_share_mode_entries));
585 memcpy(result.dptr + sizeof(*data), lck->share_modes,
586 sizeof(struct share_mode_entry)*lck->num_share_modes);
587 offset = sizeof(*data) +
588 sizeof(struct share_mode_entry)*lck->num_share_modes;
590 /* Store any delete on close token. */
591 if (lck->delete_token) {
592 char *p = result.dptr + offset;
594 memcpy(p, &lck->delete_token->uid, sizeof(uid_t));
597 memcpy(p, &lck->delete_token->gid, sizeof(gid_t));
599 for (i = 0; i < lck->delete_token->ngroups; i++) {
600 memcpy(p, &lck->delete_token->groups[i], sizeof(gid_t));
603 offset = p - result.dptr;
606 safe_strcpy(result.dptr + offset, lck->servicepath,
607 result.dsize - offset - 1);
608 offset += sp_len + 1;
609 safe_strcpy(result.dptr + offset, lck->filename,
610 result.dsize - offset - 1);
612 if (DEBUGLEVEL >= 10) {
613 print_share_mode_table(data);
619 static int share_mode_lock_destructor(void *p)
621 struct share_mode_lock *lck =
622 talloc_get_type_abort(p, struct share_mode_lock);
623 TDB_DATA key = locking_key(lck->dev, lck->ino);
626 if (!lck->modified) {
630 data = unparse_share_modes(lck);
632 if (data.dptr == NULL) {
634 /* There has been an entry before, delete it */
635 if (tdb_delete(tdb, key) == -1) {
636 smb_panic("Could not delete share entry\n");
642 if (tdb_store(tdb, key, data, TDB_REPLACE) == -1) {
643 smb_panic("Could not store share mode entry\n");
647 tdb_chainunlock(tdb, key);
652 struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
653 SMB_DEV_T dev, SMB_INO_T ino,
654 const char *servicepath,
657 struct share_mode_lock *lck;
658 TDB_DATA key = locking_key(dev, ino);
661 lck = TALLOC_P(mem_ctx, struct share_mode_lock);
663 DEBUG(0, ("talloc failed\n"));
667 /* Ensure we set every field here as the destructor must be
668 valid even if parse_share_modes fails. */
670 lck->servicepath = NULL;
671 lck->filename = NULL;
674 lck->num_share_modes = 0;
675 lck->share_modes = NULL;
676 lck->delete_token = NULL;
677 lck->delete_on_close = False;
678 lck->initial_delete_on_close = False;
680 lck->modified = False;
682 if (tdb_chainlock(tdb, key) != 0) {
683 DEBUG(3, ("Could not lock share entry\n"));
688 /* We must set the destructor immediately after the chainlock
689 ensure the lock is cleaned up on any of the error return
692 talloc_set_destructor(lck, share_mode_lock_destructor);
694 data = tdb_fetch(tdb, key);
695 lck->fresh = (data.dptr == NULL);
699 if (fname == NULL || servicepath == NULL) {
703 lck->filename = talloc_strdup(lck, fname);
704 lck->servicepath = talloc_strdup(lck, servicepath);
705 if (lck->filename == NULL || lck->servicepath == NULL) {
706 DEBUG(0, ("talloc failed\n"));
711 if (!parse_share_modes(data, lck)) {
712 DEBUG(0, ("Could not parse share modes\n"));
714 SAFE_FREE(data.dptr);
719 SAFE_FREE(data.dptr);
724 /*******************************************************************
725 Sets the service name and filename for rename.
726 At this point we emit "file renamed" messages to all
727 process id's that have this file open.
728 Based on an initial code idea from SATOH Fumiyasu <fumiya@samba.gr.jp>
729 ********************************************************************/
731 BOOL rename_share_filename(struct share_mode_lock *lck,
732 const char *servicepath,
745 DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n",
746 servicepath, newname));
749 * rename_internal_fsp() and rename_internals() add './' to
750 * head of newname if newname does not contain a '/'.
752 while (newname[0] && newname[1] && newname[0] == '.' && newname[1] == '/') {
756 lck->servicepath = talloc_strdup(lck, servicepath);
757 lck->filename = talloc_strdup(lck, newname);
758 if (lck->filename == NULL || lck->servicepath == NULL) {
759 DEBUG(0, ("rename_share_filename: talloc failed\n"));
762 lck->modified = True;
764 sp_len = strlen(lck->servicepath);
765 fn_len = strlen(lck->filename);
767 msg_len = MSG_FILE_RENAMED_MIN_SIZE + sp_len + 1 + fn_len + 1;
769 /* Set up the name changed message. */
770 frm = TALLOC(lck, msg_len);
775 SDEV_T_VAL(frm,0,lck->dev);
776 SINO_T_VAL(frm,8,lck->ino);
778 DEBUG(10,("rename_share_filename: msg_len = %d\n", msg_len ));
780 safe_strcpy(&frm[16], lck->servicepath, sp_len);
781 safe_strcpy(&frm[16 + sp_len + 1], lck->filename, fn_len);
783 /* Send the messages. */
784 for (i=0; i<lck->num_share_modes; i++) {
785 struct share_mode_entry *se = &lck->share_modes[i];
786 if (!is_valid_share_mode_entry(se)) {
789 /* But not to ourselves... */
790 if (procid_is_me(&se->pid)) {
794 DEBUG(10,("rename_share_filename: sending rename message to pid %u "
795 "dev %x, inode %.0f sharepath %s newname %s\n",
796 (unsigned int)procid_to_pid(&se->pid),
797 (unsigned int)lck->dev, (double)lck->ino,
798 lck->servicepath, lck->filename ));
801 message_send_pid(se->pid, MSG_SMB_FILE_RENAME,
809 BOOL get_delete_on_close_flag(SMB_DEV_T dev, SMB_INO_T inode)
812 struct share_mode_lock *lck = get_share_mode_lock(NULL, dev, inode, NULL, NULL);
816 result = lck->delete_on_close;
821 BOOL is_valid_share_mode_entry(const struct share_mode_entry *e)
825 num_props += ((e->op_type == NO_OPLOCK) ? 1 : 0);
826 num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0);
827 num_props += (LEVEL_II_OPLOCK_TYPE(e->op_type) ? 1 : 0);
829 SMB_ASSERT(num_props <= 1);
830 return (num_props != 0);
833 BOOL is_deferred_open_entry(const struct share_mode_entry *e)
835 return (e->op_type == DEFERRED_OPEN_ENTRY);
838 BOOL is_unused_share_mode_entry(const struct share_mode_entry *e)
840 return (e->op_type == UNUSED_SHARE_MODE_ENTRY);
843 /*******************************************************************
844 Fill a share mode entry.
845 ********************************************************************/
847 static void fill_share_mode_entry(struct share_mode_entry *e,
849 uint16 mid, uint16 op_type)
852 e->pid = procid_self();
853 e->share_access = fsp->share_access;
854 e->private_options = fsp->fh->private_options;
855 e->access_mask = fsp->access_mask;
857 e->op_type = op_type;
858 e->time.tv_sec = fsp->open_time.tv_sec;
859 e->time.tv_usec = fsp->open_time.tv_usec;
860 e->share_file_id = fsp->file_id;
862 e->inode = fsp->inode;
865 static void fill_deferred_open_entry(struct share_mode_entry *e,
866 const struct timeval request_time,
867 SMB_DEV_T dev, SMB_INO_T ino, uint16 mid)
870 e->pid = procid_self();
872 e->op_type = DEFERRED_OPEN_ENTRY;
873 e->time.tv_sec = request_time.tv_sec;
874 e->time.tv_usec = request_time.tv_usec;
879 static void add_share_mode_entry(struct share_mode_lock *lck,
880 const struct share_mode_entry *entry)
884 for (i=0; i<lck->num_share_modes; i++) {
885 struct share_mode_entry *e = &lck->share_modes[i];
886 if (is_unused_share_mode_entry(e)) {
892 if (i == lck->num_share_modes) {
893 /* No unused entry found */
894 ADD_TO_ARRAY(lck, struct share_mode_entry, *entry,
895 &lck->share_modes, &lck->num_share_modes);
897 lck->modified = True;
900 void set_share_mode(struct share_mode_lock *lck, files_struct *fsp,
901 uint16 mid, uint16 op_type)
903 struct share_mode_entry entry;
904 fill_share_mode_entry(&entry, fsp, mid, op_type);
905 add_share_mode_entry(lck, &entry);
908 void add_deferred_open(struct share_mode_lock *lck, uint16 mid,
909 struct timeval request_time,
910 SMB_DEV_T dev, SMB_INO_T ino)
912 struct share_mode_entry entry;
913 fill_deferred_open_entry(&entry, request_time, dev, ino, mid);
914 add_share_mode_entry(lck, &entry);
917 /*******************************************************************
918 Check if two share mode entries are identical, ignoring oplock
919 and mid info and desired_access.
920 ********************************************************************/
922 static BOOL share_modes_identical(struct share_mode_entry *e1,
923 struct share_mode_entry *e2)
925 #if 1 /* JRA PARANOIA TEST - REMOVE LATER */
926 if (procid_equal(&e1->pid, &e2->pid) &&
927 e1->share_file_id == e2->share_file_id &&
928 e1->dev == e2->dev &&
929 e1->inode == e2->inode &&
930 (e1->share_access) != (e2->share_access)) {
931 DEBUG(0,("PANIC: share_modes_identical: share_mode "
932 "mismatch (e1 = 0x%x, e2 = 0x%x). Logic error.\n",
933 (unsigned int)e1->share_access,
934 (unsigned int)e2->share_access ));
935 smb_panic("PANIC: share_modes_identical logic error.\n");
939 return (procid_equal(&e1->pid, &e2->pid) &&
940 (e1->share_access) == (e2->share_access) &&
941 e1->dev == e2->dev &&
942 e1->inode == e2->inode &&
943 e1->share_file_id == e2->share_file_id );
946 static BOOL deferred_open_identical(struct share_mode_entry *e1,
947 struct share_mode_entry *e2)
949 return (procid_equal(&e1->pid, &e2->pid) &&
950 (e1->op_mid == e2->op_mid) &&
951 (e1->dev == e2->dev) &&
952 (e1->inode == e2->inode));
955 static struct share_mode_entry *find_share_mode_entry(struct share_mode_lock *lck,
956 struct share_mode_entry *entry)
960 for (i=0; i<lck->num_share_modes; i++) {
961 struct share_mode_entry *e = &lck->share_modes[i];
962 if (is_valid_share_mode_entry(entry) &&
963 is_valid_share_mode_entry(e) &&
964 share_modes_identical(e, entry)) {
967 if (is_deferred_open_entry(entry) &&
968 is_deferred_open_entry(e) &&
969 deferred_open_identical(e, entry)) {
976 /*******************************************************************
977 Del the share mode of a file for this process. Return the number of
979 ********************************************************************/
981 BOOL del_share_mode(struct share_mode_lock *lck, files_struct *fsp)
983 struct share_mode_entry entry, *e;
985 fill_share_mode_entry(&entry, fsp, 0, 0);
987 e = find_share_mode_entry(lck, &entry);
992 e->op_type = UNUSED_SHARE_MODE_ENTRY;
993 lck->modified = True;
997 void del_deferred_open_entry(struct share_mode_lock *lck, uint16 mid)
999 struct share_mode_entry entry, *e;
1001 fill_deferred_open_entry(&entry, timeval_zero(),
1002 lck->dev, lck->ino, mid);
1004 e = find_share_mode_entry(lck, &entry);
1009 e->op_type = UNUSED_SHARE_MODE_ENTRY;
1010 lck->modified = True;
1013 /*******************************************************************
1014 Remove an oplock mid and mode entry from a share mode.
1015 ********************************************************************/
1017 BOOL remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
1019 struct share_mode_entry entry, *e;
1021 fill_share_mode_entry(&entry, fsp, 0, 0);
1023 e = find_share_mode_entry(lck, &entry);
1029 e->op_type = NO_OPLOCK;
1030 lck->modified = True;
1034 /*******************************************************************
1035 Downgrade a oplock type from exclusive to level II.
1036 ********************************************************************/
1038 BOOL downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
1040 struct share_mode_entry entry, *e;
1042 fill_share_mode_entry(&entry, fsp, 0, 0);
1044 e = find_share_mode_entry(lck, &entry);
1049 e->op_type = LEVEL_II_OPLOCK;
1050 lck->modified = True;
1054 /****************************************************************************
1055 Deal with the internal needs of setting the delete on close flag. Note that
1056 as the tdb locking is recursive, it is safe to call this from within
1057 open_file_shared. JRA.
1058 ****************************************************************************/
1060 NTSTATUS can_set_delete_on_close(files_struct *fsp, BOOL delete_on_close,
1063 if (!delete_on_close) {
1064 return NT_STATUS_OK;
1068 * Only allow delete on close for writable files.
1071 if ((dosmode & aRONLY) &&
1072 !lp_delete_readonly(SNUM(fsp->conn))) {
1073 DEBUG(10,("can_set_delete_on_close: file %s delete on close "
1074 "flag set but file attribute is readonly.\n",
1076 return NT_STATUS_CANNOT_DELETE;
1080 * Only allow delete on close for writable shares.
1083 if (!CAN_WRITE(fsp->conn)) {
1084 DEBUG(10,("can_set_delete_on_close: file %s delete on "
1085 "close flag set but write access denied on share.\n",
1087 return NT_STATUS_ACCESS_DENIED;
1091 * Only allow delete on close for files/directories opened with delete
1095 if (!(fsp->access_mask & DELETE_ACCESS)) {
1096 DEBUG(10,("can_set_delete_on_close: file %s delete on "
1097 "close flag set but delete access denied.\n",
1099 return NT_STATUS_ACCESS_DENIED;
1102 return NT_STATUS_OK;
1105 /*************************************************************************
1106 Return a talloced copy of a UNIX_USER_TOKEN. NULL on fail.
1107 (Should this be in locking.c.... ?).
1108 *************************************************************************/
1110 static UNIX_USER_TOKEN *copy_unix_token(TALLOC_CTX *ctx, UNIX_USER_TOKEN *tok)
1112 UNIX_USER_TOKEN *cpy;
1118 cpy = TALLOC_P(ctx, UNIX_USER_TOKEN);
1123 cpy->uid = tok->uid;
1124 cpy->gid = tok->gid;
1125 cpy->ngroups = tok->ngroups;
1127 /* Make this a talloc child of cpy. */
1128 cpy->groups = TALLOC_ARRAY(cpy, gid_t, tok->ngroups);
1132 memcpy(cpy->groups, tok->groups, tok->ngroups * sizeof(gid_t));
1137 /****************************************************************************
1138 Replace the delete on close token.
1139 ****************************************************************************/
1141 void set_delete_on_close_token(struct share_mode_lock *lck, UNIX_USER_TOKEN *tok)
1143 /* Ensure there's no token. */
1144 if (lck->delete_token) {
1145 TALLOC_FREE(lck->delete_token); /* Also deletes groups... */
1146 lck->delete_token = NULL;
1149 /* Copy the new token (can be NULL). */
1150 lck->delete_token = copy_unix_token(lck, tok);
1151 lck->modified = True;
1154 /****************************************************************************
1155 Sets the delete on close flag over all share modes on this file.
1156 Modify the share mode entry for all files open
1157 on this device and inode to tell other smbds we have
1158 changed the delete on close flag. This will be noticed
1159 in the close code, the last closer will delete the file
1161 Note that setting this to any value clears the initial_delete_on_close flag.
1162 If delete_on_close is True this makes a copy of any UNIX_USER_TOKEN into the
1164 ****************************************************************************/
1166 BOOL set_delete_on_close(files_struct *fsp, BOOL delete_on_close, UNIX_USER_TOKEN *tok)
1168 struct share_mode_lock *lck;
1170 DEBUG(10,("set_delete_on_close: %s delete on close flag for "
1171 "fnum = %d, file %s\n",
1172 delete_on_close ? "Adding" : "Removing", fsp->fnum,
1179 lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL);
1184 if (lck->delete_on_close != delete_on_close) {
1185 set_delete_on_close_token(lck, tok);
1186 lck->delete_on_close = delete_on_close;
1187 if (delete_on_close) {
1188 SMB_ASSERT(lck->delete_token != NULL);
1190 lck->modified = True;
1193 if (lck->initial_delete_on_close) {
1194 lck->initial_delete_on_close = False;
1195 lck->modified = True;
1202 static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf,
1205 struct locking_data *data;
1206 struct share_mode_entry *shares;
1207 const char *sharepath;
1210 void (*traverse_callback)(struct share_mode_entry *, const char *, const char *) = state;
1212 /* Ensure this is a locking_key record. */
1213 if (kbuf.dsize != sizeof(struct locking_key))
1216 data = (struct locking_data *)dbuf.dptr;
1217 shares = (struct share_mode_entry *)(dbuf.dptr + sizeof(*data));
1218 sharepath = dbuf.dptr + sizeof(*data) +
1219 data->u.s.num_share_mode_entries*sizeof(*shares) +
1220 data->u.s.delete_token_size;
1221 fname = dbuf.dptr + sizeof(*data) +
1222 data->u.s.num_share_mode_entries*sizeof(*shares) +
1223 data->u.s.delete_token_size +
1224 strlen(sharepath) + 1;
1226 for (i=0;i<data->u.s.num_share_mode_entries;i++) {
1227 traverse_callback(&shares[i], sharepath, fname);
1232 /*******************************************************************
1233 Call the specified function on each entry under management by the
1235 ********************************************************************/
1237 int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *, const char *))
1241 return tdb_traverse(tdb, traverse_fn, fn);