source: branches/samba-3.0/source/locking/locking.c@ 578

Last change on this file since 578 was 62, checked in by Paul Smedley, 18 years ago

Update source to 3.0.25c level

File size: 38.8 KB
Line 
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
7
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.
12
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.
17
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.
21
22 Revision History:
23
24 12 aug 96: Erik.Devriendt@te6.siemens.be
25 added support for shared memory implementation of share mode locking
26
27 May 1997. Jeremy Allison (jallison@whistle.com). Modified share mode
28 locking to deal with multiple share modes per open file.
29
30 September 1997. Jeremy Allison (jallison@whistle.com). Added oplock
31 support.
32
33 rewrtten completely to use new tdb code. Tridge, Dec '99
34
35 Added POSIX locking support. Jeremy Allison (jeremy@valinux.com), Apr. 2000.
36 Added Unix Extensions POSIX locking support. Jeremy Allison Mar 2006.
37*/
38
39#include "includes.h"
40
41#undef DBGC_CLASS
42#define DBGC_CLASS DBGC_LOCKING
43
44#define NO_LOCKING_COUNT (-1)
45
46/* the locking database handle */
47static TDB_CONTEXT *tdb;
48
49/****************************************************************************
50 Debugging aids :-).
51****************************************************************************/
52
53const char *lock_type_name(enum brl_type lock_type)
54{
55 switch (lock_type) {
56 case READ_LOCK:
57 return "READ";
58 case WRITE_LOCK:
59 return "WRITE";
60 case PENDING_READ_LOCK:
61 return "PENDING_READ";
62 case PENDING_WRITE_LOCK:
63 return "PENDING_WRITE";
64 default:
65 return "other";
66 }
67}
68
69const char *lock_flav_name(enum brl_flavour lock_flav)
70{
71 return (lock_flav == WINDOWS_LOCK) ? "WINDOWS_LOCK" : "POSIX_LOCK";
72}
73
74/****************************************************************************
75 Utility function called to see if a file region is locked.
76 Called in the read/write codepath.
77****************************************************************************/
78
79BOOL is_locked(files_struct *fsp,
80 uint32 smbpid,
81 SMB_BIG_UINT count,
82 SMB_BIG_UINT offset,
83 enum brl_type lock_type)
84{
85 int strict_locking = lp_strict_locking(fsp->conn->params);
86 enum brl_flavour lock_flav = lp_posix_cifsu_locktype(fsp);
87 BOOL ret = True;
88
89 if (count == 0) {
90 return False;
91 }
92
93 if (!lp_locking(fsp->conn->params) || !strict_locking) {
94 return False;
95 }
96
97 if (strict_locking == Auto) {
98 if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && (lock_type == READ_LOCK || lock_type == WRITE_LOCK)) {
99 DEBUG(10,("is_locked: optimisation - exclusive oplock on file %s\n", fsp->fsp_name ));
100 ret = False;
101 } else if ((fsp->oplock_type == LEVEL_II_OPLOCK) &&
102 (lock_type == READ_LOCK)) {
103 DEBUG(10,("is_locked: optimisation - level II oplock on file %s\n", fsp->fsp_name ));
104 ret = False;
105 } else {
106 struct byte_range_lock *br_lck = brl_get_locks_readonly(NULL, fsp);
107 if (!br_lck) {
108 return False;
109 }
110 ret = !brl_locktest(br_lck,
111 smbpid,
112 procid_self(),
113 offset,
114 count,
115 lock_type,
116 lock_flav);
117 TALLOC_FREE(br_lck);
118 }
119 } else {
120 struct byte_range_lock *br_lck = brl_get_locks_readonly(NULL, fsp);
121 if (!br_lck) {
122 return False;
123 }
124 ret = !brl_locktest(br_lck,
125 smbpid,
126 procid_self(),
127 offset,
128 count,
129 lock_type,
130 lock_flav);
131 TALLOC_FREE(br_lck);
132 }
133
134 DEBUG(10,("is_locked: flavour = %s brl start=%.0f len=%.0f %s for fnum %d file %s\n",
135 lock_flav_name(lock_flav),
136 (double)offset, (double)count, ret ? "locked" : "unlocked",
137 fsp->fnum, fsp->fsp_name ));
138
139 return ret;
140}
141
142/****************************************************************************
143 Find out if a lock could be granted - return who is blocking us if we can't.
144****************************************************************************/
145
146NTSTATUS query_lock(files_struct *fsp,
147 uint32 *psmbpid,
148 SMB_BIG_UINT *pcount,
149 SMB_BIG_UINT *poffset,
150 enum brl_type *plock_type,
151 enum brl_flavour lock_flav)
152{
153 struct byte_range_lock *br_lck = NULL;
154 NTSTATUS status = NT_STATUS_LOCK_NOT_GRANTED;
155
156 if (!fsp->can_lock) {
157 return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
158 }
159
160 if (!lp_locking(fsp->conn->params)) {
161 return NT_STATUS_OK;
162 }
163
164 br_lck = brl_get_locks_readonly(NULL, fsp);
165 if (!br_lck) {
166 return NT_STATUS_NO_MEMORY;
167 }
168
169 status = brl_lockquery(br_lck,
170 psmbpid,
171 procid_self(),
172 poffset,
173 pcount,
174 plock_type,
175 lock_flav);
176
177 TALLOC_FREE(br_lck);
178 return status;
179}
180
181/****************************************************************************
182 Utility function called by locking requests.
183****************************************************************************/
184
185struct byte_range_lock *do_lock(files_struct *fsp,
186 uint32 lock_pid,
187 SMB_BIG_UINT count,
188 SMB_BIG_UINT offset,
189 enum brl_type lock_type,
190 enum brl_flavour lock_flav,
191 BOOL blocking_lock,
192 NTSTATUS *perr,
193 uint32 *plock_pid)
194{
195 struct byte_range_lock *br_lck = NULL;
196
197 if (!fsp->can_lock) {
198 *perr = fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
199 return NULL;
200 }
201
202 if (!lp_locking(fsp->conn->params)) {
203 *perr = NT_STATUS_OK;
204 return NULL;
205 }
206
207 /* NOTE! 0 byte long ranges ARE allowed and should be stored */
208
209 DEBUG(10,("do_lock: lock flavour %s lock type %s start=%.0f len=%.0f requested for fnum %d file %s\n",
210 lock_flav_name(lock_flav), lock_type_name(lock_type),
211 (double)offset, (double)count, fsp->fnum, fsp->fsp_name ));
212
213 br_lck = brl_get_locks(NULL, fsp);
214 if (!br_lck) {
215 *perr = NT_STATUS_NO_MEMORY;
216 return NULL;
217 }
218
219 *perr = brl_lock(br_lck,
220 lock_pid,
221 procid_self(),
222 offset,
223 count,
224 lock_type,
225 lock_flav,
226 blocking_lock,
227 plock_pid);
228
229 if (lock_flav == WINDOWS_LOCK &&
230 fsp->current_lock_count != NO_LOCKING_COUNT) {
231 /* blocking ie. pending, locks also count here,
232 * as this is an efficiency counter to avoid checking
233 * the lock db. on close. JRA. */
234
235 fsp->current_lock_count++;
236 } else {
237 /* Notice that this has had a POSIX lock request.
238 * We can't count locks after this so forget them.
239 */
240 fsp->current_lock_count = NO_LOCKING_COUNT;
241 }
242
243 return br_lck;
244}
245
246/****************************************************************************
247 Utility function called by unlocking requests.
248****************************************************************************/
249
250NTSTATUS do_unlock(files_struct *fsp,
251 uint32 lock_pid,
252 SMB_BIG_UINT count,
253 SMB_BIG_UINT offset,
254 enum brl_flavour lock_flav)
255{
256 BOOL ok = False;
257 struct byte_range_lock *br_lck = NULL;
258
259 if (!fsp->can_lock) {
260 return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
261 }
262
263 if (!lp_locking(fsp->conn->params)) {
264 return NT_STATUS_OK;
265 }
266
267 DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for fnum %d file %s\n",
268 (double)offset, (double)count, fsp->fnum, fsp->fsp_name ));
269
270 br_lck = brl_get_locks(NULL, fsp);
271 if (!br_lck) {
272 return NT_STATUS_NO_MEMORY;
273 }
274
275 ok = brl_unlock(br_lck,
276 lock_pid,
277 procid_self(),
278 offset,
279 count,
280 lock_flav);
281
282 TALLOC_FREE(br_lck);
283
284 if (!ok) {
285 DEBUG(10,("do_unlock: returning ERRlock.\n" ));
286 return NT_STATUS_RANGE_NOT_LOCKED;
287 }
288
289 if (lock_flav == WINDOWS_LOCK &&
290 fsp->current_lock_count != NO_LOCKING_COUNT) {
291 SMB_ASSERT(fsp->current_lock_count > 0);
292 fsp->current_lock_count--;
293 }
294
295 return NT_STATUS_OK;
296}
297
298/****************************************************************************
299 Cancel any pending blocked locks.
300****************************************************************************/
301
302NTSTATUS do_lock_cancel(files_struct *fsp,
303 uint32 lock_pid,
304 SMB_BIG_UINT count,
305 SMB_BIG_UINT offset,
306 enum brl_flavour lock_flav)
307{
308 BOOL ok = False;
309 struct byte_range_lock *br_lck = NULL;
310
311 if (!fsp->can_lock) {
312 return fsp->is_directory ?
313 NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
314 }
315
316 if (!lp_locking(fsp->conn->params)) {
317 return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
318 }
319
320 DEBUG(10,("do_lock_cancel: cancel start=%.0f len=%.0f requested for fnum %d file %s\n",
321 (double)offset, (double)count, fsp->fnum, fsp->fsp_name ));
322
323 br_lck = brl_get_locks(NULL, fsp);
324 if (!br_lck) {
325 return NT_STATUS_NO_MEMORY;
326 }
327
328 ok = brl_lock_cancel(br_lck,
329 lock_pid,
330 procid_self(),
331 offset,
332 count,
333 lock_flav);
334
335 TALLOC_FREE(br_lck);
336
337 if (!ok) {
338 DEBUG(10,("do_lock_cancel: returning ERRcancelviolation.\n" ));
339 return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
340 }
341
342 if (lock_flav == WINDOWS_LOCK &&
343 fsp->current_lock_count != NO_LOCKING_COUNT) {
344 SMB_ASSERT(fsp->current_lock_count > 0);
345 fsp->current_lock_count--;
346 }
347
348 return NT_STATUS_OK;
349}
350
351/****************************************************************************
352 Remove any locks on this fd. Called from file_close().
353****************************************************************************/
354
355void locking_close_file(files_struct *fsp)
356{
357 struct byte_range_lock *br_lck;
358
359 if (!lp_locking(fsp->conn->params)) {
360 return;
361 }
362
363 /* If we have not outstanding locks or pending
364 * locks then we don't need to look in the lock db.
365 */
366
367 if (fsp->current_lock_count == 0) {
368 return;
369 }
370
371 br_lck = brl_get_locks(NULL,fsp);
372
373 if (br_lck) {
374 cancel_pending_lock_requests_by_fid(fsp, br_lck);
375 brl_close_fnum(br_lck);
376 TALLOC_FREE(br_lck);
377 }
378}
379
380/****************************************************************************
381 Initialise the locking functions.
382****************************************************************************/
383
384static int open_read_only;
385
386BOOL locking_init(int read_only)
387{
388 brl_init(read_only);
389
390 if (tdb)
391 return True;
392
393 tdb = tdb_open_log(lock_path("locking.tdb"),
394 lp_open_files_db_hash_size(),
395 TDB_DEFAULT|(read_only?0x0:TDB_CLEAR_IF_FIRST),
396 read_only?O_RDONLY:O_RDWR|O_CREAT,
397 0644);
398
399 if (!tdb) {
400 DEBUG(0,("ERROR: Failed to initialise locking database\n"));
401 return False;
402 }
403
404 /* Activate the per-hashchain freelist */
405 tdb_set_max_dead(tdb, 5);
406
407 if (!posix_locking_init(read_only))
408 return False;
409
410 open_read_only = read_only;
411
412 return True;
413}
414
415/*******************************************************************
416 Deinitialize the share_mode management.
417******************************************************************/
418
419BOOL locking_end(void)
420{
421 BOOL ret = True;
422
423 brl_shutdown(open_read_only);
424 if (tdb) {
425 if (tdb_close(tdb) != 0)
426 ret = False;
427 }
428
429 return ret;
430}
431
432/*******************************************************************
433 Form a static locking key for a dev/inode pair.
434******************************************************************/
435
436/* key and data records in the tdb locking database */
437struct locking_key {
438 SMB_DEV_T dev;
439 SMB_INO_T ino;
440};
441
442/*******************************************************************
443 Form a static locking key for a dev/inode pair.
444******************************************************************/
445
446static TDB_DATA locking_key(SMB_DEV_T dev, SMB_INO_T inode)
447{
448 static struct locking_key key;
449 TDB_DATA kbuf;
450
451 memset(&key, '\0', sizeof(key));
452 key.dev = dev;
453 key.ino = inode;
454 kbuf.dptr = (char *)&key;
455 kbuf.dsize = sizeof(key);
456 return kbuf;
457}
458
459/*******************************************************************
460 Print out a share mode.
461********************************************************************/
462
463char *share_mode_str(int num, struct share_mode_entry *e)
464{
465 static pstring share_str;
466
467 slprintf(share_str, sizeof(share_str)-1, "share_mode_entry[%d]: %s "
468 "pid = %s, share_access = 0x%x, private_options = 0x%x, "
469 "access_mask = 0x%x, mid = 0x%x, type= 0x%x, file_id = %lu, "
470 "uid = %u, flags = %u, dev = 0x%x, inode = %.0f",
471 num,
472 e->op_type == UNUSED_SHARE_MODE_ENTRY ? "UNUSED" : "",
473 procid_str_static(&e->pid),
474 e->share_access, e->private_options,
475 e->access_mask, e->op_mid, e->op_type, e->share_file_id,
476 (unsigned int)e->uid, (unsigned int)e->flags,
477 (unsigned int)e->dev, (double)e->inode );
478
479 return share_str;
480}
481
482/*******************************************************************
483 Print out a share mode table.
484********************************************************************/
485
486static void print_share_mode_table(struct locking_data *data)
487{
488 int num_share_modes = data->u.s.num_share_mode_entries;
489 struct share_mode_entry *shares =
490 (struct share_mode_entry *)(data + 1);
491 int i;
492
493 for (i = 0; i < num_share_modes; i++) {
494 struct share_mode_entry entry;
495
496 memcpy(&entry, &shares[i], sizeof(struct share_mode_entry));
497 DEBUG(10,("print_share_mode_table: %s\n",
498 share_mode_str(i, &entry)));
499 }
500}
501
502/*******************************************************************
503 Get all share mode entries for a dev/inode pair.
504********************************************************************/
505
506static BOOL parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck)
507{
508 struct locking_data *data;
509 int i;
510
511 if (dbuf.dsize < sizeof(struct locking_data)) {
512 smb_panic("PANIC: parse_share_modes: buffer too short.\n");
513 }
514
515 data = (struct locking_data *)dbuf.dptr;
516
517 lck->delete_on_close = data->u.s.delete_on_close;
518 lck->num_share_modes = data->u.s.num_share_mode_entries;
519
520 DEBUG(10, ("parse_share_modes: delete_on_close: %d, "
521 "num_share_modes: %d\n",
522 lck->delete_on_close,
523 lck->num_share_modes));
524
525 if ((lck->num_share_modes < 0) || (lck->num_share_modes > 1000000)) {
526 DEBUG(0, ("invalid number of share modes: %d\n",
527 lck->num_share_modes));
528 smb_panic("PANIC: invalid number of share modes");
529 }
530
531 lck->share_modes = NULL;
532
533 if (lck->num_share_modes != 0) {
534
535 if (dbuf.dsize < (sizeof(struct locking_data) +
536 (lck->num_share_modes *
537 sizeof(struct share_mode_entry)))) {
538 smb_panic("PANIC: parse_share_modes: buffer too short.\n");
539 }
540
541 lck->share_modes = (struct share_mode_entry *)
542 TALLOC_MEMDUP(lck, dbuf.dptr+sizeof(*data),
543 lck->num_share_modes *
544 sizeof(struct share_mode_entry));
545
546 if (lck->share_modes == NULL) {
547 smb_panic("talloc failed\n");
548 }
549 }
550
551 /* Get any delete token. */
552 if (data->u.s.delete_token_size) {
553 char *p = dbuf.dptr + sizeof(*data) +
554 (lck->num_share_modes *
555 sizeof(struct share_mode_entry));
556
557 if ((data->u.s.delete_token_size < sizeof(uid_t) + sizeof(gid_t)) ||
558 ((data->u.s.delete_token_size - sizeof(uid_t)) % sizeof(gid_t)) != 0) {
559 DEBUG(0, ("parse_share_modes: invalid token size %d\n",
560 data->u.s.delete_token_size));
561 smb_panic("parse_share_modes: invalid token size\n");
562 }
563
564 lck->delete_token = TALLOC_P(lck, UNIX_USER_TOKEN);
565 if (!lck->delete_token) {
566 smb_panic("talloc failed\n");
567 }
568
569 /* Copy out the uid and gid. */
570 memcpy(&lck->delete_token->uid, p, sizeof(uid_t));
571 p += sizeof(uid_t);
572 memcpy(&lck->delete_token->gid, p, sizeof(gid_t));
573 p += sizeof(gid_t);
574
575 /* Any supplementary groups ? */
576 lck->delete_token->ngroups = (data->u.s.delete_token_size > (sizeof(uid_t) + sizeof(gid_t))) ?
577 ((data->u.s.delete_token_size -
578 (sizeof(uid_t) + sizeof(gid_t)))/sizeof(gid_t)) : 0;
579
580 if (lck->delete_token->ngroups) {
581 /* Make this a talloc child of lck->delete_token. */
582 lck->delete_token->groups = TALLOC_ARRAY(lck->delete_token, gid_t,
583 lck->delete_token->ngroups);
584 if (!lck->delete_token) {
585 smb_panic("talloc failed\n");
586 }
587
588 for (i = 0; i < lck->delete_token->ngroups; i++) {
589 memcpy(&lck->delete_token->groups[i], p, sizeof(gid_t));
590 p += sizeof(gid_t);
591 }
592 }
593
594 } else {
595 lck->delete_token = NULL;
596 }
597
598 /* Save off the associated service path and filename. */
599 lck->servicepath = talloc_strdup(lck, dbuf.dptr + sizeof(*data) +
600 (lck->num_share_modes *
601 sizeof(struct share_mode_entry)) +
602 data->u.s.delete_token_size );
603 if (lck->servicepath == NULL) {
604 smb_panic("talloc_strdup failed\n");
605 }
606
607 lck->filename = talloc_strdup(lck, dbuf.dptr + sizeof(*data) +
608 (lck->num_share_modes *
609 sizeof(struct share_mode_entry)) +
610 data->u.s.delete_token_size +
611 strlen(lck->servicepath) + 1 );
612 if (lck->filename == NULL) {
613 smb_panic("talloc_strdup failed\n");
614 }
615
616 /*
617 * Ensure that each entry has a real process attached.
618 */
619
620 for (i = 0; i < lck->num_share_modes; i++) {
621 struct share_mode_entry *entry_p = &lck->share_modes[i];
622 DEBUG(10,("parse_share_modes: %s\n",
623 share_mode_str(i, entry_p) ));
624 if (!process_exists(entry_p->pid)) {
625 DEBUG(10,("parse_share_modes: deleted %s\n",
626 share_mode_str(i, entry_p) ));
627 entry_p->op_type = UNUSED_SHARE_MODE_ENTRY;
628 lck->modified = True;
629 }
630 }
631
632 return True;
633}
634
635static TDB_DATA unparse_share_modes(struct share_mode_lock *lck)
636{
637 TDB_DATA result;
638 int num_valid = 0;
639 int i;
640 struct locking_data *data;
641 ssize_t offset;
642 ssize_t sp_len;
643 uint32 delete_token_size;
644
645 result.dptr = NULL;
646 result.dsize = 0;
647
648 for (i=0; i<lck->num_share_modes; i++) {
649 if (!is_unused_share_mode_entry(&lck->share_modes[i])) {
650 num_valid += 1;
651 }
652 }
653
654 if (num_valid == 0) {
655 return result;
656 }
657
658 sp_len = strlen(lck->servicepath);
659 delete_token_size = (lck->delete_token ?
660 (sizeof(uid_t) + sizeof(gid_t) + (lck->delete_token->ngroups*sizeof(gid_t))) : 0);
661
662 result.dsize = sizeof(*data) +
663 lck->num_share_modes * sizeof(struct share_mode_entry) +
664 delete_token_size +
665 sp_len + 1 +
666 strlen(lck->filename) + 1;
667 result.dptr = TALLOC_ARRAY(lck, char, result.dsize);
668
669 if (result.dptr == NULL) {
670 smb_panic("talloc failed\n");
671 }
672
673 data = (struct locking_data *)result.dptr;
674 ZERO_STRUCTP(data);
675 data->u.s.num_share_mode_entries = lck->num_share_modes;
676 data->u.s.delete_on_close = lck->delete_on_close;
677 data->u.s.delete_token_size = delete_token_size;
678 DEBUG(10, ("unparse_share_modes: del: %d, tok = %u, num: %d\n",
679 data->u.s.delete_on_close,
680 (unsigned int)data->u.s.delete_token_size,
681 data->u.s.num_share_mode_entries));
682 memcpy(result.dptr + sizeof(*data), lck->share_modes,
683 sizeof(struct share_mode_entry)*lck->num_share_modes);
684 offset = sizeof(*data) +
685 sizeof(struct share_mode_entry)*lck->num_share_modes;
686
687 /* Store any delete on close token. */
688 if (lck->delete_token) {
689 char *p = result.dptr + offset;
690
691 memcpy(p, &lck->delete_token->uid, sizeof(uid_t));
692 p += sizeof(uid_t);
693
694 memcpy(p, &lck->delete_token->gid, sizeof(gid_t));
695 p += sizeof(gid_t);
696
697 for (i = 0; i < lck->delete_token->ngroups; i++) {
698 memcpy(p, &lck->delete_token->groups[i], sizeof(gid_t));
699 p += sizeof(gid_t);
700 }
701 offset = p - result.dptr;
702 }
703
704 safe_strcpy(result.dptr + offset, lck->servicepath,
705 result.dsize - offset - 1);
706 offset += sp_len + 1;
707 safe_strcpy(result.dptr + offset, lck->filename,
708 result.dsize - offset - 1);
709
710 if (DEBUGLEVEL >= 10) {
711 print_share_mode_table(data);
712 }
713
714 return result;
715}
716
717static int share_mode_lock_destructor(struct share_mode_lock *lck)
718{
719 TDB_DATA key = locking_key(lck->dev, lck->ino);
720 TDB_DATA data;
721
722 if (!lck->modified) {
723 goto done;
724 }
725
726 data = unparse_share_modes(lck);
727
728 if (data.dptr == NULL) {
729 if (!lck->fresh) {
730 /* There has been an entry before, delete it */
731 if (tdb_delete(tdb, key) == -1) {
732 smb_panic("Could not delete share entry\n");
733 }
734 }
735 goto done;
736 }
737
738 if (tdb_store(tdb, key, data, TDB_REPLACE) == -1) {
739 smb_panic("Could not store share mode entry\n");
740 }
741
742 done:
743 tdb_chainunlock(tdb, key);
744
745 return 0;
746}
747
748struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
749 SMB_DEV_T dev, SMB_INO_T ino,
750 const char *servicepath,
751 const char *fname)
752{
753 struct share_mode_lock *lck;
754 TDB_DATA key = locking_key(dev, ino);
755 TDB_DATA data;
756
757 lck = TALLOC_P(mem_ctx, struct share_mode_lock);
758 if (lck == NULL) {
759 DEBUG(0, ("talloc failed\n"));
760 return NULL;
761 }
762
763 /* Ensure we set every field here as the destructor must be
764 valid even if parse_share_modes fails. */
765
766 lck->servicepath = NULL;
767 lck->filename = NULL;
768 lck->dev = dev;
769 lck->ino = ino;
770 lck->num_share_modes = 0;
771 lck->share_modes = NULL;
772 lck->delete_token = NULL;
773 lck->delete_on_close = False;
774 lck->fresh = False;
775 lck->modified = False;
776
777 if (tdb_chainlock(tdb, key) != 0) {
778 DEBUG(3, ("Could not lock share entry\n"));
779 TALLOC_FREE(lck);
780 return NULL;
781 }
782
783 /* We must set the destructor immediately after the chainlock
784 ensure the lock is cleaned up on any of the error return
785 paths below. */
786
787 talloc_set_destructor(lck, share_mode_lock_destructor);
788
789 data = tdb_fetch(tdb, key);
790 lck->fresh = (data.dptr == NULL);
791
792 if (lck->fresh) {
793
794 if (fname == NULL || servicepath == NULL) {
795 TALLOC_FREE(lck);
796 return NULL;
797 }
798 lck->filename = talloc_strdup(lck, fname);
799 lck->servicepath = talloc_strdup(lck, servicepath);
800 if (lck->filename == NULL || lck->servicepath == NULL) {
801 DEBUG(0, ("talloc failed\n"));
802 TALLOC_FREE(lck);
803 return NULL;
804 }
805 } else {
806 if (!parse_share_modes(data, lck)) {
807 DEBUG(0, ("Could not parse share modes\n"));
808 TALLOC_FREE(lck);
809 SAFE_FREE(data.dptr);
810 return NULL;
811 }
812 }
813
814 SAFE_FREE(data.dptr);
815
816 return lck;
817}
818
819/*******************************************************************
820 Sets the service name and filename for rename.
821 At this point we emit "file renamed" messages to all
822 process id's that have this file open.
823 Based on an initial code idea from SATOH Fumiyasu <fumiya@samba.gr.jp>
824********************************************************************/
825
826BOOL rename_share_filename(struct share_mode_lock *lck,
827 const char *servicepath,
828 const char *newname)
829{
830 size_t sp_len;
831 size_t fn_len;
832 size_t msg_len;
833 char *frm = NULL;
834 int i;
835
836 if (!lck) {
837 return False;
838 }
839
840 DEBUG(10, ("rename_share_filename: servicepath %s newname %s\n",
841 servicepath, newname));
842
843 /*
844 * rename_internal_fsp() and rename_internals() add './' to
845 * head of newname if newname does not contain a '/'.
846 */
847 while (newname[0] && newname[1] && newname[0] == '.' && newname[1] == '/') {
848 newname += 2;
849 }
850
851 lck->servicepath = talloc_strdup(lck, servicepath);
852 lck->filename = talloc_strdup(lck, newname);
853 if (lck->filename == NULL || lck->servicepath == NULL) {
854 DEBUG(0, ("rename_share_filename: talloc failed\n"));
855 return False;
856 }
857 lck->modified = True;
858
859 sp_len = strlen(lck->servicepath);
860 fn_len = strlen(lck->filename);
861
862 msg_len = MSG_FILE_RENAMED_MIN_SIZE + sp_len + 1 + fn_len + 1;
863
864 /* Set up the name changed message. */
865 frm = TALLOC_ARRAY(lck, char, msg_len);
866 if (!frm) {
867 return False;
868 }
869
870 SDEV_T_VAL(frm,0,lck->dev);
871 SINO_T_VAL(frm,8,lck->ino);
872
873 DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len ));
874
875 safe_strcpy(&frm[16], lck->servicepath, sp_len);
876 safe_strcpy(&frm[16 + sp_len + 1], lck->filename, fn_len);
877
878 /* Send the messages. */
879 for (i=0; i<lck->num_share_modes; i++) {
880 struct share_mode_entry *se = &lck->share_modes[i];
881 if (!is_valid_share_mode_entry(se)) {
882 continue;
883 }
884 /* But not to ourselves... */
885 if (procid_is_me(&se->pid)) {
886 continue;
887 }
888
889 DEBUG(10,("rename_share_filename: sending rename message to pid %s "
890 "dev %x, inode %.0f sharepath %s newname %s\n",
891 procid_str_static(&se->pid),
892 (unsigned int)lck->dev, (double)lck->ino,
893 lck->servicepath, lck->filename ));
894
895 message_send_pid(se->pid, MSG_SMB_FILE_RENAME,
896 frm, msg_len, True);
897 }
898
899 return True;
900}
901
902static int pull_delete_on_close_flag(TDB_DATA key, TDB_DATA dbuf,
903 void *private_data)
904{
905 BOOL *result = (BOOL *)private_data;
906 struct locking_data *data;
907
908 if (dbuf.dsize < sizeof(struct locking_data)) {
909 smb_panic("PANIC: parse_share_modes: buffer too short.\n");
910 }
911
912 data = (struct locking_data *)dbuf.dptr;
913
914 *result = data->u.s.delete_on_close;
915 return 0;
916}
917
918BOOL get_delete_on_close_flag(SMB_DEV_T dev, SMB_INO_T inode)
919{
920 TDB_DATA key = locking_key(dev, inode);
921 BOOL result = False;
922
923 tdb_parse_record(tdb, key, pull_delete_on_close_flag,
924 (void *)&result);
925 return result;
926}
927
928BOOL is_valid_share_mode_entry(const struct share_mode_entry *e)
929{
930 int num_props = 0;
931
932 if (e->op_type == UNUSED_SHARE_MODE_ENTRY) {
933 /* cope with dead entries from the process not
934 existing. These should not be considered valid,
935 otherwise we end up doing zero timeout sharing
936 violation */
937 return False;
938 }
939
940 num_props += ((e->op_type == NO_OPLOCK) ? 1 : 0);
941 num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0);
942 num_props += (LEVEL_II_OPLOCK_TYPE(e->op_type) ? 1 : 0);
943
944 SMB_ASSERT(num_props <= 1);
945 return (num_props != 0);
946}
947
948BOOL is_deferred_open_entry(const struct share_mode_entry *e)
949{
950 return (e->op_type == DEFERRED_OPEN_ENTRY);
951}
952
953BOOL is_unused_share_mode_entry(const struct share_mode_entry *e)
954{
955 return (e->op_type == UNUSED_SHARE_MODE_ENTRY);
956}
957
958/*******************************************************************
959 Fill a share mode entry.
960********************************************************************/
961
962static void fill_share_mode_entry(struct share_mode_entry *e,
963 files_struct *fsp,
964 uid_t uid, uint16 mid, uint16 op_type)
965{
966 ZERO_STRUCTP(e);
967 e->pid = procid_self();
968 e->share_access = fsp->share_access;
969 e->private_options = fsp->fh->private_options;
970 e->access_mask = fsp->access_mask;
971 e->op_mid = mid;
972 e->op_type = op_type;
973 e->time.tv_sec = fsp->open_time.tv_sec;
974 e->time.tv_usec = fsp->open_time.tv_usec;
975 e->dev = fsp->dev;
976 e->inode = fsp->inode;
977 e->share_file_id = fsp->fh->file_id;
978 e->uid = (uint32)uid;
979 e->flags = fsp->posix_open ? SHARE_MODE_FLAG_POSIX_OPEN : 0;
980}
981
982static void fill_deferred_open_entry(struct share_mode_entry *e,
983 const struct timeval request_time,
984 SMB_DEV_T dev, SMB_INO_T ino, uint16 mid)
985{
986 ZERO_STRUCTP(e);
987 e->pid = procid_self();
988 e->op_mid = mid;
989 e->op_type = DEFERRED_OPEN_ENTRY;
990 e->time.tv_sec = request_time.tv_sec;
991 e->time.tv_usec = request_time.tv_usec;
992 e->dev = dev;
993 e->inode = ino;
994 e->uid = (uint32)-1;
995 e->flags = 0;
996}
997
998static void add_share_mode_entry(struct share_mode_lock *lck,
999 const struct share_mode_entry *entry)
1000{
1001 int i;
1002
1003 for (i=0; i<lck->num_share_modes; i++) {
1004 struct share_mode_entry *e = &lck->share_modes[i];
1005 if (is_unused_share_mode_entry(e)) {
1006 *e = *entry;
1007 break;
1008 }
1009 }
1010
1011 if (i == lck->num_share_modes) {
1012 /* No unused entry found */
1013 ADD_TO_ARRAY(lck, struct share_mode_entry, *entry,
1014 &lck->share_modes, &lck->num_share_modes);
1015 }
1016 lck->modified = True;
1017}
1018
1019void set_share_mode(struct share_mode_lock *lck, files_struct *fsp,
1020 uid_t uid, uint16 mid, uint16 op_type, BOOL initial_delete_on_close_allowed)
1021{
1022 struct share_mode_entry entry;
1023 fill_share_mode_entry(&entry, fsp, uid, mid, op_type);
1024 if (initial_delete_on_close_allowed) {
1025 entry.flags |= SHARE_MODE_ALLOW_INITIAL_DELETE_ON_CLOSE;
1026 }
1027 add_share_mode_entry(lck, &entry);
1028}
1029
1030void add_deferred_open(struct share_mode_lock *lck, uint16 mid,
1031 struct timeval request_time,
1032 SMB_DEV_T dev, SMB_INO_T ino)
1033{
1034 struct share_mode_entry entry;
1035 fill_deferred_open_entry(&entry, request_time, dev, ino, mid);
1036 add_share_mode_entry(lck, &entry);
1037}
1038
1039/*******************************************************************
1040 Check if two share mode entries are identical, ignoring oplock
1041 and mid info and desired_access. (Removed paranoia test - it's
1042 not automatically a logic error if they are identical. JRA.)
1043********************************************************************/
1044
1045static BOOL share_modes_identical(struct share_mode_entry *e1,
1046 struct share_mode_entry *e2)
1047{
1048 /* We used to check for e1->share_access == e2->share_access here
1049 as well as the other fields but 2 different DOS or FCB opens
1050 sharing the same share mode entry may validly differ in
1051 fsp->share_access field. */
1052
1053 return (procid_equal(&e1->pid, &e2->pid) &&
1054 e1->dev == e2->dev &&
1055 e1->inode == e2->inode &&
1056 e1->share_file_id == e2->share_file_id );
1057}
1058
1059static BOOL deferred_open_identical(struct share_mode_entry *e1,
1060 struct share_mode_entry *e2)
1061{
1062 return (procid_equal(&e1->pid, &e2->pid) &&
1063 (e1->op_mid == e2->op_mid) &&
1064 (e1->dev == e2->dev) &&
1065 (e1->inode == e2->inode));
1066}
1067
1068static struct share_mode_entry *find_share_mode_entry(struct share_mode_lock *lck,
1069 struct share_mode_entry *entry)
1070{
1071 int i;
1072
1073 for (i=0; i<lck->num_share_modes; i++) {
1074 struct share_mode_entry *e = &lck->share_modes[i];
1075 if (is_valid_share_mode_entry(entry) &&
1076 is_valid_share_mode_entry(e) &&
1077 share_modes_identical(e, entry)) {
1078 return e;
1079 }
1080 if (is_deferred_open_entry(entry) &&
1081 is_deferred_open_entry(e) &&
1082 deferred_open_identical(e, entry)) {
1083 return e;
1084 }
1085 }
1086 return NULL;
1087}
1088
1089/*******************************************************************
1090 Del the share mode of a file for this process. Return the number of
1091 entries left.
1092********************************************************************/
1093
1094BOOL del_share_mode(struct share_mode_lock *lck, files_struct *fsp)
1095{
1096 struct share_mode_entry entry, *e;
1097
1098 /* Don't care about the pid owner being correct here - just a search. */
1099 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1100
1101 e = find_share_mode_entry(lck, &entry);
1102 if (e == NULL) {
1103 return False;
1104 }
1105
1106 e->op_type = UNUSED_SHARE_MODE_ENTRY;
1107 lck->modified = True;
1108 return True;
1109}
1110
1111void del_deferred_open_entry(struct share_mode_lock *lck, uint16 mid)
1112{
1113 struct share_mode_entry entry, *e;
1114
1115 fill_deferred_open_entry(&entry, timeval_zero(),
1116 lck->dev, lck->ino, mid);
1117
1118 e = find_share_mode_entry(lck, &entry);
1119 if (e == NULL) {
1120 return;
1121 }
1122
1123 e->op_type = UNUSED_SHARE_MODE_ENTRY;
1124 lck->modified = True;
1125}
1126
1127/*******************************************************************
1128 Remove an oplock mid and mode entry from a share mode.
1129********************************************************************/
1130
1131BOOL remove_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
1132{
1133 struct share_mode_entry entry, *e;
1134
1135 /* Don't care about the pid owner being correct here - just a search. */
1136 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1137
1138 e = find_share_mode_entry(lck, &entry);
1139 if (e == NULL) {
1140 return False;
1141 }
1142
1143 e->op_mid = 0;
1144 e->op_type = NO_OPLOCK;
1145 lck->modified = True;
1146 return True;
1147}
1148
1149/*******************************************************************
1150 Downgrade a oplock type from exclusive to level II.
1151********************************************************************/
1152
1153BOOL downgrade_share_oplock(struct share_mode_lock *lck, files_struct *fsp)
1154{
1155 struct share_mode_entry entry, *e;
1156
1157 /* Don't care about the pid owner being correct here - just a search. */
1158 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1159
1160 e = find_share_mode_entry(lck, &entry);
1161 if (e == NULL) {
1162 return False;
1163 }
1164
1165 e->op_type = LEVEL_II_OPLOCK;
1166 lck->modified = True;
1167 return True;
1168}
1169
1170/****************************************************************************
1171 Deal with the internal needs of setting the delete on close flag. Note that
1172 as the tdb locking is recursive, it is safe to call this from within
1173 open_file_ntcreate. JRA.
1174****************************************************************************/
1175
1176NTSTATUS can_set_delete_on_close(files_struct *fsp, BOOL delete_on_close,
1177 uint32 dosmode)
1178{
1179 if (!delete_on_close) {
1180 return NT_STATUS_OK;
1181 }
1182
1183 /*
1184 * Only allow delete on close for writable files.
1185 */
1186
1187 if ((dosmode & aRONLY) &&
1188 !lp_delete_readonly(SNUM(fsp->conn))) {
1189 DEBUG(10,("can_set_delete_on_close: file %s delete on close "
1190 "flag set but file attribute is readonly.\n",
1191 fsp->fsp_name ));
1192 return NT_STATUS_CANNOT_DELETE;
1193 }
1194
1195 /*
1196 * Only allow delete on close for writable shares.
1197 */
1198
1199 if (!CAN_WRITE(fsp->conn)) {
1200 DEBUG(10,("can_set_delete_on_close: file %s delete on "
1201 "close flag set but write access denied on share.\n",
1202 fsp->fsp_name ));
1203 return NT_STATUS_ACCESS_DENIED;
1204 }
1205
1206 /*
1207 * Only allow delete on close for files/directories opened with delete
1208 * intent.
1209 */
1210
1211 if (!(fsp->access_mask & DELETE_ACCESS)) {
1212 DEBUG(10,("can_set_delete_on_close: file %s delete on "
1213 "close flag set but delete access denied.\n",
1214 fsp->fsp_name ));
1215 return NT_STATUS_ACCESS_DENIED;
1216 }
1217
1218 /* Don't allow delete on close for non-empty directories. */
1219 if (fsp->is_directory) {
1220 return can_delete_directory(fsp->conn, fsp->fsp_name);
1221 }
1222
1223 return NT_STATUS_OK;
1224}
1225
1226/****************************************************************************
1227 Do we have an open file handle that created this entry ?
1228****************************************************************************/
1229
1230BOOL can_set_initial_delete_on_close(const struct share_mode_lock *lck)
1231{
1232 int i;
1233
1234 for (i=0; i<lck->num_share_modes; i++) {
1235 if (lck->share_modes[i].flags & SHARE_MODE_ALLOW_INITIAL_DELETE_ON_CLOSE) {
1236 return True;
1237 }
1238 }
1239 return False;
1240}
1241
1242/*************************************************************************
1243 Return a talloced copy of a UNIX_USER_TOKEN. NULL on fail.
1244 (Should this be in locking.c.... ?).
1245*************************************************************************/
1246
1247static UNIX_USER_TOKEN *copy_unix_token(TALLOC_CTX *ctx, UNIX_USER_TOKEN *tok)
1248{
1249 UNIX_USER_TOKEN *cpy;
1250
1251 if (tok == NULL) {
1252 return NULL;
1253 }
1254
1255 cpy = TALLOC_P(ctx, UNIX_USER_TOKEN);
1256 if (!cpy) {
1257 return NULL;
1258 }
1259
1260 cpy->uid = tok->uid;
1261 cpy->gid = tok->gid;
1262 cpy->ngroups = tok->ngroups;
1263 if (tok->ngroups) {
1264 /* Make this a talloc child of cpy. */
1265 cpy->groups = TALLOC_ARRAY(cpy, gid_t, tok->ngroups);
1266 if (!cpy->groups) {
1267 return NULL;
1268 }
1269 memcpy(cpy->groups, tok->groups, tok->ngroups * sizeof(gid_t));
1270 }
1271 return cpy;
1272}
1273
1274/****************************************************************************
1275 Replace the delete on close token.
1276****************************************************************************/
1277
1278void set_delete_on_close_token(struct share_mode_lock *lck, UNIX_USER_TOKEN *tok)
1279{
1280 /* Ensure there's no token. */
1281 if (lck->delete_token) {
1282 TALLOC_FREE(lck->delete_token); /* Also deletes groups... */
1283 lck->delete_token = NULL;
1284 }
1285
1286 /* Copy the new token (can be NULL). */
1287 lck->delete_token = copy_unix_token(lck, tok);
1288 lck->modified = True;
1289}
1290
1291/****************************************************************************
1292 Sets the delete on close flag over all share modes on this file.
1293 Modify the share mode entry for all files open
1294 on this device and inode to tell other smbds we have
1295 changed the delete on close flag. This will be noticed
1296 in the close code, the last closer will delete the file
1297 if flag is set.
1298 This makes a copy of any UNIX_USER_TOKEN into the
1299 lck entry. This function is used when the lock is already granted.
1300****************************************************************************/
1301
1302void set_delete_on_close_lck(struct share_mode_lock *lck, BOOL delete_on_close, UNIX_USER_TOKEN *tok)
1303{
1304 if (lck->delete_on_close != delete_on_close) {
1305 set_delete_on_close_token(lck, tok);
1306 lck->delete_on_close = delete_on_close;
1307 if (delete_on_close) {
1308 SMB_ASSERT(lck->delete_token != NULL);
1309 }
1310 lck->modified = True;
1311 }
1312}
1313
1314BOOL set_delete_on_close(files_struct *fsp, BOOL delete_on_close, UNIX_USER_TOKEN *tok)
1315{
1316 struct share_mode_lock *lck;
1317
1318 DEBUG(10,("set_delete_on_close: %s delete on close flag for "
1319 "fnum = %d, file %s\n",
1320 delete_on_close ? "Adding" : "Removing", fsp->fnum,
1321 fsp->fsp_name ));
1322
1323 if (fsp->is_stat) {
1324 return True;
1325 }
1326
1327 lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL);
1328 if (lck == NULL) {
1329 return False;
1330 }
1331
1332 set_delete_on_close_lck(lck, delete_on_close, tok);
1333
1334 if (fsp->is_directory) {
1335 send_stat_cache_delete_message(fsp->fsp_name);
1336 }
1337
1338 TALLOC_FREE(lck);
1339 return True;
1340}
1341
1342/****************************************************************************
1343 Sets the allow initial delete on close flag for this share mode.
1344****************************************************************************/
1345
1346BOOL set_allow_initial_delete_on_close(struct share_mode_lock *lck, files_struct *fsp, BOOL delete_on_close)
1347{
1348 struct share_mode_entry entry, *e;
1349
1350 /* Don't care about the pid owner being correct here - just a search. */
1351 fill_share_mode_entry(&entry, fsp, (uid_t)-1, 0, NO_OPLOCK);
1352
1353 e = find_share_mode_entry(lck, &entry);
1354 if (e == NULL) {
1355 return False;
1356 }
1357
1358 if (delete_on_close) {
1359 e->flags |= SHARE_MODE_ALLOW_INITIAL_DELETE_ON_CLOSE;
1360 } else {
1361 e->flags &= ~SHARE_MODE_ALLOW_INITIAL_DELETE_ON_CLOSE;
1362 }
1363 lck->modified = True;
1364 return True;
1365}
1366
1367struct forall_state {
1368 void (*fn)(const struct share_mode_entry *entry,
1369 const char *sharepath,
1370 const char *fname,
1371 void *private_data);
1372 void *private_data;
1373};
1374
1375static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf,
1376 void *_state)
1377{
1378 struct forall_state *state = (struct forall_state *)_state;
1379 struct locking_data *data;
1380 struct share_mode_entry *shares;
1381 const char *sharepath;
1382 const char *fname;
1383 int i;
1384
1385 /* Ensure this is a locking_key record. */
1386 if (kbuf.dsize != sizeof(struct locking_key))
1387 return 0;
1388
1389 data = (struct locking_data *)dbuf.dptr;
1390 shares = (struct share_mode_entry *)(dbuf.dptr + sizeof(*data));
1391 sharepath = dbuf.dptr + sizeof(*data) +
1392 data->u.s.num_share_mode_entries*sizeof(*shares) +
1393 data->u.s.delete_token_size;
1394 fname = dbuf.dptr + sizeof(*data) +
1395 data->u.s.num_share_mode_entries*sizeof(*shares) +
1396 data->u.s.delete_token_size +
1397 strlen(sharepath) + 1;
1398
1399 for (i=0;i<data->u.s.num_share_mode_entries;i++) {
1400 state->fn(&shares[i], sharepath, fname,
1401 state->private_data);
1402 }
1403 return 0;
1404}
1405
1406/*******************************************************************
1407 Call the specified function on each entry under management by the
1408 share mode system.
1409********************************************************************/
1410
1411int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *,
1412 const char *, void *),
1413 void *private_data)
1414{
1415 struct forall_state state;
1416
1417 if (tdb == NULL)
1418 return 0;
1419
1420 state.fn = fn;
1421 state.private_data = private_data;
1422
1423 return tdb_traverse(tdb, traverse_fn, (void *)&state);
1424}
Note: See TracBrowser for help on using the repository browser.