source: trunk/server/source3/locking/locking.c@ 988

Last change on this file since 988 was 862, checked in by Silvan Scherrer, 11 years ago

Samba Server: update trunk to 3.6.23

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