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 <[email protected]>
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 <[email protected]>
    Reviewed-by: Andreas Schneider <[email protected]>
    
    Autobuild-User(master): Andreas Schneider <[email protected]>
    Autobuild-Date(master): Thu Mar  1 14:48:19 CET 2018 on sn-devel-144

commit 49adb5ac8fed5ec972bf3907169d2efd378970ca
Author: Volker Lendecke <[email protected]>
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 <[email protected]>
    Reviewed-by: Andreas Schneider <[email protected]>

commit 33f5f5c4610f1a249c2dc88848e4262e2f343c94
Author: Volker Lendecke <[email protected]>
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 <[email protected]>
    Reviewed-by: Andreas Schneider <[email protected]>

commit 09677053f7f0e3a6c007a59b9ac08fc159f79c9d
Author: Volker Lendecke <[email protected]>
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 <[email protected]>
    Reviewed-by: Andreas Schneider <[email protected]>

commit 0e6d3a59eb9d526018852ee0a349e64d51eb0f56
Author: Volker Lendecke <[email protected]>
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 <[email protected]>
    Reviewed-by: Andreas Schneider <[email protected]>

commit dba9a12e304d305a91c336681a34637bc41ac90b
Author: Volker Lendecke <[email protected]>
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 <[email protected]>
    Reviewed-by: Andreas Schneider <[email protected]>

commit 0c58fb365a9652544b0fd40b52a79e641933a528
Author: Volker Lendecke <[email protected]>
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 <[email protected]>
    Reviewed-by: Andreas Schneider <[email protected]>

commit 815bdc65a2938dc00af2be1931918dbe40394dcb
Author: Volker Lendecke <[email protected]>
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 <[email protected]>
    Reviewed-by: Andreas Schneider <[email protected]>

commit 723560aed2082fefdb0f9d27548fda200438bc8a
Author: Volker Lendecke <[email protected]>
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 <[email protected]>
    Reviewed-by: Andreas Schneider <[email protected]>

commit 94c02211f92000d84efabac98cc6f3341a49ae76
Author: Volker Lendecke <[email protected]>
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 <[email protected]>
    Reviewed-by: Andreas Schneider <[email protected]>

commit 4f76a1deae60f7725f7e4307549de3d097a59236
Author: Volker Lendecke <[email protected]>
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 <[email protected]>
    Reviewed-by: Andreas Schneider <[email protected]>

commit 6a65ea900d48347fbdec253cc5a6dadd613bbada
Author: Andreas Schneider <[email protected]>
Date:   Tue Feb 27 09:18:36 2018 +0100

    third_party: Add missing config.h in libpamtest
    
    Signed-off-by: Andreas Schneider <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit 0cf640a2f401d43421d4d8c244bdb50da8bebd86
Author: Andreas Schneider <[email protected]>
Date:   Thu Feb 22 17:00:14 2018 +0100

    third_party: Update pam_wrapper to version 1.0.5
    
    Signed-off-by: Andreas Schneider <[email protected]>
    Reviewed-by: Ralph Boehme <[email protected]>

commit ea3a80e66967cab13a664c50ae5f7d23be805e22
Author: Garming Sam <[email protected]>
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 <[email protected]>
    Reviewed-by: Andreas Schneider <[email protected]>

commit 79d70d98089e5b3813b645214d7407183c26cb87
Author: Timur I. Bakeyev <[email protected]>
Date:   Mon Dec 11 02:47:21 2017 +0100

    Remove some bashisms from the test scripts
    
    Signed-off-by: Timur I. Bakeyev <[email protected]>
    Reviewed-by: Garming Sam <[email protected]>
    Reviewed-by: Andreas Schneider <[email protected]>

commit 43ca89b46bc76d10fb9bfda1d4ac7d16cf55b689
Author: Garming Sam <[email protected]>
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 <[email protected]>
    Reviewed-by: Andreas Schneider <[email protected]>

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

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

Reply via email to