[SCM] Samba Shared Repository - branch master updated

Andreas Schneider asn at samba.org
Thu Mar 1 13:49:02 UTC 2018


The branch, master has been updated
       via  c380626 winbind: Fix --ping-dc error handling
       via  49adb5a winbind: Fix a race between the sigchld and 0-sized socket read
       via  33f5f5c winbind: Remove the "winbindd_children" global
       via  0967705 winbind: Use forall_children in reinit_after_fork()
       via  0e6d3a5 winbind: Use forall_children in winbind_msg_ip_dropped_parent()
       via  dba9a12 winbind: Use forall_domain_children in winbind_msg_online
       via  0c58fb3 winbind: Use forall_domain_children in winbind_msg_offline()
       via  815bdc6 winbind: Remove unused winbindd_internal_child()
       via  723560a winbind: "internal" children never have a domain set
       via  94c0221 winbind: Use forall_children in winbind_child_died()
       via  4f76a1d winbind: Implement forall_children()
       via  6a65ea9 third_party: Add missing config.h in libpamtest
       via  0cf640a third_party: Update pam_wrapper to version 1.0.5
       via  ea3a80e domain.py: Give some advice if the schema upgrade command fails
       via  79d70d9 Remove some bashisms from the test scripts
       via  43ca89b tests/dbcheck: Provision using the old schema and ignore displayName
      from  1aabfff libsmb: Remove incorrect fall through comment in trusts_util.c

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit c38062604b7884fa97e63ad28ed2f2a86880d022
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Feb 26 15:32:05 2018 +0100

    winbind: Fix --ping-dc error handling
    
    If the child dies at the wrong moment, we get an error in the "req" itself.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13309
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    
    Autobuild-User(master): Andreas Schneider <asn at cryptomilk.org>
    Autobuild-Date(master): Thu Mar  1 14:48:19 CET 2018 on sn-devel-144

commit 49adb5ac8fed5ec972bf3907169d2efd378970ca
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Feb 26 15:12:14 2018 +0100

    winbind: Fix a race between the sigchld and 0-sized socket read
    
    Fix a bug when a child dies when a request is pending in the child. If the
    signal handler fires before epoll finds out the other end of the parent-child
    socket is closed, we close the socket on our side without taking care of the
    pending request. This causes two problems: First, that one pending request
    never is replied to properly, and secondly, we might end up with EPOLL_DEL on a
    wrong file descriptor. This causes all sorts of trouble if we hit an active
    one.
    
    The fix for this problem is not to close the socket in winbind_child_died().
    This however stops an idle child that dies hard from being properly cleaned up.
    The fix for that is to add the child->monitor_fde that is set pending only when
    no child request is active. This way we can remove the close(sock) in the
    signal handler.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13309
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 33f5f5c4610f1a249c2dc88848e4262e2f343c94
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Feb 26 13:48:24 2018 +0100

    winbind: Remove the "winbindd_children" global
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13309
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 09677053f7f0e3a6c007a59b9ac08fc159f79c9d
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Feb 26 13:45:01 2018 +0100

    winbind: Use forall_children in reinit_after_fork()
    
    This removes the special handling for idmap_child() after the "This is
    a little tricky" comment. I believe this was not required at all, the
    idmap_child is part of the winbindd_children list.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13309
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 0e6d3a59eb9d526018852ee0a349e64d51eb0f56
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Feb 26 13:37:05 2018 +0100

    winbind: Use forall_children in winbind_msg_ip_dropped_parent()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13309
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit dba9a12e304d305a91c336681a34637bc41ac90b
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Feb 26 13:24:50 2018 +0100

    winbind: Use forall_domain_children in winbind_msg_online
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13309
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 0c58fb365a9652544b0fd40b52a79e641933a528
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Feb 26 13:20:25 2018 +0100

    winbind: Use forall_domain_children in winbind_msg_offline()
    
    Note that we only walk the domain children, which all have
    child->domain != NULL. So we don't need that check anymore.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13309
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 815bdc65a2938dc00af2be1931918dbe40394dcb
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Feb 26 13:15:14 2018 +0100

    winbind: Remove unused winbindd_internal_child()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13309
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 723560aed2082fefdb0f9d27548fda200438bc8a
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Feb 26 13:14:21 2018 +0100

    winbind: "internal" children never have a domain set
    
    Look at setup_domain_child(): There we always set child->domain. The only other
    two children are the idmap and locator children, which don't have a domain set.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13309
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 94c02211f92000d84efabac98cc6f3341a49ae76
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Feb 26 12:59:06 2018 +0100

    winbind: Use forall_children in winbind_child_died()
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13309
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 4f76a1deae60f7725f7e4307549de3d097a59236
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Feb 26 12:55:31 2018 +0100

    winbind: Implement forall_children()
    
    Step 0 in removing winbindd_children as a variable: We have access to
    all children via our domain list and the two explicit children. There's
    no need to separately maintain a list of winbind children. Maintaining
    child->pid != 0 is sufficient to make sure we only walk active children.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13309
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 6a65ea900d48347fbdec253cc5a6dadd613bbada
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Feb 27 09:18:36 2018 +0100

    third_party: Add missing config.h in libpamtest
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit 0cf640a2f401d43421d4d8c244bdb50da8bebd86
Author: Andreas Schneider <asn at samba.org>
Date:   Thu Feb 22 17:00:14 2018 +0100

    third_party: Update pam_wrapper to version 1.0.5
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit ea3a80e66967cab13a664c50ae5f7d23be805e22
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Wed Feb 28 12:38:12 2018 +1300

    domain.py: Give some advice if the schema upgrade command fails
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 79d70d98089e5b3813b645214d7407183c26cb87
Author: Timur I. Bakeyev <timur at iXsystems.com>
Date:   Mon Dec 11 02:47:21 2017 +0100

    Remove some bashisms from the test scripts
    
    Signed-off-by: Timur I. Bakeyev <timur at iXsystems.com>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andreas Schneider <asn at samba.org>

