source: branches/samba-3.5.x/source3/locking/locking.c@ 821

Last change on this file since 821 was 732, checked in by Silvan Scherrer, 13 years ago

Samba Server 3.5: update branche to 3.5.12

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