[SCM] Samba Shared Repository - branch v4-1-test updated

Karolin Seeger kseeger at samba.org
Thu May 21 09:45:04 MDT 2015


The branch, v4-1-test has been updated
       via  995bef1 s4: libcli/finddcs_cldap: continue processing CLDAP until all addresses are used
       via  67fbd6d s3:winbindd: make sure we remove pending io requests before closing client sockets
      from  d8626e9 s4:lib/tls: fix build with gnutls 3.4

https://git.samba.org/?p=samba.git;a=shortlog;h=v4-1-test


- Log -----------------------------------------------------------------
commit 995bef1aadc534f16e9cb581fc826b396fbe762d
Author: Alexander Bokovoy <ab at samba.org>
Date:   Wed May 20 11:17:38 2015 +0300

    s4: libcli/finddcs_cldap: continue processing CLDAP until all addresses are used
    
    This is a subtle bug that causes CLDAP pings to fail if SRV records
    discovered cannot be resolved or connection to them cannot be
    established. The code that fires up CLDAP ping will silently cancel
    the whole tevent request without going to the next server in the queue.
    
    This may happen, for example, when connection to IPv6 addresses couldn't
    be established, or when IPv4 address is not online or blocked by
    firewall.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=11284
    
    Signed-off-by: Alexander Bokovoy <ab at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    (cherry picked from commit eb029b32e95c9e7382488f3a1b033cdbe3237c1c)
    
    Autobuild-User(v4-1-test): Karolin Seeger <kseeger at samba.org>
    Autobuild-Date(v4-1-test): Thu May 21 17:44:11 CEST 2015 on sn-devel-104

commit 67fbd6dfd2640549dc4ba1649a6c55c291493de7
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon May 18 13:17:40 2015 +0200

    s3:winbindd: make sure we remove pending io requests before closing client sockets
    
    This avoids a crash inside the tevent epoll backend.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=11141
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Stefan Metzmacher <metze at samba.org>
    Autobuild-Date(master): Wed May 20 22:16:54 CEST 2015 on sn-devel-104
    
    (cherry picked from commit 435ddd8223eaa6fafb62cead0399bdd042d998e8)

-----------------------------------------------------------------------

Summary of changes:
 source3/winbindd/winbindd.c    | 26 ++++++++++++++++++++++++++
 source3/winbindd/winbindd.h    |  2 ++
 source4/libcli/finddcs_cldap.c | 42 ++++++++++++++++++++++++++++++++----------
 3 files changed, 60 insertions(+), 10 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c
index 27c43dc..2c94f49 100644
--- a/source3/winbindd/winbindd.c
+++ b/source3/winbindd/winbindd.c
@@ -792,6 +792,7 @@ static void request_finished(struct winbindd_cli_state *state)
 		return;
 	}
 	tevent_req_set_callback(req, winbind_client_response_written, state);
+	state->io_req = req;
 }
 
 static void winbind_client_response_written(struct tevent_req *req)
@@ -801,6 +802,8 @@ static void winbind_client_response_written(struct tevent_req *req)
 	ssize_t ret;
 	int err;
 
+	state->io_req = NULL;
+
 	ret = wb_resp_write_recv(req, &err);
 	TALLOC_FREE(req);
 	if (ret == -1) {
@@ -827,6 +830,7 @@ static void winbind_client_response_written(struct tevent_req *req)
 		return;
 	}
 	tevent_req_set_callback(req, winbind_client_request_read, state);
+	state->io_req = req;
 }
 
 void request_error(struct winbindd_cli_state *state)
@@ -897,6 +901,7 @@ static void new_connection(int listen_sock, bool privileged)
 		return;
 	}
 	tevent_req_set_callback(req, winbind_client_request_read, state);
+	state->io_req = req;
 
 	/* Add to connection list */
 
@@ -910,6 +915,8 @@ static void winbind_client_request_read(struct tevent_req *req)
 	ssize_t ret;
 	int err;
 
+	state->io_req = NULL;
+
 	ret = wb_req_read_recv(req, state, &state->request, &err);
 	TALLOC_FREE(req);
 	if (ret == -1) {
@@ -941,6 +948,25 @@ static void remove_client(struct winbindd_cli_state *state)
 		return;
 	}
 