commit 43ca89b46bc76d10fb9bfda1d4ac7d16cf55b689
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Wed Feb 28 12:17:46 2018 +1300

    tests/dbcheck: Provision using the old schema and ignore displayName
    
    These tests are currently not run on Ubuntu due to bashisms in the test.
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Andreas Schneider <asn at samba.org>

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

Summary of changes:
 python/samba/netcmd/domain.py              |  11 +-
 source3/winbindd/winbindd.h                |   3 +-
 source3/winbindd/winbindd_dual.c           | 340 +++++++++++++++++++----------
 source3/winbindd/winbindd_ndr.c            |   2 -
 source3/winbindd/winbindd_ping_dc.c        |   5 +
 source3/winbindd/winbindd_proto.h          |   1 -
 source3/winbindd/winbindd_util.c           |  12 -
 testprogs/blackbox/dbcheck-oldrelease.sh   |  13 +-
 third_party/pam_wrapper/libpamtest.c       |   2 +
 third_party/pam_wrapper/pam_wrapper.c      |  67 +++---
 third_party/pam_wrapper/python/pypamtest.c |   2 +
 third_party/pam_wrapper/wscript            |   2 +-
 12 files changed, 284 insertions(+), 176 deletions(-)


Changeset truncated at 500 lines:

diff --git a/python/samba/netcmd/domain.py b/python/samba/netcmd/domain.py
index 7b23fa7..d3b9b0c 100644
--- a/python/samba/netcmd/domain.py
+++ b/python/samba/netcmd/domain.py
@@ -4150,9 +4150,14 @@ class cmd_domain_schema_upgrade(Command):
                 # Apply patches if we parsed the Schema-Updates.md file
                 diff = os.path.abspath(os.path.join(diff_dir, update + '.diff'))
                 if temp_folder and os.path.exists(diff):
-                    p = subprocess.Popen(['patch', update, '-i', diff],
-                                         stdout=subprocess.PIPE,
-                                         stderr=subprocess.PIPE, cwd=temp_folder)
+                    try:
+                        p = subprocess.Popen(['patch', update, '-i', diff],
+                                             stdout=subprocess.PIPE,
+                                             stderr=subprocess.PIPE, cwd=temp_folder)
+                    except (OSError, IOError):
+                        shutil.rmtree(temp_folder)
+                        raise CommandError("Failed to upgrade schema. Check if 'patch' is installed.")
+
                     stdout, stderr = p.communicate()
 
                     if p.returncode:
