s3: In winbind, close parent/child sockets
[samba.git] / source3 / winbindd / winbindd_dual.c
index 6465d849dd3bbf2ec1858f253c756618ea9111c6..47ab6c17b707991f5e43236ba9c9f3e2c3338470 100644 (file)
 
 #include "includes.h"
 #include "winbindd.h"
-#include "lib/wb_reqtrans.h"
-#include "librpc/gen_ndr/messaging.h"
+#include "nsswitch/wb_reqtrans.h"
 #include "secrets.h"
 #include "../lib/util/select.h"
 #include "../libcli/security/security.h"
+#include "system/select.h"
+#include "messages.h"
+#include "ntdomain.h"
+#include "../lib/util/tevent_unix.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_WINBIND
@@ -149,12 +152,7 @@ static void wb_child_request_trigger(struct tevent_req *req,
                return;
        }
        tevent_req_set_callback(subreq, wb_child_request_done, req);
-
-       if (!tevent_req_set_endtime(req, state->ev,
-                                   timeval_current_ofs(300, 0))) {
-               tevent_req_nomem(NULL, req);
-                return;
-        }
+       tevent_req_set_endtime(req, state->ev, timeval_current_ofs(300, 0));
 }
 
 static void wb_child_request_done(struct tevent_req *subreq)
@@ -1169,7 +1167,8 @@ static void child_msg_dump_event_list(struct messaging_context *msg,
        dump_event_list(winbind_event_context());
 }
 
-bool winbindd_reinit_after_fork(const char *logfilename)
+bool winbindd_reinit_after_fork(const struct winbindd_child *myself,
+                               const char *logfilename)
 {
        struct winbindd_domain *domain;
        struct winbindd_child *cl;
@@ -1244,6 +1243,14 @@ bool winbindd_reinit_after_fork(const char *logfilename)
                 * 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
@@ -1327,7 +1334,7 @@ static bool fork_domain_child(struct winbindd_child *child)
        state.sock = fdpair[0];
        close(fdpair[1]);
 
-       if (!winbindd_reinit_after_fork(child->logfilename)) {
+       if (!winbindd_reinit_after_fork(child, child->logfilename)) {
                _exit(0);
        }
 
@@ -1419,9 +1426,9 @@ static bool fork_domain_child(struct winbindd_child *child)
        while (1) {
 
                int ret;
-               fd_set r_fds;
-               fd_set w_fds;
-               int maxfd;
+               struct pollfd *pfds;
+               int num_pfds;
+               int timeout;
                struct timeval t;
                struct timeval *tp;
                TALLOC_CTX *frame = talloc_stackframe();
@@ -1429,7 +1436,7 @@ static bool fork_domain_child(struct winbindd_child *child)
                int iov_count;
                NTSTATUS status;
 
-               if (run_events(winbind_event_context(), 0, NULL, NULL)) {
+               if (run_events_poll(winbind_event_context(), 0, NULL, 0)) {
                        TALLOC_FREE(frame);
                        continue;
                }
@@ -1442,35 +1449,41 @@ static bool fork_domain_child(struct winbindd_child *child)
                        child->domain->startup = False;
                }
 
-               FD_ZERO(&r_fds);
-               FD_ZERO(&w_fds);
-               FD_SET(state.sock, &r_fds);
-               maxfd = state.sock;
+               pfds = TALLOC_ZERO_P(talloc_tos(), struct pollfd);
+               if (pfds == NULL) {
+                       DEBUG(1, ("talloc failed\n"));
+                       _exit(1);
+               }
 
-               /*
-                * Initialize this high as event_add_to_select_args()
-                * uses a timeval_min() on this and next_event. Fix
-                * from Roel van Meer <rolek@alt001.com>.
-                */
-               t.tv_sec = 999999;
-               t.tv_usec = 0;
-
-               event_add_to_select_args(winbind_event_context(),
-                                        &r_fds, &w_fds, &t, &maxfd);
+               pfds->fd = state.sock;
+               pfds->events = POLLIN|POLLHUP;
+               num_pfds = 1;
+
+               timeout = INT_MAX;
+
+               if (!event_add_to_poll_args(
+                           winbind_event_context(), talloc_tos(),
+                           &pfds, &num_pfds, &timeout)) {
+                       DEBUG(1, ("event_add_to_poll_args failed\n"));
+                       _exit(1);
+               }
                tp = get_timed_events_timeout(winbind_event_context(), &t);
                if (tp) {
                        DEBUG(11,("select will use timeout of %u.%u seconds\n",
                                (unsigned int)tp->tv_sec, (unsigned int)tp->tv_usec ));
                }
 
-               ret = sys_select(maxfd + 1, &r_fds, &w_fds, NULL, tp);
+               ret = sys_poll(pfds, num_pfds, timeout);
 
-               if (run_events(winbind_event_context(), ret, &r_fds, &w_fds)) {
+               if (run_events_poll(winbind_event_context(), ret,
+                                   pfds, num_pfds)) {
                        /* We got a signal - continue. */
                        TALLOC_FREE(frame);
                        continue;
                }
 
+               TALLOC_FREE(pfds);
+
                if (ret == 0) {
                        DEBUG(11,("nothing is ready yet, continue\n"));
                        TALLOC_FREE(frame);
@@ -1484,9 +1497,9 @@ static bool fork_domain_child(struct winbindd_child *child)
                }
 
                if (ret == -1 && errno != EINTR) {
-                       DEBUG(0,("select error occured\n"));
+                       DEBUG(0,("poll error occured\n"));
                        TALLOC_FREE(frame);
-                       perror("select");
+                       perror("poll");
                        _exit(1);
                }