Fix denial of service - memory corruption.
[samba.git] / source3 / winbindd / winbindd_dual.c
index 1385c76bae497a09ff94de217018d836c5daeff9..3eef3d39fd0d42400bb8b8a44508469516281177 100644 (file)
@@ -183,7 +183,7 @@ static void async_request_timeout_handler(struct event_context *ctx,
 
        DEBUG(0,("async_request_timeout_handler: child pid %u is not responding. "
                "Closing connection to it.\n",
-               state->child_pid ));
+               (unsigned int)state->child_pid ));
 
        /* Deal with the reply - set to error. */
        async_reply_recv(private_data, False);
@@ -1147,8 +1147,9 @@ bool winbindd_reinit_after_fork(const char *logfilename)
        struct winbindd_domain *domain;
        struct winbindd_child *cl;
 
-       if (!reinit_after_fork(winbind_messaging_context(),
-                              winbind_event_context(), true)) {
+       if (!NT_STATUS_IS_OK(reinit_after_fork(winbind_messaging_context(),
+                                              winbind_event_context(),
+                                              true))) {
                DEBUG(0,("reinit_after_fork() failed\n"));
                return false;
        }
@@ -1166,6 +1167,9 @@ bool winbindd_reinit_after_fork(const char *logfilename)
                                            logfilename))
                return false;
 
+       /* Stop zombies in children */
+       CatchChild();
+
        /* Don't handle the same messages as our parent. */
        messaging_deregister(winbind_messaging_context(),
                             MSG_SMB_CONF_UPDATED, NULL);
@@ -1281,9 +1285,6 @@ static bool fork_domain_child(struct winbindd_child *child)
 
        DEBUG(10, ("Child process %d\n", (int)sys_getpid()));
 
-       /* Stop zombies in children */
-       CatchChild();
-
        state.sock = fdpair[0];
        close(fdpair[1]);
 
@@ -1360,7 +1361,7 @@ static bool fork_domain_child(struct winbindd_child *child)
        }
 
        if (child->domain && child->domain->primary &&
-           !lp_use_kerberos_keytab() &&
+           !USE_KERBEROS_KEYTAB &&
            lp_server_role() == ROLE_DOMAIN_MEMBER) {
 
                struct timeval next_change;
@@ -1402,9 +1403,24 @@ static bool fork_domain_child(struct winbindd_child *child)
 
                FD_ZERO(&r_fds);
                FD_ZERO(&w_fds);
+
+               if (state.sock < 0 || state.sock >= FD_SETSIZE) {
+                       TALLOC_FREE(frame);
+                       perror("EBADF");
+                       _exit(1);
+               }
+
                FD_SET(state.sock, &r_fds);
                maxfd = state.sock;
 
+                /*
+                * 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(), &now,
                                         &r_fds, &w_fds, &t, &maxfd);
                tp = get_timed_events_timeout(winbind_event_context(), &t);