diff --git a/source3/winbindd/winbindd.h b/source3/winbindd/winbindd.h
index 081722f..f496c41 100644
--- a/source3/winbindd/winbindd.h
+++ b/source3/winbindd/winbindd.h
@@ -115,13 +115,12 @@ struct winbindd_child_dispatch_table {
 };
 
 struct winbindd_child {
-	struct winbindd_child *next, *prev;
-
 	pid_t pid;
 	struct winbindd_domain *domain;
 	char *logfilename;
 
 	int sock;
+	struct tevent_fd *monitor_fde; /* Watch for dead children/sockets */
 	struct tevent_queue *queue;
 	struct dcerpc_binding_handle *binding_handle;
 
diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c
index fa34e73..2a4950b 100644
--- a/source3/winbindd/winbindd_dual.c
+++ b/source3/winbindd/winbindd_dual.c
@@ -46,7 +46,56 @@
 
 extern bool override_logfile;
 
-static struct winbindd_child *winbindd_children = NULL;
+static void forall_domain_children(bool (*fn)(struct winbindd_child *c,
+					      void *private_data),
+				   void *private_data)
+{
+	struct winbindd_domain *d;
+
+	for (d = domain_list(); d != NULL; d = d->next) {
+		int i;
+
+		for (i = 0; i < lp_winbind_max_domain_connections(); i++) {
+			struct winbindd_child *c = &d->children[i];
+			bool ok;
+
+			if (c->pid == 0) {
+				continue;
+			}
+
+			ok = fn(c, private_data);
+			if (!ok) {
+				return;
+			}
+		}
+	}
+}
+
+static void forall_children(bool (*fn)(struct winbindd_child *c,
+				       void *private_data),
+			    void *private_data)
+{
+	struct winbindd_child *c;
+	bool ok;
+
+	c = idmap_child();
+	if (c->pid != 0) {
+		ok = fn(c, private_data);
+		if (!ok) {
+			return;
+		}
+	}
+
+	c = locator_child();
+	if (c->pid != 0) {
+		ok = fn(c, private_data);
+		if (!ok) {
+			return;
+		}
+	}
+
+	forall_domain_children(fn, private_data);
+}
 
 /* Read some data from a client connection */
 
@@ -190,6 +239,8 @@ static void wb_child_request_waited(struct tevent_req *subreq)
 		return;
 	}
 
+	tevent_fd_set_flags(state->child->monitor_fde, 0);
+
 	subreq = wb_simple_trans_send(state, server_event_context(), NULL,
 				      state->child->sock, state->request);
 	if (tevent_req_nomem(subreq, req)) {
@@ -289,6 +340,8 @@ static void wb_child_request_cleanup(struct tevent_req *req,
 	TALLOC_FREE(state->subreq);
 	TALLOC_FREE(state->queue_subreq);
 
+	tevent_fd_set_flags(state->child->monitor_fde, TEVENT_FD_READ);
+
 	if (state->child->domain != NULL) {
 		/*
 		 * If the child is attached to a domain,
@@ -310,9 +363,34 @@ static void wb_child_request_cleanup(struct tevent_req *req,
 	 * The basic parent/child communication broke, close
 	 * our socket
 	 */
+	TALLOC_FREE(state->child->monitor_fde);
 	close(state->child->sock);
 	state->child->sock = -1;
-	DLIST_REMOVE(winbindd_children, state->child);
+}
+
+static void child_socket_readable(struct tevent_context *ev,
+				  struct tevent_fd *fde,
+				  uint16_t flags,
+				  void *private_data)
+{
+	struct winbindd_child *child = private_data;
+
+	if ((flags & TEVENT_FD_READ) == 0) {
+		return;
+	}
+
+	TALLOC_FREE(child->monitor_fde);
+
+	/*
+	 * We're only active when there is no outstanding child
+	 * request. Arriving here means the child closed its socket,
+	 * it died. Do the same here.
+	 */
+
+	SMB_ASSERT(child->sock != -1);
+
+	close(child->sock);
+	child->sock = -1;
 }
 
 static struct winbindd_child *choose_domain_child(struct winbindd_domain *domain)
@@ -709,6 +787,7 @@ void setup_child(struct winbindd_domain *domain, struct winbindd_child *child,
 			  "logname == NULL");
 	}
 
+	child->pid = 0;
 	child->sock = -1;
 	child->domain = domain;
 	child->table = table;
@@ -720,30 +799,35 @@ void setup_child(struct winbindd_domain *domain, struct winbindd_child *child,
 	}
 }
 
