2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 2004
5 Copyright (C) Stefan Metzmacher 2008
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 this is the open files database, tdb backend. It implements shared
23 storage of what files are open between server instances, and
24 implements the rules of shared access to files.
26 The caller needs to provide a file_key, which specifies what file
27 they are talking about. This needs to be a unique key across all
28 filesystems, and is usually implemented in terms of a device/inode
31 Before any operations can be performed the caller needs to establish
32 a lock on the record associated with file_key. That is done by
33 calling odb_lock(). The caller releases this lock by calling
34 talloc_free() on the returned handle.
36 All other operations on a record are done by passing the odb_lock()
37 handle back to this module. The handle contains internal
38 information about what file_key is being operated on.
42 #include "system/filesys.h"
43 #include "lib/tdb/include/tdb.h"
44 #include "messaging/messaging.h"
46 #include "lib/messaging/irpc.h"
47 #include "librpc/gen_ndr/ndr_opendb.h"
48 #include "ntvfs/ntvfs.h"
49 #include "ntvfs/common/ntvfs_common.h"
50 #include "cluster/cluster.h"
51 #include "param/param.h"
55 struct ntvfs_context *ntvfs_ctx;
60 an odb lock handle. You must obtain one of these using odb_lock() before doing
64 struct odb_context *odb;
69 Open up the openfiles.tdb database. Close it down using
70 talloc_free(). We need the messaging_ctx to allow for pending open
73 static struct odb_context *odb_tdb_init(TALLOC_CTX *mem_ctx,
74 struct ntvfs_context *ntvfs_ctx)
76 struct odb_context *odb;
78 odb = talloc(mem_ctx, struct odb_context);
83 odb->w = cluster_tdb_tmp_open(odb, ntvfs_ctx->lp_ctx, "openfiles.tdb", TDB_DEFAULT);
89 odb->ntvfs_ctx = ntvfs_ctx;
91 /* leave oplocks disabled by default until the code is working */
92 odb->oplocks = lp_parm_bool(ntvfs_ctx->lp_ctx, NULL, "opendb", "oplocks", false);
98 destroy a lock on the database
100 static int odb_lock_destructor(struct odb_lock *lck)
102 tdb_chainunlock(lck->odb->w->tdb, lck->key);
107 get a lock on a entry in the odb. This call returns a lock handle,
108 which the caller should unlock using talloc_free().
110 static struct odb_lock *odb_tdb_lock(TALLOC_CTX *mem_ctx,
111 struct odb_context *odb, DATA_BLOB *file_key)
113 struct odb_lock *lck;
115 lck = talloc(mem_ctx, struct odb_lock);
120 lck->odb = talloc_reference(lck, odb);
121 lck->key.dptr = talloc_memdup(lck, file_key->data, file_key->length);
122 lck->key.dsize = file_key->length;
123 if (lck->key.dptr == NULL) {
128 if (tdb_chainlock(odb->w->tdb, lck->key) != 0) {
133 talloc_set_destructor(lck, odb_lock_destructor);
138 static DATA_BLOB odb_tdb_get_key(TALLOC_CTX *mem_ctx, struct odb_lock *lck)
140 return data_blob_talloc(mem_ctx, lck->key.dptr, lck->key.dsize);
145 determine if two odb_entry structures conflict
147 return NT_STATUS_OK on no conflict
149 static NTSTATUS share_conflict(struct opendb_entry *e1,
151 uint32_t share_access,
152 uint32_t access_mask)
154 /* if either open involves no read.write or delete access then
156 if (!(e1->access_mask & (SEC_FILE_WRITE_DATA |
157 SEC_FILE_APPEND_DATA |
163 if (!(access_mask & (SEC_FILE_WRITE_DATA |
164 SEC_FILE_APPEND_DATA |
171 /* data IO access masks. This is skipped if the two open handles
172 are on different streams (as in that case the masks don't
174 if (e1->stream_id != stream_id) {
178 #define CHECK_MASK(am, right, sa, share) \
179 if (((am) & (right)) && !((sa) & (share))) return NT_STATUS_SHARING_VIOLATION
181 CHECK_MASK(e1->access_mask, SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA,
182 share_access, NTCREATEX_SHARE_ACCESS_WRITE);
183 CHECK_MASK(access_mask, SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA,
184 e1->share_access, NTCREATEX_SHARE_ACCESS_WRITE);
186 CHECK_MASK(e1->access_mask, SEC_FILE_READ_DATA | SEC_FILE_EXECUTE,
187 share_access, NTCREATEX_SHARE_ACCESS_READ);
188 CHECK_MASK(access_mask, SEC_FILE_READ_DATA | SEC_FILE_EXECUTE,
189 e1->share_access, NTCREATEX_SHARE_ACCESS_READ);
191 CHECK_MASK(e1->access_mask, SEC_STD_DELETE,
192 share_access, NTCREATEX_SHARE_ACCESS_DELETE);
193 CHECK_MASK(access_mask, SEC_STD_DELETE,
194 e1->share_access, NTCREATEX_SHARE_ACCESS_DELETE);
200 pull a record, translating from the db format to the opendb_file structure defined
203 static NTSTATUS odb_pull_record(struct odb_lock *lck, struct opendb_file *file)
205 struct odb_context *odb = lck->odb;
208 enum ndr_err_code ndr_err;
210 dbuf = tdb_fetch(odb->w->tdb, lck->key);
211 if (dbuf.dptr == NULL) {
212 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
215 blob.data = dbuf.dptr;
216 blob.length = dbuf.dsize;
218 ndr_err = ndr_pull_struct_blob(&blob, lck, lp_iconv_convenience(lck->odb->ntvfs_ctx->lp_ctx), file, (ndr_pull_flags_fn_t)ndr_pull_opendb_file);
220 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
221 return ndr_map_error2ntstatus(ndr_err);
228 push a record, translating from the opendb_file structure defined in opendb.idl
230 static NTSTATUS odb_push_record(struct odb_lock *lck, struct opendb_file *file)
232 struct odb_context *odb = lck->odb;
235 enum ndr_err_code ndr_err;
238 if (file->num_entries == 0) {
239 ret = tdb_delete(odb->w->tdb, lck->key);
241 return NT_STATUS_INTERNAL_DB_CORRUPTION;
246 ndr_err = ndr_push_struct_blob(&blob, lck, lp_iconv_convenience(lck->odb->ntvfs_ctx->lp_ctx), file, (ndr_push_flags_fn_t)ndr_push_opendb_file);
247 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
248 return ndr_map_error2ntstatus(ndr_err);
251 dbuf.dptr = blob.data;
252 dbuf.dsize = blob.length;
254 ret = tdb_store(odb->w->tdb, lck->key, dbuf, TDB_REPLACE);
255 data_blob_free(&blob);
257 return NT_STATUS_INTERNAL_DB_CORRUPTION;
264 send an oplock break to a client
266 static NTSTATUS odb_oplock_break_send(struct odb_context *odb,
267 struct opendb_entry *e,
271 struct opendb_oplock_break op_break;
274 ZERO_STRUCT(op_break);
276 /* tell the server handling this open file about the need to send the client
278 op_break.file_handle = e->file_handle;
279 op_break.level = level;
281 blob = data_blob_const(&op_break, sizeof(op_break));
283 status = messaging_send(odb->ntvfs_ctx->msg_ctx, e->server,
284 MSG_NTVFS_OPLOCK_BREAK, &blob);
285 NT_STATUS_NOT_OK_RETURN(status);
290 static bool access_attributes_only(uint32_t access_mask,
291 uint32_t open_disposition,
294 switch (open_disposition) {
295 case NTCREATEX_DISP_SUPERSEDE:
296 case NTCREATEX_DISP_OVERWRITE_IF:
297 case NTCREATEX_DISP_OVERWRITE:
307 #define CHECK_MASK(m,g) ((m) && (((m) & ~(g))==0) && (((m) & (g)) != 0))
308 return CHECK_MASK(access_mask,
309 SEC_STD_SYNCHRONIZE |
310 SEC_FILE_READ_ATTRIBUTE |
311 SEC_FILE_WRITE_ATTRIBUTE);
315 static NTSTATUS odb_tdb_open_can_internal(struct odb_context *odb,
316 const struct opendb_file *file,
317 uint32_t stream_id, uint32_t share_access,
318 uint32_t access_mask, bool delete_on_close,
319 uint32_t open_disposition, bool break_to_none,
324 bool attrs_only = false;
326 /* see if anyone has an oplock, which we need to break */
327 for (i=0;i<file->num_entries;i++) {
328 if (file->entries[i].oplock_level == OPLOCK_BATCH) {
329 bool oplock_return = OPLOCK_BREAK_TO_LEVEL_II;
330 /* if this is an attribute only access
331 * it doesn't conflict with a BACTCH oplock
332 * but we'll not grant the oplock below
334 attrs_only = access_attributes_only(access_mask,
340 /* a batch oplock caches close calls, which
341 means the client application might have
342 already closed the file. We have to allow
343 this close to propogate by sending a oplock
344 break request and suspending this call
345 until the break is acknowledged or the file
348 oplock_return = OPLOCK_BREAK_TO_NONE;
350 odb_oplock_break_send(odb, &file->entries[i],
352 return NT_STATUS_OPLOCK_NOT_GRANTED;
356 if (file->delete_on_close) {
357 /* while delete on close is set, no new opens are allowed */
358 return NT_STATUS_DELETE_PENDING;
361 if (file->num_entries != 0 && delete_on_close) {
362 return NT_STATUS_SHARING_VIOLATION;
365 /* check for sharing violations */
366 for (i=0;i<file->num_entries;i++) {
367 status = share_conflict(&file->entries[i], stream_id,
368 share_access, access_mask);
369 NT_STATUS_NOT_OK_RETURN(status);
372 /* we now know the open could succeed, but we need to check
373 for any exclusive oplocks. We can't grant a second open
374 till these are broken. Note that we check for batch oplocks
375 before checking for sharing violations, and check for
376 exclusive oplocks afterwards. */
377 for (i=0;i<file->num_entries;i++) {
378 if (file->entries[i].oplock_level == OPLOCK_EXCLUSIVE) {
379 bool oplock_return = OPLOCK_BREAK_TO_LEVEL_II;
380 /* if this is an attribute only access
381 * it doesn't conflict with an EXCLUSIVE oplock
382 * but we'll not grant the oplock below
384 attrs_only = access_attributes_only(access_mask,
391 * send an oplock break to the holder of the
392 * oplock and tell caller to retry later
395 oplock_return = OPLOCK_BREAK_TO_NONE;
397 odb_oplock_break_send(odb, &file->entries[i],
399 return NT_STATUS_OPLOCK_NOT_GRANTED;
404 *_attrs_only = attrs_only;
410 register an open file in the open files database. This implements the share_access
413 Note that the path is only used by the delete on close logic, not
414 for comparing with other filenames
416 static NTSTATUS odb_tdb_open_file(struct odb_lock *lck,
417 void *file_handle, const char *path,
418 uint32_t stream_id, uint32_t share_access,
419 uint32_t access_mask, bool delete_on_close,
420 uint32_t open_disposition, bool break_to_none,
421 uint32_t oplock_level, uint32_t *oplock_granted)
423 struct odb_context *odb = lck->odb;
424 struct opendb_entry e;
425 struct opendb_file file;
427 bool attrs_only = false;
429 if (odb->oplocks == false) {
430 oplock_level = OPLOCK_NONE;
433 status = odb_pull_record(lck, &file);
434 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
435 /* initialise a blank structure */
439 NT_STATUS_NOT_OK_RETURN(status);
442 /* see if it conflicts */
443 status = odb_tdb_open_can_internal(odb, &file, stream_id,
444 share_access, access_mask,
445 delete_on_close, open_disposition,
446 break_to_none, &attrs_only);
447 NT_STATUS_NOT_OK_RETURN(status);
449 /* see if it conflicts */
450 e.server = odb->ntvfs_ctx->server_id;
451 e.file_handle = file_handle;
452 e.stream_id = stream_id;
453 e.share_access = share_access;
454 e.access_mask = access_mask;
455 e.delete_on_close = delete_on_close;
456 e.oplock_level = OPLOCK_NONE;
459 possibly grant an exclusive, batch or level2 oplock
461 if (oplock_granted) {
463 e.oplock_level = OPLOCK_NONE;
464 *oplock_granted = NO_OPLOCK_RETURN;
465 } else if (oplock_level == OPLOCK_EXCLUSIVE) {
466 if (file.num_entries == 0) {
467 e.oplock_level = OPLOCK_EXCLUSIVE;
468 *oplock_granted = EXCLUSIVE_OPLOCK_RETURN;
470 e.oplock_level = OPLOCK_LEVEL_II;
471 *oplock_granted = LEVEL_II_OPLOCK_RETURN;
473 } else if (oplock_level == OPLOCK_BATCH) {
474 if (file.num_entries == 0) {
475 e.oplock_level = OPLOCK_BATCH;
476 *oplock_granted = BATCH_OPLOCK_RETURN;
478 e.oplock_level = OPLOCK_LEVEL_II;
479 *oplock_granted = LEVEL_II_OPLOCK_RETURN;
481 } else if (oplock_level == OPLOCK_LEVEL_II) {
482 e.oplock_level = OPLOCK_LEVEL_II;
483 *oplock_granted = LEVEL_II_OPLOCK_RETURN;
485 e.oplock_level = OPLOCK_NONE;
486 *oplock_granted = NO_OPLOCK_RETURN;
490 /* it doesn't conflict, so add it to the end */
491 file.entries = talloc_realloc(lck, file.entries, struct opendb_entry,
493 NT_STATUS_HAVE_NO_MEMORY(file.entries);
495 file.entries[file.num_entries] = e;
498 return odb_push_record(lck, &file);
503 register a pending open file in the open files database
505 static NTSTATUS odb_tdb_open_file_pending(struct odb_lock *lck, void *private)
507 struct odb_context *odb = lck->odb;
508 struct opendb_file file;
511 status = odb_pull_record(lck, &file);
512 NT_STATUS_NOT_OK_RETURN(status);
514 file.pending = talloc_realloc(lck, file.pending, struct opendb_pending,
516 NT_STATUS_HAVE_NO_MEMORY(file.pending);
518 file.pending[file.num_pending].server = odb->ntvfs_ctx->server_id;
519 file.pending[file.num_pending].notify_ptr = private;
523 return odb_push_record(lck, &file);
528 remove a opendb entry
530 static NTSTATUS odb_tdb_close_file(struct odb_lock *lck, void *file_handle,
531 const char **_delete_path)
533 struct odb_context *odb = lck->odb;
534 struct opendb_file file;
535 const char *delete_path = NULL;
539 status = odb_pull_record(lck, &file);
540 NT_STATUS_NOT_OK_RETURN(status);
542 /* find the entry, and delete it */
543 for (i=0;i<file.num_entries;i++) {
544 if (file_handle == file.entries[i].file_handle &&
545 cluster_id_equal(&odb->ntvfs_ctx->server_id, &file.entries[i].server)) {
546 if (file.entries[i].delete_on_close) {
547 file.delete_on_close = true;
549 if (i < file.num_entries-1) {
550 memmove(file.entries+i, file.entries+i+1,
551 (file.num_entries - (i+1)) *
552 sizeof(struct opendb_entry));
558 if (i == file.num_entries) {
559 return NT_STATUS_UNSUCCESSFUL;
562 /* send any pending notifications, removing them once sent */
563 for (i=0;i<file.num_pending;i++) {
564 messaging_send_ptr(odb->ntvfs_ctx->msg_ctx, file.pending[i].server,
566 file.pending[i].notify_ptr);
568 file.num_pending = 0;
572 if (file.num_entries == 0 && file.delete_on_close) {
573 delete_path = talloc_strdup(lck, file.path);
574 NT_STATUS_HAVE_NO_MEMORY(delete_path);
578 *_delete_path = delete_path;
581 return odb_push_record(lck, &file);
585 update the oplock level of the client
587 static NTSTATUS odb_tdb_update_oplock(struct odb_lock *lck, void *file_handle,
588 uint32_t oplock_level)
590 struct odb_context *odb = lck->odb;
591 struct opendb_file file;
595 status = odb_pull_record(lck, &file);
596 NT_STATUS_NOT_OK_RETURN(status);
598 /* find the entry, and update it */
599 for (i=0;i<file.num_entries;i++) {
600 if (file_handle == file.entries[i].file_handle &&
601 cluster_id_equal(&odb->ntvfs_ctx->server_id, &file.entries[i].server)) {
602 file.entries[i].oplock_level = oplock_level;
607 if (i == file.num_entries) {
608 return NT_STATUS_UNSUCCESSFUL;
611 /* send any pending notifications, removing them once sent */
612 for (i=0;i<file.num_pending;i++) {
613 messaging_send_ptr(odb->ntvfs_ctx->msg_ctx,
614 file.pending[i].server,
616 file.pending[i].notify_ptr);
618 file.num_pending = 0;
620 return odb_push_record(lck, &file);
624 send oplocks breaks to none to all level2 holders
626 static NTSTATUS odb_tdb_break_oplocks(struct odb_lock *lck)
628 struct odb_context *odb = lck->odb;
630 struct opendb_file file;
632 bool modified = true;
634 status = odb_pull_record(lck, &file);
635 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
638 NT_STATUS_NOT_OK_RETURN(status);
640 /* see if anyone has an oplock, which we need to break */
641 for (i=0;i<file.num_entries;i++) {
642 if (file.entries[i].oplock_level == OPLOCK_LEVEL_II) {
644 * there could be multiple level2 oplocks
645 * and we just send a break to none to all of them
646 * without waiting for a release
648 odb_oplock_break_send(odb, &file.entries[i],
649 OPLOCK_BREAK_TO_NONE);
650 file.entries[i].oplock_level = OPLOCK_NONE;
656 return odb_push_record(lck, &file);
662 remove a pending opendb entry
664 static NTSTATUS odb_tdb_remove_pending(struct odb_lock *lck, void *private)
666 struct odb_context *odb = lck->odb;
669 struct opendb_file file;
671 status = odb_pull_record(lck, &file);
672 NT_STATUS_NOT_OK_RETURN(status);
674 /* find the entry, and delete it */
675 for (i=0;i<file.num_pending;i++) {
676 if (private == file.pending[i].notify_ptr &&
677 cluster_id_equal(&odb->ntvfs_ctx->server_id, &file.pending[i].server)) {
678 if (i < file.num_pending-1) {
679 memmove(file.pending+i, file.pending+i+1,
680 (file.num_pending - (i+1)) *
681 sizeof(struct opendb_pending));
687 if (i == file.num_pending) {
688 return NT_STATUS_UNSUCCESSFUL;
693 return odb_push_record(lck, &file);
698 rename the path in a open file
700 static NTSTATUS odb_tdb_rename(struct odb_lock *lck, const char *path)
702 struct opendb_file file;
705 status = odb_pull_record(lck, &file);
706 if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
707 /* not having the record at all is OK */
710 NT_STATUS_NOT_OK_RETURN(status);
713 return odb_push_record(lck, &file);
717 update delete on close flag on an open file
719 static NTSTATUS odb_tdb_set_delete_on_close(struct odb_lock *lck, bool del_on_close)
722 struct opendb_file file;
724 status = odb_pull_record(lck, &file);
725 NT_STATUS_NOT_OK_RETURN(status);
727 file.delete_on_close = del_on_close;
729 return odb_push_record(lck, &file);
733 return the current value of the delete_on_close bit, and how many
734 people still have the file open
736 static NTSTATUS odb_tdb_get_delete_on_close(struct odb_context *odb,
737 DATA_BLOB *key, bool *del_on_close,
738 int *open_count, char **path)
741 struct opendb_file file;
742 struct odb_lock *lck;
744 lck = odb_lock(odb, odb, key);
745 NT_STATUS_HAVE_NO_MEMORY(lck);
747 status = odb_pull_record(lck, &file);
748 if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) {
750 (*del_on_close) = false;
753 if (!NT_STATUS_IS_OK(status)) {
758 (*del_on_close) = file.delete_on_close;
759 if (open_count != NULL) {
760 (*open_count) = file.num_entries;
763 *path = talloc_strdup(odb, file.path);
764 NT_STATUS_HAVE_NO_MEMORY(*path);
765 if (file.num_entries == 1 && file.entries[0].delete_on_close) {
766 (*del_on_close) = true;
777 determine if a file can be opened with the given share_access,
778 create_options and access_mask
780 static NTSTATUS odb_tdb_can_open(struct odb_lock *lck,
781 uint32_t stream_id, uint32_t share_access,
782 uint32_t access_mask, bool delete_on_close,
783 uint32_t open_disposition, bool break_to_none)
785 struct odb_context *odb = lck->odb;
787 struct opendb_file file;
788 bool attrs_only = false;
790 status = odb_pull_record(lck, &file);
791 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
794 NT_STATUS_NOT_OK_RETURN(status);
796 status = odb_tdb_open_can_internal(odb, &file, stream_id,
797 share_access, access_mask,
798 delete_on_close, open_disposition,
799 break_to_none, &attrs_only);
800 NT_STATUS_NOT_OK_RETURN(status);
806 static const struct opendb_ops opendb_tdb_ops = {
807 .odb_init = odb_tdb_init,
808 .odb_lock = odb_tdb_lock,
809 .odb_get_key = odb_tdb_get_key,
810 .odb_open_file = odb_tdb_open_file,
811 .odb_open_file_pending = odb_tdb_open_file_pending,
812 .odb_close_file = odb_tdb_close_file,
813 .odb_remove_pending = odb_tdb_remove_pending,
814 .odb_rename = odb_tdb_rename,
815 .odb_set_delete_on_close = odb_tdb_set_delete_on_close,
816 .odb_get_delete_on_close = odb_tdb_get_delete_on_close,
817 .odb_can_open = odb_tdb_can_open,
818 .odb_update_oplock = odb_tdb_update_oplock,
819 .odb_break_oplocks = odb_tdb_break_oplocks
823 void odb_tdb_init_ops(void)
825 odb_set_ops(&opendb_tdb_ops);