+	/*
+	 * We need to remove a pending wb_req_read_*
+	 * or wb_resp_write_* request before closing the
+	 * socket.
+	 *
+	 * This is important as they might have used tevent_add_fd() and we
+	 * use the epoll * backend on linux. So we must remove the tevent_fd
+	 * before closing the fd.
+	 *
+	 * Otherwise we might hit a race with close_conns_after_fork() (via
+	 * winbindd_reinit_after_fork()) where a file description
+	 * is still open in a child, which means it's still active in
+	 * the parents epoll queue, but the related tevent_fd is already
+	 * already gone in the parent.
+	 *
+	 * See bug #11141.
+	 */
+	TALLOC_FREE(state->io_req);
+
 	if (state->sock != -1) {
 		/* tell client, we are closing ... */
 		nwritten = write(state->sock, &c, sizeof(c));
diff --git a/source3/winbindd/winbindd.h b/source3/winbindd/winbindd.h
index 72eb3ec..986a41d 100644
--- a/source3/winbindd/winbindd.h
+++ b/source3/winbindd/winbindd.h
@@ -66,6 +66,8 @@ struct winbindd_cli_state {
 	struct winbindd_request *request;         /* Request from client */
 	struct tevent_queue *out_queue;
 	struct winbindd_response *response;        /* Respose to client */
+	struct tevent_req *io_req; /* wb_req_read_* or wb_resp_write_* */
+
 	bool getpwent_initialized;                /* Has getpwent_state been
 						   * initialized? */
 	bool getgrent_initialized;                /* Has getgrent_state been
diff --git a/source4/libcli/finddcs_cldap.c b/source4/libcli/finddcs_cldap.c
index bf8da4e..e0da371 100644
--- a/source4/libcli/finddcs_cldap.c
+++ b/source4/libcli/finddcs_cldap.c
@@ -42,6 +42,7 @@ struct finddcs_cldap_state {
 	uint32_t srv_address_index;
 	struct cldap_socket *cldap;
 	struct cldap_netlogon *netlogon;
+	NTSTATUS status;
 };
 
 static void finddcs_cldap_srv_resolved(struct composite_context *ctx);
@@ -245,10 +246,15 @@ static void finddcs_cldap_next_server(struct finddcs_cldap_state *state)
 	struct tevent_req *subreq;
 	struct tsocket_address *dest;
 	int ret;
-	NTSTATUS status;
+
+	TALLOC_FREE(state->cldap);
 
 	if (state->srv_addresses[state->srv_address_index] == NULL) {
-		tevent_req_nterror(state->req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
+		if (NT_STATUS_IS_OK(state->status)) {
+			tevent_req_nterror(state->req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
+		} else {
+			tevent_req_nterror(state->req, state->status);
+		}
 		DEBUG(2,("finddcs: No matching CLDAP server found\n"));
 		return;
 	}
@@ -259,22 +265,29 @@ static void finddcs_cldap_next_server(struct finddcs_cldap_state *state)
 						389,
 						&dest);
 	if (ret == 0) {
-		status = NT_STATUS_OK;
+		state->status = NT_STATUS_OK;
 	} else {
-		status = map_nt_error_from_unix_common(errno);
+		state->status = map_nt_error_from_unix_common(errno);
 	}
-	if (tevent_req_nterror(state->req, status)) {
+	if (!NT_STATUS_IS_OK(state->status)) {
+		state->srv_address_index++;
+		finddcs_cldap_next_server(state);
 		return;
 	}
 
-	status = cldap_socket_init(state, NULL, dest, &state->cldap);
-	if (tevent_req_nterror(state->req, status)) {
+	state->status = cldap_socket_init(state, NULL, dest, &state->cldap);
+	if (!NT_STATUS_IS_OK(state->status)) {
+		state->srv_address_index++;
+		finddcs_cldap_next_server(state);
 		return;
 	}
 
 	TALLOC_FREE(state->netlogon);
 	state->netlogon = talloc_zero(state, struct cldap_netlogon);
-	if (tevent_req_nomem(state->netlogon, state->req)) {
+	if (state->netlogon == NULL) {
+		state->status = NT_STATUS_NO_MEMORY;
+		state->srv_address_index++;
+		finddcs_cldap_next_server(state);
 		return;
 	}
 
@@ -283,7 +296,10 @@ static void finddcs_cldap_next_server(struct finddcs_cldap_state *state)
 	}
 	if (state->domain_sid) {
 		state->netlogon->in.domain_sid = dom_sid_string(state, state->domain_sid);
-		if (tevent_req_nomem(state->netlogon->in.domain_sid, state->req)) {
+		if (state->netlogon->in.domain_sid == NULL) {
+			state->status = NT_STATUS_NO_MEMORY;
+			state->srv_address_index++;
+			finddcs_cldap_next_server(state);
 			return;
 		}
 	}
@@ -299,7 +315,10 @@ static void finddcs_cldap_next_server(struct finddcs_cldap_state *state)
 
 	subreq = cldap_netlogon_send(state, state->ev,
 				     state->cldap, state->netlogon);
-	if (tevent_req_nomem(subreq, state->req)) {
+	if (subreq == NULL) {
+		state->status = NT_STATUS_NO_MEMORY;
+		state->srv_address_index++;
+		finddcs_cldap_next_server(state);
 		return;
 	}
 
@@ -321,6 +340,7 @@ static void finddcs_cldap_netlogon_replied(struct tevent_req *subreq)
 	TALLOC_FREE(subreq);
 	TALLOC_FREE(state->cldap);
 	if (!NT_STATUS_IS_OK(status)) {
+		state->status = status;
 		state->srv_address_index++;
 		finddcs_cldap_next_server(state);
 		return;
@@ -364,6 +384,7 @@ static void finddcs_cldap_name_resolved(struct composite_context *ctx)
 
 	state->srv_address_index = 0;
 
+	state->status = NT_STATUS_OK;
 	finddcs_cldap_next_server(state);
 }
 
@@ -416,6 +437,7 @@ static void finddcs_cldap_srv_resolved(struct composite_context *ctx)
 
 	state->srv_address_index = 0;
 
+	state->status = NT_STATUS_OK;
 	finddcs_cldap_next_server(state);
 }
 


-- 
Samba Shared Repository


More information about the samba-cvs mailing list