diff options
-rw-r--r-- | source3/Makefile.in | 3 | ||||
-rw-r--r-- | source3/locking/locking.c | 40 | ||||
-rw-r--r-- | source3/locking/proto.h | 1 | ||||
-rw-r--r-- | source3/locking/share_mode_lock.c | 42 | ||||
-rw-r--r-- | source3/smbd/close.c | 16 | ||||
-rw-r--r-- | source3/smbd/open.c | 25 | ||||
-rw-r--r-- | source3/smbd/trans2.c | 3 | ||||
-rw-r--r-- | source3/torture/proto.h | 1 | ||||
-rw-r--r-- | source3/torture/test_cleanup.c | 175 | ||||
-rw-r--r-- | source3/torture/torture.c | 1 | ||||
-rwxr-xr-x | source3/wscript_build | 1 |
11 files changed, 46 insertions, 262 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in index 984cc00f06..1eb8cd8bf3 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -1282,12 +1282,11 @@ SMBTORTURE_OBJ1 = torture/torture.o torture/nbio.o torture/scanner.o torture/uta torture/t_strappend.o SMBTORTURE_OBJ = $(SMBTORTURE_OBJ1) $(PARAM_OBJ) $(TLDAP_OBJ) \ - $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) $(LOCKING_OBJ) \ + $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) \ @LIBWBCLIENT_STATIC@ \ torture/wbc_async.o \ ../nsswitch/wb_reqtrans.o \ ../libcli/lsarpc/util_lsarpc.o \ - lib/filename_util.o \ $(LIBMSRPC_OBJ) $(LIBMSRPC_GEN_OBJ) $(LIBCLI_ECHO_OBJ) MASKTEST_OBJ = torture/masktest.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(KRBCLIENT_OBJ) \ diff --git a/source3/locking/locking.c b/source3/locking/locking.c index b9fba17a87..b9afd2392c 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -556,10 +556,6 @@ bool rename_share_filename(struct messaging_context *msg_ctx, continue; } - if (share_mode_stale_pid(d, i)) { - continue; - } - DEBUG(10,("rename_share_filename: sending rename message to " "pid %s file_id %s sharepath %s base_name %s " "stream_name %s\n", @@ -620,9 +616,7 @@ bool is_valid_share_mode_entry(const struct share_mode_entry *e) num_props += (EXCLUSIVE_OPLOCK_TYPE(e->op_type) ? 1 : 0); num_props += (LEVEL_II_OPLOCK_TYPE(e->op_type) ? 1 : 0); - if (serverid_exists(&e->pid) && (num_props > 1)) { - smb_panic("Invalid share mode entry"); - } + SMB_ASSERT(num_props <= 1); return (num_props != 0); } @@ -631,38 +625,6 @@ bool is_deferred_open_entry(const struct share_mode_entry *e) return (e->op_type == DEFERRED_OPEN_ENTRY); } -/* - * In case d->share_modes[i] conflicts with something or otherwise is - * being used, we need to make sure the corresponding process still - * exists. This routine checks it and potentially removes the entry - * from d->share_modes. Modifies d->num_share_modes, watch out in - * routines iterating over that array. - */ -bool share_mode_stale_pid(struct share_mode_data *d, unsigned i) -{ - struct share_mode_entry *e; - - if (i > d->num_share_modes) { - DEBUG(1, ("Asking for index %u, only %u around\n", - i, (unsigned)d->num_share_modes)); - return false; - } - e = &d->share_modes[i]; - if (serverid_exists(&e->pid)) { - DEBUG(10, ("PID %s (index %u out of %u) still exists\n", - procid_str_static(&e->pid), i, - (unsigned)d->num_share_modes)); - return false; - } - DEBUG(10, ("PID %s (index %u out of %u) does not exist anymore\n", - procid_str_static(&e->pid), i, - (unsigned)d->num_share_modes)); - *e = d->share_modes[d->num_share_modes-1]; - d->num_share_modes -= 1; - d->modified = true; - return true; -} - /******************************************************************* Fill a share mode entry. ********************************************************************/ diff --git a/source3/locking/proto.h b/source3/locking/proto.h index f6a6f2ee12..54badd9149 100644 --- a/source3/locking/proto.h +++ b/source3/locking/proto.h @@ -168,7 +168,6 @@ void get_file_infos(struct file_id id, struct timespec *write_time); bool is_valid_share_mode_entry(const struct share_mode_entry *e); bool is_deferred_open_entry(const struct share_mode_entry *e); -bool share_mode_stale_pid(struct share_mode_data *d, unsigned i); void set_share_mode(struct share_mode_lock *lck, files_struct *fsp, uid_t uid, uint64_t mid, uint16 op_type); void add_deferred_open(struct share_mode_lock *lck, uint64_t mid, diff --git a/source3/locking/share_mode_lock.c b/source3/locking/share_mode_lock.c index 1fea748e72..f28332c226 100644 --- a/source3/locking/share_mode_lock.c +++ b/source3/locking/share_mode_lock.c @@ -118,6 +118,9 @@ static struct share_mode_data *parse_share_modes(TALLOC_CTX *mem_ctx, const TDB_DATA dbuf) { struct share_mode_data *d; + int i; + struct server_id *pids; + bool *pid_exists; enum ndr_err_code ndr_err; DATA_BLOB blob; @@ -145,6 +148,45 @@ static struct share_mode_data *parse_share_modes(TALLOC_CTX *mem_ctx, NDR_PRINT_DEBUG(share_mode_data, d); } + /* + * Ensure that each entry has a real process attached. + */ + + pids = talloc_array(talloc_tos(), struct server_id, + d->num_share_modes); + if (pids == NULL) { + DEBUG(0, ("talloc failed\n")); + goto fail; + } + pid_exists = talloc_array(talloc_tos(), bool, d->num_share_modes); + if (pid_exists == NULL) { + DEBUG(0, ("talloc failed\n")); + goto fail; + } + + for (i=0; i<d->num_share_modes; i++) { + pids[i] = d->share_modes[i].pid; + } + if (!serverids_exist(pids, d->num_share_modes, pid_exists)) { + DEBUG(0, ("serverid_exists failed\n")); + goto fail; + } + + i = 0; + while (i < d->num_share_modes) { + struct share_mode_entry *e = &d->share_modes[i]; + if (!pid_exists[i]) { + DEBUG(10, ("wipe non-existent pid %s\n", + procid_str_static(&e->pid))); + *e = d->share_modes[d->num_share_modes-1]; + d->num_share_modes -= 1; + d->modified = True; + continue; + } + i += 1; + } + TALLOC_FREE(pid_exists); + TALLOC_FREE(pids); return d; fail: TALLOC_FREE(d); diff --git a/source3/smbd/close.c b/source3/smbd/close.c index e46e1aec89..c87b1a000b 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -179,15 +179,9 @@ static void notify_deferred_opens(struct smbd_server_connection *sconn, num_deferred = 0; for (i=0; i<lck->data->num_share_modes; i++) { - struct share_mode_entry *e = &lck->data->share_modes[i]; - - if (!is_deferred_open_entry(e)) { - continue; - } - if (share_mode_stale_pid(lck->data, i)) { - continue; + if (is_deferred_open_entry(&lck->data->share_modes[i])) { + num_deferred += 1; } - num_deferred += 1; } if (num_deferred == 0) { return; @@ -425,9 +419,6 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) { continue; } - if (share_mode_stale_pid(lck->data, i)) { - continue; - } delete_file = False; break; } @@ -1078,9 +1069,6 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp, if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) { continue; } - if (share_mode_stale_pid(lck->data, i)) { - continue; - } delete_dir = False; break; } diff --git a/source3/smbd/open.c b/source3/smbd/open.c index f0e523dc77..543a6619e9 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -1024,11 +1024,6 @@ static NTSTATUS open_mode_check(connection_struct *conn, * too */ if (share_conflict(&lck->data->share_modes[i], access_mask, share_access)) { - - if (share_mode_stale_pid(lck->data, i)) { - continue; - } - return NT_STATUS_SHARING_VIOLATION; } } @@ -1128,11 +1123,6 @@ static void find_oplock_types(files_struct *fsp, if (BATCH_OPLOCK_TYPE(lck->data->share_modes[i].op_type)) { /* batch - can only be one. */ - if (share_mode_stale_pid(lck->data, i)) { - DEBUG(10, ("find_oplock_types: Found stale " - "batch oplock\n")); - continue; - } if (*pp_ex_or_batch || *pp_batch || *got_level2 || *got_no_oplock) { smb_panic("Bad batch oplock entry."); } @@ -1140,11 +1130,6 @@ static void find_oplock_types(files_struct *fsp, } if (EXCLUSIVE_OPLOCK_TYPE(lck->data->share_modes[i].op_type)) { - if (share_mode_stale_pid(lck->data, i)) { - DEBUG(10, ("find_oplock_types: Found stale " - "duplicate oplock\n")); - continue; - } /* Exclusive or batch - can only be one. */ if (*pp_ex_or_batch || *got_level2 || *got_no_oplock) { smb_panic("Bad exclusive or batch oplock entry."); @@ -1154,11 +1139,6 @@ static void find_oplock_types(files_struct *fsp, if (LEVEL_II_OPLOCK_TYPE(lck->data->share_modes[i].op_type)) { if (*pp_batch || *pp_ex_or_batch) { - if (share_mode_stale_pid(lck->data, i)) { - DEBUG(10, ("find_oplock_types: Found " - "stale LevelII oplock\n")); - continue; - } smb_panic("Bad levelII oplock entry."); } *got_level2 = true; @@ -1166,11 +1146,6 @@ static void find_oplock_types(files_struct *fsp, if (lck->data->share_modes[i].op_type == NO_OPLOCK) { if (*pp_batch || *pp_ex_or_batch) { - if (share_mode_stale_pid(lck->data, i)) { - DEBUG(10, ("find_oplock_types: Found " - "stale NO_OPLOCK entry\n")); - continue; - } smb_panic("Bad no oplock entry."); } *got_no_oplock = true; diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 936b39a2c2..590ee5bf7c 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -7595,9 +7595,6 @@ static NTSTATUS smb_posix_unlink(connection_struct *conn, if (e->flags & SHARE_MODE_FLAG_POSIX_OPEN) { continue; } - if (share_mode_stale_pid(lck->data, i)) { - continue; - } /* Fail with sharing violation. */ close_file(req, fsp, NORMAL_CLOSE); TALLOC_FREE(lck); diff --git a/source3/torture/proto.h b/source3/torture/proto.h index 4104fbc998..80618ceb34 100644 --- a/source3/torture/proto.h +++ b/source3/torture/proto.h @@ -104,7 +104,6 @@ bool run_local_conv_auth_info(int dummy); bool run_local_sprintf_append(int dummy); bool run_cleanup1(int dummy); bool run_cleanup2(int dummy); -bool run_cleanup3(int dummy); bool run_ctdb_conn(int dummy); bool run_msg_test(int dummy); bool run_notify_bench2(int dummy); diff --git a/source3/torture/test_cleanup.c b/source3/torture/test_cleanup.c index d9dce402de..39f579a9cd 100644 --- a/source3/torture/test_cleanup.c +++ b/source3/torture/test_cleanup.c @@ -18,14 +18,11 @@ */ #include "includes.h" -#include "locking/proto.h" #include "torture/proto.h" #include "system/filesys.h" -#include "system/select.h" #include "libsmb/libsmb.h" #include "libcli/smb/smbXcli_base.h" #include "libcli/security/security.h" -#include "librpc/gen_ndr/open_files.h" bool run_cleanup1(int dummy) { @@ -157,175 +154,3 @@ bool run_cleanup2(int dummy) } return true; } - -static bool create_stale_share_mode_entry(const char *fname, - struct file_id *p_id) -{ - struct cli_state *cli; - uint16_t fnum; - NTSTATUS status; - SMB_STRUCT_STAT sbuf; - struct file_id id; - - if (!torture_open_connection(&cli, 0)) { - return false; - } - - status = torture_setup_unix_extensions(cli); - if (!NT_STATUS_IS_OK(status)) { - printf("torture_setup_unix_extensions failed: %s\n", - nt_errstr(status)); - return false; - } - status = cli_openx(cli, fname, O_RDWR|O_CREAT, DENY_ALL, &fnum); - if (!NT_STATUS_IS_OK(status)) { - printf("open of %s failed (%s)\n", fname, nt_errstr(status)); - return false; - } - status = cli_posix_stat(cli, fname, &sbuf); - if (!NT_STATUS_IS_OK(status)) { - printf("cli_posix_stat failed: %s\n", nt_errstr(status)); - return false; - } - status = smbXcli_conn_samba_suicide(cli->conn, 1); - if (!NT_STATUS_IS_OK(status)) { - printf("smbXcli_conn_samba_suicide failed: %s\n", - nt_errstr(status)); - return false; - } - - id.devid = sbuf.st_ex_rdev; - id.inode = sbuf.st_ex_ino; - id.extid = 0; - - poll(NULL, 0, 1000); - - *p_id = id; - return true; -} - -static bool corrupt_dummy(struct share_mode_data *d) -{ - return true; -} - -static bool invalidate_sharemode(struct share_mode_data *d) -{ - d->share_modes[0].op_type = - OPLOCK_EXCLUSIVE|OPLOCK_BATCH|OPLOCK_LEVEL_II; - d->modified = true; - return true; -} - -static bool duplicate_entry(struct share_mode_data *d, int i) -{ - struct share_mode_entry *tmp; - - if (i >= d->num_share_modes) { - return false; - } - - tmp = talloc_realloc(d, d->share_modes, struct share_mode_entry, - d->num_share_modes + 1); - if (tmp == NULL) { - return false; - } - d->share_modes = tmp; - d->num_share_modes += 1; - d->share_modes[d->num_share_modes-1] = d->share_modes[i]; - d->modified = true; - return true; -} - -static bool create_duplicate_batch(struct share_mode_data *d) -{ - if (d->num_share_modes != 1) { - return false; - } - d->share_modes[0].op_type = OPLOCK_BATCH; - if (!duplicate_entry(d, 0)) { - return false; - } - return true; -} - -struct corruption_fns { - bool (*fn)(struct share_mode_data *d); - const char *descr; -}; - -bool run_cleanup3(int dummy) -{ - struct cli_state *cli; - const char *fname = "cleanup3"; - uint16_t fnum; - NTSTATUS status; - struct share_mode_lock *lck; - struct file_id id; - size_t i; - - struct corruption_fns fns[] = { - { corrupt_dummy, "no corruption" }, - { invalidate_sharemode, "invalidate_sharemode" }, - { create_duplicate_batch, "create_duplicate_batch" }, - }; - - printf("CLEANUP3: Checking that a share mode is cleaned up on " - "conflict\n"); - - for (i=0; i<ARRAY_SIZE(fns); i++) { - - printf("testing %s\n", fns[i].descr); - - if (!create_stale_share_mode_entry(fname, &id)) { - printf("create_stale_entry failed\n"); - return false; - } - - printf("%d %d %d\n", (int)id.devid, (int)id.inode, - (int)id.extid); - - if (!locking_init()) { - printf("locking_init failed\n"); - return false; - } - lck = get_existing_share_mode_lock(talloc_tos(), id); - if (lck == NULL) { - printf("get_existing_share_mode_lock failed\n"); - return false; - } - if (lck->data->num_share_modes != 1) { - printf("get_existing_share_mode_lock did clean up\n"); - return false; - } - - fns[i].fn(lck->data); - - TALLOC_FREE(lck); - - if (!torture_open_connection(&cli, 0)) { - return false; - } - status = cli_openx(cli, fname, O_RDWR|O_CREAT, DENY_ALL, - &fnum); - if (!NT_STATUS_IS_OK(status)) { - printf("open of %s failed (%s)\n", fname, - nt_errstr(status)); - return false; - } - lck = get_existing_share_mode_lock(talloc_tos(), id); - if (lck == NULL) { - printf("get_existing_share_mode_lock failed\n"); - return false; - } - if (lck->data->num_share_modes != 1) { - printf("conflicting open did not clean up\n"); - return false; - } - TALLOC_FREE(lck); - - torture_close_connection(cli); - } - - return true; -} diff --git a/source3/torture/torture.c b/source3/torture/torture.c index ad30d3dceb..962d0e7967 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -8916,7 +8916,6 @@ static struct { { "SMB2-SESSION-REAUTH", run_smb2_session_reauth }, { "CLEANUP1", run_cleanup1 }, { "CLEANUP2", run_cleanup2 }, - { "CLEANUP3", run_cleanup3 }, { "LOCAL-SUBSTITUTE", run_local_substitute, 0}, { "LOCAL-GENCACHE", run_local_gencache, 0}, { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0}, diff --git a/source3/wscript_build b/source3/wscript_build index ff1e7785ca..4deb556d23 100755 --- a/source3/wscript_build +++ b/source3/wscript_build @@ -1381,7 +1381,6 @@ bld.SAMBA3_BINARY('smbtorture' + bld.env.suffix3, TLDAP RPC_NDR_ECHO WB_REQTRANS - LOCKING idmap ''', vars=locals()) |