1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-11 05:18:09 +03:00

smbd: consolidate DH reconnect failure code

No change in behaviour, except that we now
also call fd_close() if vfs_default_durable_cookie()
failed.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15624

Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>

Signed-off-by: Ralph Boehme <slow@samba.org>
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Guenther Deschner <gd@samba.org>
(cherry picked from commit a91457f97c)
This commit is contained in:
Ralph Boehme 2024-04-09 14:52:44 +02:00 committed by Jule Anger
parent 4e419975cc
commit e620d1a871

View File

@ -624,22 +624,22 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
ok = share_mode_forall_entries(lck, durable_reconnect_fn, &e);
if (!ok) {
DBG_WARNING("share_mode_forall_entries failed\n");
TALLOC_FREE(lck);
return NT_STATUS_INTERNAL_DB_ERROR;
status = NT_STATUS_INTERNAL_DB_ERROR;
goto fail;
}
if (e.pid.pid == 0) {
DBG_WARNING("Did not find a unique valid share mode entry\n");
TALLOC_FREE(lck);
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
goto fail;
}
if (!server_id_is_disconnected(&e.pid)) {
DEBUG(5, ("vfs_default_durable_reconnect: denying durable "
"reconnect for handle that was not marked "
"disconnected (e.g. smbd or cluster node died)\n"));
TALLOC_FREE(lck);
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
goto fail;
}
if (e.share_file_id != op->global->open_persistent_id) {
@ -648,8 +648,8 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
"(e.g. another client had opened the file)\n",
e.share_file_id,
op->global->open_persistent_id);
TALLOC_FREE(lck);
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
goto fail;
}
if ((e.access_mask & (FILE_WRITE_DATA|FILE_APPEND_DATA)) &&
@ -658,8 +658,8 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
DEBUG(5, ("vfs_default_durable_reconnect: denying durable "
"share[%s] is not writeable anymore\n",
lp_servicename(talloc_tos(), lp_sub, SNUM(conn))));
TALLOC_FREE(lck);
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
goto fail;
}
/*
@ -670,8 +670,7 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("vfs_default_durable_reconnect: failed to create "
"new fsp: %s\n", nt_errstr(status)));
TALLOC_FREE(lck);
return status;
goto fail;
}
fh_set_private_options(fsp->fh, e.private_options);
@ -714,9 +713,8 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
*/
if (!GUID_equal(fsp_client_guid(fsp),
&e.client_guid)) {
TALLOC_FREE(lck);
file_free(smb1req, fsp);
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
goto fail;
}
status = leases_db_get(
@ -730,9 +728,7 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
&lease_version, /* lease_version */
&epoch); /* epoch */
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(lck);
file_free(smb1req, fsp);
return status;
goto fail;
}
fsp->lease = find_fsp_lease(
@ -742,9 +738,8 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
lease_version,
epoch);
if (fsp->lease == NULL) {
TALLOC_FREE(lck);
file_free(smb1req, fsp);
return NT_STATUS_NO_MEMORY;
status = NT_STATUS_NO_MEMORY;
goto fail;
}
}
@ -760,12 +755,10 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
status = fsp_set_smb_fname(fsp, smb_fname);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(lck);
file_free(smb1req, fsp);
DEBUG(0, ("vfs_default_durable_reconnect: "
"fsp_set_smb_fname failed: %s\n",
nt_errstr(status)));
return status;
goto fail;
}
op->compat = fsp;
@ -780,11 +773,8 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
fh_get_gen_id(fsp->fh));
if (!ok) {
DBG_DEBUG("Could not set new share_mode_entry values\n");
TALLOC_FREE(lck);
op->compat = NULL;
fsp->op = NULL;
file_free(smb1req, fsp);
return NT_STATUS_INTERNAL_ERROR;
status = NT_STATUS_INTERNAL_ERROR;
goto fail;
}
ok = brl_reconnect_disconnected(fsp);
@ -793,11 +783,7 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
DEBUG(1, ("vfs_default_durable_reconnect: "
"failed to reopen brlocks: %s\n",
nt_errstr(status)));
TALLOC_FREE(lck);
op->compat = NULL;
fsp->op = NULL;
file_free(smb1req, fsp);
return status;
goto fail;
}
/*
@ -813,13 +799,9 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
status = fd_openat(conn->cwd_fsp, fsp->fsp_name, fsp, &how);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(lck);
DEBUG(1, ("vfs_default_durable_reconnect: failed to open "
"file: %s\n", nt_errstr(status)));
op->compat = NULL;
fsp->op = NULL;
file_free(smb1req, fsp);
return status;
goto fail;
}
/*
@ -833,48 +815,22 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
if (ret == -1) {
NTSTATUS close_status;
status = map_nt_error_from_unix_common(errno);
DEBUG(1, ("Unable to fstat stream: %s => %s\n",
smb_fname_str_dbg(smb_fname),
nt_errstr(status)));
close_status = fd_close(fsp);
if (!NT_STATUS_IS_OK(close_status)) {
DBG_ERR("fd_close failed (%s) - leaking file "
"descriptor\n", nt_errstr(close_status));
}
TALLOC_FREE(lck);
op->compat = NULL;
fsp->op = NULL;
file_free(smb1req, fsp);
return status;
goto fail;
}
if (!S_ISREG(fsp->fsp_name->st.st_ex_mode)) {
NTSTATUS close_status = fd_close(fsp);
if (!NT_STATUS_IS_OK(close_status)) {
DBG_ERR("fd_close failed (%s) - leaking file "
"descriptor\n", nt_errstr(close_status));
}
TALLOC_FREE(lck);
op->compat = NULL;
fsp->op = NULL;
file_free(smb1req, fsp);
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
goto fail;
}
file_id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st);
if (!file_id_equal(&cookie.id, &file_id)) {
NTSTATUS close_status = fd_close(fsp);
if (!NT_STATUS_IS_OK(close_status)) {
DBG_ERR("fd_close failed (%s) - leaking file "
"descriptor\n", nt_errstr(close_status));
}
TALLOC_FREE(lck);
op->compat = NULL;
fsp->op = NULL;
file_free(smb1req, fsp);
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
goto fail;
}
(void)fdos_mode(fsp);
@ -883,42 +839,21 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
&fsp->fsp_name->st,
fsp_str_dbg(fsp));
if (!ok) {
NTSTATUS close_status = fd_close(fsp);
if (!NT_STATUS_IS_OK(close_status)) {
DBG_ERR("fd_close failed (%s) - leaking file "
"descriptor\n", nt_errstr(close_status));
}
TALLOC_FREE(lck);
op->compat = NULL;
fsp->op = NULL;
file_free(smb1req, fsp);
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
goto fail;
}
status = set_file_oplock(fsp);
if (!NT_STATUS_IS_OK(status)) {
NTSTATUS close_status = fd_close(fsp);
if (!NT_STATUS_IS_OK(close_status)) {
DBG_ERR("fd_close failed (%s) - leaking file "
"descriptor\n", nt_errstr(close_status));
}
TALLOC_FREE(lck);
op->compat = NULL;
fsp->op = NULL;
file_free(smb1req, fsp);
return status;
goto fail;
}
status = vfs_default_durable_cookie(fsp, mem_ctx, &new_cookie_blob);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(lck);
DEBUG(1, ("vfs_default_durable_reconnect: "
"vfs_default_durable_cookie - %s\n",
nt_errstr(status)));
op->compat = NULL;
fsp->op = NULL;
file_free(smb1req, fsp);
return status;
goto fail;
}
smb1req->chain_fsp = fsp;
@ -935,4 +870,21 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn,
*new_cookie = new_cookie_blob;
return NT_STATUS_OK;
fail:
if (fsp != NULL && fsp_get_pathref_fd(fsp) != -1) {
NTSTATUS close_status;
close_status = fd_close(fsp);
if (!NT_STATUS_IS_OK(close_status)) {
DBG_ERR("fd_close failed (%s), leaking fd\n",
nt_errstr(close_status));
}
}
TALLOC_FREE(lck);
if (fsp != NULL) {
op->compat = NULL;
fsp->op = NULL;
file_free(smb1req, fsp);
}
return status;
}