source: trunk/samba-3.0.25pre1/source/locking/locking.c@ 1

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

Initial code import

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