[SCM] Samba Shared Repository - branch master updated
Stefan Metzmacher
metze at samba.org
Fri Feb 21 06:52:07 MST 2014
The branch, master has been updated
via 33f10d0 s3:smbd: avoid invalid lock_order panic triggered by "CTDB_SRVID_RELEASE_IP"
via 9677fae s3:lib/ctdbd_conn: let release_ip_handler return bool
via 52ccb40 s3:smbd: maintain smbd_server_connection->status
via 58c71be s3:smbd: simplify exit_server_common()
from 913b2a1 clitar: don't panic, propagate talloc errors upwards
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 33f10d06baf44e31d558bc5bd926c886915322cc
Author: Stefan Metzmacher <metze at samba.org>
Date: Thu Feb 13 15:36:27 2014 +0100
s3:smbd: avoid invalid lock_order panic triggered by "CTDB_SRVID_RELEASE_IP"
If smbd_server_connection_terminate("CTDB_SRVID_RELEASE_IP") is triggered from
within ctdbd_migrate(), we got a smb_panic complaining about invalid
lock_order, as ctdbd_migrate is called from dbwrap_fetch_locked().
Bug: https://bugzilla.samba.org/show_bug.cgi?id=10444
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Volker Lendecke <vl at samba.org>
Autobuild-User(master): Stefan Metzmacher <metze at samba.org>
Autobuild-Date(master): Fri Feb 21 14:51:51 CET 2014 on sn-devel-104
commit 9677fae6aab26d2bf0884dc31516d2dcd8840c03
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Feb 17 11:57:52 2014 +0100
s3:lib/ctdbd_conn: let release_ip_handler return bool
If it returns true the passed ip address matched and we
let a nested ctdb operation fail with NT_STATUS_ADDRESS_CLOSED.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Volker Lendecke <vl at samba.org>
commit 52ccb40d595fc80bfa53b0b9cd75ffb902369681
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Feb 17 12:01:12 2014 +0100
s3:smbd: maintain smbd_server_connection->status
If this isn't NT_STATUS_OK, we skip any io on the socket.
This avoids possible problems during shutdown.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Volker Lendecke <vl at samba.org>
commit 58c71bee40bb91868fc69d8f7fa640db0e33efae
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Feb 17 12:05:42 2014 +0100
s3:smbd: simplify exit_server_common()
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Volker Lendecke <vl at samba.org>
-----------------------------------------------------------------------
Summary of changes:
source3/include/ctdbd_conn.h | 2 +-
source3/lib/ctdbd_conn.c | 36 +++++++++++++++++---
source3/smbd/globals.h | 1 +
source3/smbd/process.c | 72 +++++++++++++++++++++++++++++++++++++++--
source3/smbd/server_exit.c | 17 +++++++--
source3/smbd/smb2_server.c | 16 +++++++++
6 files changed, 129 insertions(+), 15 deletions(-)
Changeset truncated at 500 lines:
diff --git a/source3/include/ctdbd_conn.h b/source3/include/ctdbd_conn.h
index ce5c8ba..0f85229 100644
--- a/source3/include/ctdbd_conn.h
+++ b/source3/include/ctdbd_conn.h
@@ -76,7 +76,7 @@ NTSTATUS ctdbd_traverse(uint32_t db_id,
NTSTATUS ctdbd_register_ips(struct ctdbd_connection *conn,
const struct sockaddr_storage *server,
const struct sockaddr_storage *client,
- void (*release_ip_handler)(const char *ip_addr,
+ bool (*release_ip_handler)(const char *ip_addr,
void *private_data),
void *private_data);
diff --git a/source3/lib/ctdbd_conn.c b/source3/lib/ctdbd_conn.c
index 6ab4bbe..4d90324 100644
--- a/source3/lib/ctdbd_conn.c
+++ b/source3/lib/ctdbd_conn.c
@@ -59,7 +59,7 @@ struct ctdbd_connection {
struct ctdb_packet_context *pkt;
struct tevent_fd *fde;
- void (*release_ip_handler)(const char *ip_addr, void *private_data);
+ bool (*release_ip_handler)(const char *ip_addr, void *private_data);
void *release_ip_priv;
};
@@ -428,10 +428,23 @@ static NTSTATUS ctdb_read_req(struct ctdbd_connection *conn, uint32_t reqid,
if ((conn->release_ip_handler != NULL)
&& (msg->srvid == CTDB_SRVID_RELEASE_IP)) {
+ bool ret;
+
/* must be dispatched immediately */
DEBUG(10, ("received CTDB_SRVID_RELEASE_IP\n"));
- conn->release_ip_handler((const char *)msg->data,
- conn->release_ip_priv);
+ ret = conn->release_ip_handler((const char *)msg->data,
+ conn->release_ip_priv);
+ if (ret) {
+ /*
+ * We need to release the ip,
+ * so return an error to the upper layers.
+ *
+ * We make sure we don't trigger this again.
+ */
+ conn->release_ip_handler = NULL;
+ conn->release_ip_priv = NULL;
+ return NT_STATUS_ADDRESS_CLOSED;
+ }
TALLOC_FREE(hdr);
goto next_pkt;
}
@@ -630,10 +643,21 @@ static NTSTATUS ctdb_handle_message(uint8_t *buf, size_t length,
if ((conn->release_ip_handler != NULL)
&& (msg->srvid == CTDB_SRVID_RELEASE_IP)) {
+ bool ret;
+
/* must be dispatched immediately */
DEBUG(10, ("received CTDB_SRVID_RELEASE_IP\n"));
- conn->release_ip_handler((const char *)msg->data,
- conn->release_ip_priv);
+ ret = conn->release_ip_handler((const char *)msg->data,
+ conn->release_ip_priv);
+ if (ret) {
+ /*
+ * We need to release the ip.
+ *
+ * We make sure we don't trigger this again.
+ */
+ conn->release_ip_handler = NULL;
+ conn->release_ip_priv = NULL;
+ }
TALLOC_FREE(buf);
return NT_STATUS_OK;
}
@@ -1692,7 +1716,7 @@ static void smbd_ctdb_canonicalize_ip(const struct sockaddr_storage *in,
NTSTATUS ctdbd_register_ips(struct ctdbd_connection *conn,
const struct sockaddr_storage *_server,
const struct sockaddr_storage *_client,
- void (*release_ip_handler)(const char *ip_addr,
+ bool (*release_ip_handler)(const char *ip_addr,
void *private_data),
void *private_data)
{
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 94111b6..bae3ed0 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -633,6 +633,7 @@ struct user_struct {
};
struct smbd_server_connection {
+ NTSTATUS status;
int sock;
const struct tsocket_address *local_address;
const struct tsocket_address *remote_address;
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index f5ca2f9..41b3611 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -152,6 +152,13 @@ bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
ssize_t ret;
char *buf_out = buffer;
+ if (!NT_STATUS_IS_OK(sconn->status)) {
+ /*
+ * we're not supposed to do any io
+ */
+ return true;
+ }
+
smbd_lock_socket(sconn);
if (do_signing) {
@@ -2445,6 +2452,15 @@ static void smbd_server_connection_handler(struct tevent_context *ev,
struct smbd_server_connection *conn = talloc_get_type(private_data,
struct smbd_server_connection);
+ if (!NT_STATUS_IS_OK(conn->status)) {
+ /*
+ * we're not supposed to do any io
+ */
+ TEVENT_FD_NOT_READABLE(conn->smb1.fde);
+ TEVENT_FD_NOT_WRITEABLE(conn->smb1.fde);
+ return;
+ }
+
if (flags & TEVENT_FD_WRITE) {
smbd_server_connection_write_handler(conn);
return;
@@ -2463,6 +2479,15 @@ static void smbd_server_echo_handler(struct tevent_context *ev,
struct smbd_server_connection *conn = talloc_get_type(private_data,
struct smbd_server_connection);
+ if (!NT_STATUS_IS_OK(conn->status)) {
+ /*
+ * we're not supposed to do any io
+ */
+ TEVENT_FD_NOT_READABLE(conn->smb1.echo_handler.trusted_fde);
+ TEVENT_FD_NOT_WRITEABLE(conn->smb1.echo_handler.trusted_fde);
+ return;
+ }
+
if (flags & TEVENT_FD_WRITE) {
smbd_server_connection_write_handler(conn);
return;
@@ -2478,13 +2503,32 @@ static void smbd_server_echo_handler(struct tevent_context *ev,
struct smbd_release_ip_state {
struct smbd_server_connection *sconn;
+ struct tevent_immediate *im;
char addr[INET6_ADDRSTRLEN];
};
+static void smbd_release_ip_immediate(struct tevent_context *ctx,
+ struct tevent_immediate *im,
+ void *private_data)
+{
+ struct smbd_release_ip_state *state =
+ talloc_get_type_abort(private_data,
+ struct smbd_release_ip_state);
+
+ if (!NT_STATUS_EQUAL(state->sconn->status, NT_STATUS_ADDRESS_CLOSED)) {
+ /*
+ * smbd_server_connection_terminate() already triggered ?
+ */
+ return;
+ }
+
+ smbd_server_connection_terminate(state->sconn, "CTDB_SRVID_RELEASE_IP");
+}
+
/****************************************************************************
received when we should release a specific IP
****************************************************************************/
-static void release_ip(const char *ip, void *priv)
+static bool release_ip(const char *ip, void *priv)
{
struct smbd_release_ip_state *state =
talloc_get_type_abort(priv,
@@ -2492,6 +2536,11 @@ static void release_ip(const char *ip, void *priv)
const char *addr = state->addr;
const char *p = addr;
+ if (!NT_STATUS_IS_OK(state->sconn->status)) {
+ /* avoid recursion */
+ return false;
+ }
+
if (strncmp("::ffff:", addr, 7) == 0) {
p = addr + 7;
}
@@ -2518,11 +2567,22 @@ static void release_ip(const char *ip, void *priv)
* triggered and has implication on our process model,
* we can just use smbd_server_connection_terminate()
* (also for SMB1).
+ *
+ * We don't call smbd_server_connection_terminate() directly
+ * as we might be called from within ctdbd_migrate(),
+ * we need to defer our action to the next event loop
*/
- smbd_server_connection_terminate(state->sconn,
- "CTDB_SRVID_RELEASE_IP");
- return;
+ tevent_schedule_immediate(state->im, state->sconn->ev_ctx,
+ smbd_release_ip_immediate, state);
+
+ /*
+ * Make sure we don't get any io on the connection.
+ */
+ state->sconn->status = NT_STATUS_ADDRESS_CLOSED;
+ return true;
}
+
+ return false;
}
static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
@@ -2542,6 +2602,10 @@ static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
return NT_STATUS_NO_MEMORY;
}
state->sconn = sconn;
+ state->im = tevent_create_immediate(state);
+ if (state->im == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
if (print_sockaddr(state->addr, sizeof(state->addr), srv) == NULL) {
return NT_STATUS_NO_MEMORY;
}
diff --git a/source3/smbd/server_exit.c b/source3/smbd/server_exit.c
index 18a1a46..357c69a 100644
--- a/source3/smbd/server_exit.c
+++ b/source3/smbd/server_exit.c
@@ -99,13 +99,22 @@ static void exit_server_common(enum server_exit_reason how,
change_to_root_user();
- if (sconn && sconn->smb1.negprot.auth_context) {
- TALLOC_FREE(sconn->smb1.negprot.auth_context);
- }
-
if (sconn) {
NTSTATUS status;
+ if (NT_STATUS_IS_OK(sconn->status)) {
+ switch (how) {
+ case SERVER_EXIT_ABNORMAL:
+ sconn->status = NT_STATUS_INTERNAL_ERROR;
+ break;
+ case SERVER_EXIT_NORMAL:
+ sconn->status = NT_STATUS_LOCAL_DISCONNECT;
+ break;
+ }
+ }
+
+ TALLOC_FREE(sconn->smb1.negprot.auth_context);
+
if (lp_log_writeable_files_on_exit()) {
bool found = false;
files_forall(sconn, log_writeable_file_fn, &found);
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index fe42ac9..5e6bfd9 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -2841,6 +2841,13 @@ static NTSTATUS smbd_smb2_request_next_incoming(struct smbd_server_connection *s
size_t max_send_queue_len;
size_t cur_send_queue_len;
+ if (!NT_STATUS_IS_OK(sconn->status)) {
+ /*
+ * we're not supposed to do any io
+ */
+ return NT_STATUS_OK;
+ }
+
if (state->req != NULL) {
/*
* if there is already a tstream_readv_pdu
@@ -3087,6 +3094,15 @@ static NTSTATUS smbd_smb2_io_handler(struct smbd_server_connection *sconn,
NTSTATUS status;
NTTIME now;
+ if (!NT_STATUS_IS_OK(sconn->status)) {
+ /*
+ * we're not supposed to do any io
+ */
+ TEVENT_FD_NOT_READABLE(sconn->smb2.fde);
+ TEVENT_FD_NOT_WRITEABLE(sconn->smb2.fde);
+ return NT_STATUS_OK;
+ }
+
if (fde_flags & TEVENT_FD_WRITE) {
status = smbd_smb2_flush_send_queue(sconn);
if (!NT_STATUS_IS_OK(status)) {
--
Samba Shared Repository
More information about the samba-cvs
mailing list