-void winbind_child_died(pid_t pid)
-{
+struct winbind_child_died_state {
+	pid_t pid;
 	struct winbindd_child *child;
+};
 
-	for (child = winbindd_children; child != NULL; child = child->next) {
-		if (child->pid == pid) {
-			break;
-		}
-	}
+static bool winbind_child_died_fn(struct winbindd_child *child,
+				  void *private_data)
+{
+	struct winbind_child_died_state *state = private_data;
 
-	if (child == NULL) {
-		DEBUG(5, ("Already reaped child %u died\n", (unsigned int)pid));
-		return;
+	if (child->pid == state->pid) {
+		state->child = child;
+		return false;
 	}
+	return true;
+}
 
-	/* This will be re-added in fork_domain_child() */
+void winbind_child_died(pid_t pid)
+{
+	struct winbind_child_died_state state = { .pid = pid };
 
-	DLIST_REMOVE(winbindd_children, child);
-	child->pid = 0;
+	forall_children(winbind_child_died_fn, &state);
 
-	if (child->sock != -1) {
-		close(child->sock);
-		child->sock = -1;
+	if (state.child == NULL) {
+		DEBUG(5, ("Already reaped child %u died\n", (unsigned int)pid));
+		return;
 	}
+
+	state.child->pid = 0;
 }
 
 /* Ensure any negative cache entries with the netbios or realm names are removed. */
@@ -762,31 +846,74 @@ void winbindd_flush_negative_conn_cache(struct winbindd_domain *domain)
  * level to that of parents.
  */
 
+struct winbind_msg_relay_state {
+	struct messaging_context *msg_ctx;
+	uint32_t msg_type;
+	DATA_BLOB *data;
+};
+
+static bool winbind_msg_relay_fn(struct winbindd_child *child,
+				 void *private_data)
+{
+	struct winbind_msg_relay_state *state = private_data;
+
+	DBG_DEBUG("sending message to pid %u.\n",
+		  (unsigned int)child->pid);
+
+	messaging_send(state->msg_ctx, pid_to_procid(child->pid),
+		       state->msg_type, state->data);
+	return true;
+}
+
 void winbind_msg_debug(struct messaging_context *msg_ctx,
  			 void *private_data,
 			 uint32_t msg_type,
 			 struct server_id server_id,
 			 DATA_BLOB *data)
 {
-	struct winbindd_child *child;
+	struct winbind_msg_relay_state state = {
+		.msg_ctx = msg_ctx, .msg_type = msg_type, .data = data
+	};
 
 	DEBUG(10,("winbind_msg_debug: got debug message.\n"));
 
 	debug_message(msg_ctx, private_data, MSG_DEBUG, server_id, data);
 
-	for (child = winbindd_children; child != NULL; child = child->next) {
+	forall_children(winbind_msg_relay_fn, &state);
+}
 
-		DEBUG(10,("winbind_msg_debug: sending message to pid %u.\n",
-			(unsigned int)child->pid));
+/* Set our domains as offline and forward the offline message to our children. */
+
+struct winbind_msg_on_offline_state {
+	struct messaging_context *msg_ctx;
+	uint32_t msg_type;
+};
 
-		messaging_send_buf(msg_ctx, pid_to_procid(child->pid),
-			   MSG_DEBUG,
-			   data->data,
-			   strlen((char *) data->data) + 1);
+static bool winbind_msg_on_offline_fn(struct winbindd_child *child,
+				      void *private_data)
+{
+	struct winbind_msg_on_offline_state *state = private_data;
+
+	if (child->domain->internal) {
+		return true;
 	}
-}
 
-/* Set our domains as offline and forward the offline message to our children. */
+	/*
+	 * Each winbindd child should only process requests for one
+	 * domain - make sure we only set it online / offline for that
+	 * domain.
+	 */
+	DBG_DEBUG("sending message to pid %u for domain %s.\n",
+		  (unsigned int)child->pid, child->domain->name);
+
+	messaging_send_buf(state->msg_ctx,
+			   pid_to_procid(child->pid),
+			   state->msg_type,
+			   (const uint8_t *)child->domain->name,
+			   strlen(child->domain->name)+1);
+
+	return true;
+}
 
 void winbind_msg_offline(struct messaging_context *msg_ctx,
 			 void *private_data,
@@ -794,7 +921,10 @@ void winbind_msg_offline(struct messaging_context *msg_ctx,
 			 struct server_id server_id,
 			 DATA_BLOB *data)
 {
-	struct winbindd_child *child;
+	struct winbind_msg_on_offline_state state = {
+		.msg_ctx = msg_ctx,
+		.msg_type = MSG_WINBIND_OFFLINE,
+	};
 	struct winbindd_domain *domain;
 
 	DEBUG(10,("winbind_msg_offline: got offline message.\n"));
@@ -819,29 +949,7 @@ void winbind_msg_offline(struct messaging_context *msg_ctx,
 		set_domain_offline(domain);
 	}
 
-	for (child = winbindd_children; child != NULL; child = child->next) {
-		/* Don't send message to internal children.  We've already
-		   done so above. */
-		if (!child->domain || winbindd_internal_child(child)) {
-			continue;
-		}
-
-		/* Or internal domains (this should not be possible....) */
-		if (child->domain->internal) {
-			continue;
-		}
-
-		/* Each winbindd child should only process requests for one domain - make sure
-		   we only set it online / offline for that domain. */
-
-		DEBUG(10,("winbind_msg_offline: sending message to pid %u for domain %s.\n",
-			(unsigned int)child->pid, child->domain->name ));
-
-		messaging_send_buf(msg_ctx, pid_to_procid(child->pid),
-				   MSG_WINBIND_OFFLINE,
-				   (const uint8_t *)child->domain->name,
-				   strlen(child->domain->name)+1);
-	}
+	forall_domain_children(winbind_msg_on_offline_fn, &state);
 }
 
 /* Set our domains as online and forward the online message to our children. */
@@ -852,7 +960,10 @@ void winbind_msg_online(struct messaging_context *msg_ctx,
 			struct server_id server_id,
 			DATA_BLOB *data)
 {
-	struct winbindd_child *child;
+	struct winbind_msg_on_offline_state state = {
+		.msg_ctx = msg_ctx,
+		.msg_type = MSG_WINBIND_ONLINE,
+	};
 	struct winbindd_domain *domain;
 
 	DEBUG(10,("winbind_msg_online: got online message.\n"));
@@ -894,28 +1005,7 @@ void winbind_msg_online(struct messaging_context *msg_ctx,
 		}
 	}
 
-	for (child = winbindd_children; child != NULL; child = child->next) {
-		/* Don't send message to internal childs. */
-		if (!child->domain || winbindd_internal_child(child)) {
-			continue;
-		}
-
-		/* Or internal domains (this should not be possible....) */
-		if (child->domain->internal) {
-			continue;
-		}
-
-		/* Each winbindd child should only process requests for one domain - make sure
-		   we only set it online / offline for that domain. */
-
-		DEBUG(10,("winbind_msg_online: sending message to pid %u for domain %s.\n",
-			(unsigned int)child->pid, child->domain->name ));
-
-		messaging_send_buf(msg_ctx, pid_to_procid(child->pid),
-				   MSG_WINBIND_ONLINE,
-				   (const uint8_t *)child->domain->name,
-				   strlen(child->domain->name)+1);
-	}
+	forall_domain_children(winbind_msg_on_offline_fn, &state);
 }
 
 static const char *collect_onlinestatus(TALLOC_CTX *mem_ctx)
@@ -1349,11 +1439,45 @@ static void child_msg_online(struct messaging_context *msg,
 	}
 }
 
+struct winbindd_reinit_after_fork_state {
+	const struct winbindd_child *myself;
+};
+
+static bool winbindd_reinit_after_fork_fn(struct winbindd_child *child,
+					  void *private_data)
+{
+	struct winbindd_reinit_after_fork_state *state = private_data;
+
+	if (child == state->myself) {
+		return true;
+	}
+
+	/* Destroy all possible events in child list. */
+	TALLOC_FREE(child->lockout_policy_event);
+	TALLOC_FREE(child->machine_password_change_event);
+
+	/*
+	 * Children should never be able to send each other messages,
+	 * all messages must go through the parent.
+	 */
+	child->pid = (pid_t)0;
+
+	/*
+	 * Close service sockets to all other children
+	 */
+	if (child->sock != -1) {
+		close(child->sock);
+		child->sock = -1;
+	}
+
+	return true;
+}
+
 NTSTATUS winbindd_reinit_after_fork(const struct winbindd_child *myself,
 				    const char *logfilename)
 {
+	struct winbindd_reinit_after_fork_state state = { .myself = myself };
 	struct winbindd_domain *domain;
-	struct winbindd_child *cl;
 	NTSTATUS status;
 
 	status = reinit_after_fork(
@@ -1417,43 +1541,7 @@ NTSTATUS winbindd_reinit_after_fork(const struct winbindd_child *myself,
 
 	ccache_remove_all_after_fork();
 
-	/* Destroy all possible events in child list. */
-	for (cl = winbindd_children; cl != NULL; cl = cl->next) {
-		TALLOC_FREE(cl->lockout_policy_event);
-		TALLOC_FREE(cl->machine_password_change_event);
-
-		/* Children should never be able to send
-		 * each other messages, all messages must
-		 * go through the parent.
-		 */
-		cl->pid = (pid_t)0;
-
-		/*
-		 * Close service sockets to all other children
-		 */
-		if ((cl != myself) && (cl->sock != -1)) {
-			close(cl->sock);
-			cl->sock = -1;
-		}
-        }
-	/*
-	 * This is a little tricky, children must not
-	 * send an MSG_WINBIND_ONLINE message to idmap_child().
-	 * If we are in a child of our primary domain or
-	 * in the process created by fork_child_dc_connect(),
-	 * and the primary domain cannot go online,
-	 * fork_child_dc_connection() sends MSG_WINBIND_ONLINE
-	 * periodically to idmap_child().
-	 *
-	 * The sequence is, fork_child_dc_connect() ---> getdcs() --->
-	 * get_dc_name_via_netlogon() ---> cm_connect_netlogon()
-	 * ---> init_dc_connection() ---> cm_open_connection --->
-	 * set_domain_online(), sends MSG_WINBIND_ONLINE to
-	 * idmap_child(). Disallow children sending messages
-	 * to each other, all messages must go through the parent.
-	 */
-	cl = idmap_child();
-	cl->pid = (pid_t)0;
+	forall_children(winbindd_reinit_after_fork_fn, &state);
 
 	return NT_STATUS_OK;
 }
@@ -1567,8 +1655,18 @@ static bool fork_domain_child(struct winbindd_child *child)
 			return false;
 		}
 
-		child->next = child->prev = NULL;
-		DLIST_ADD(winbindd_children, child);
+		child->monitor_fde = tevent_add_fd(server_event_context(),
+						   server_event_context(),
+						   fdpair[1],
+						   TEVENT_FD_READ,
+						   child_socket_readable,
+						   child);
+		if (child->monitor_fde == NULL) {
+			DBG_WARNING("tevent_add_fd failed\n");
+			close(fdpair[1]);
+			return false;
+		}
+
 		child->sock = fdpair[1];
 		return True;
 	}


-- 
Samba Shared Repository



More information about the samba-cvs mailing list