Copyright (C) Andrew Tridgell 2002
Copyright (C) Volker Lendecke 2004,2005
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
void *private_data;
};
+static void async_request_fail(struct winbindd_async_request *state);
static void async_main_request_sent(void *private_data, bool success);
static void async_request_sent(void *private_data, bool success);
static void async_reply_recv(void *private_data, bool success);
SMB_ASSERT(continuation != NULL);
+ DEBUG(10, ("Sending request to child pid %d (domain=%s)\n",
+ (int)child->pid,
+ (child->domain != NULL) ? child->domain->name : "''"));
+
state = TALLOC_P(mem_ctx, struct winbindd_async_request);
if (state == NULL) {
state->mem_ctx = mem_ctx;
state->child = child;
+ state->reply_timeout_event = NULL;
state->request = request;
state->response = response;
state->continuation = continuation;
if (!success) {
DEBUG(5, ("Could not send async request\n"));
-
- state->response->length = sizeof(struct winbindd_response);
- state->response->result = WINBINDD_ERROR;
- state->continuation(state->private_data, False);
+ async_request_fail(state);
return;
}
static void async_request_timeout_handler(struct event_context *ctx,
struct timed_event *te,
- const struct timeval *now,
+ struct timeval now,
void *private_data)
{
struct winbindd_async_request *state =
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);
TALLOC_FREE(state->reply_timeout_event);
- SMB_ASSERT(state->child_pid != (pid_t)0);
+ /* If child exists and is not already reaped,
+ send kill signal to child. */
- /* If not already reaped, send kill signal to child. */
- if (state->child->pid == state->child_pid) {
+ if ((state->child->pid != (pid_t)0) &&
+ (state->child->pid != (pid_t)-1) &&
+ (state->child->pid == state->child_pid)) {
kill(state->child_pid, SIGTERM);
/*
state->reply_timeout_event = event_add_timed(winbind_event_context(),
NULL,
timeval_current_ofs(300,0),
- "async_request_timeout",
async_request_timeout_handler,
state);
if (!state->reply_timeout_event) {
state->response));
cache_cleanup_response(state->child_pid);
-
+
DLIST_REMOVE(child->requests, state);
schedule_async_request(child);
return; /* Busy */
}
+ /*
+ * This may be a reschedule, so we might
+ * have an existing timeout event pending on
+ * the first entry in the child->requests list
+ * (we only send one request at a time).
+ * Ensure we free it before we reschedule.
+ * Bug #5814, from hargagan <shargagan@novell.com>.
+ * JRA.
+ */
+
+ TALLOC_FREE(request->reply_timeout_event);
+
if ((child->pid == 0) && (!fork_domain_child(child))) {
- /* Cancel all outstanding requests */
+ /* fork_domain_child failed.
+ Cancel all outstanding requests */
while (request != NULL) {
/* request might be free'd in the continuation */
struct winbindd_async_request *next = request->next;
- request->continuation(request->private_data, False);
+
+ async_request_fail(request);
request = next;
}
return;
/* This will be re-added in fork_domain_child() */
DLIST_REMOVE(children, child);
-
+
remove_fd_event(&child->event);
close(child->event.fd);
child->event.fd = 0;
child->event.flags = 0;
child->pid = 0;
+ if (child->requests) {
+ /*
+ * schedule_async_request() will also
+ * clear this event but the call is
+ * idempotent so it doesn't hurt to
+ * cover all possible future code
+ * paths. JRA.
+ */
+ TALLOC_FREE(child->requests->reply_timeout_event);
+ }
+
schedule_async_request(child);
}
}
}
+/*
+ * Parent winbindd process sets its own debug level first and then
+ * sends a message to all the winbindd children to adjust their debug
+ * level to that of parents.
+ */
+
+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;
+
+ DEBUG(10,("winbind_msg_debug: got debug message.\n"));
+
+ debug_message(msg_ctx, private_data, MSG_DEBUG, server_id, data);
+
+ for (child = children; child != NULL; child = child->next) {
+
+ DEBUG(10,("winbind_msg_debug: sending message to pid %u.\n",
+ (unsigned int)child->pid));
+
+ messaging_send_buf(msg_ctx, pid_to_procid(child->pid),
+ MSG_DEBUG,
+ data->data,
+ strlen((char *) data->data) + 1);
+ }
+}
+
/* Set our domains as offline and forward the offline message to our children. */
void winbind_msg_offline(struct messaging_context *msg_ctx,
if ( domain->primary ) {
struct winbindd_child *idmap = idmap_child();
-
+
if ( idmap->pid != 0 ) {
messaging_send_buf(msg_ctx,
pid_to_procid(idmap->pid),
(uint8 *)domain->name,
strlen(domain->name)+1);
}
-
}
}
}
}
-/* Forward the online/offline messages to our children. */
+static const char *collect_onlinestatus(TALLOC_CTX *mem_ctx)
+{
+ struct winbindd_domain *domain;
+ char *buf = NULL;
+
+ if ((buf = talloc_asprintf(mem_ctx, "global:%s ",
+ get_global_winbindd_state_offline() ?
+ "Offline":"Online")) == NULL) {
+ return NULL;
+ }
+
+ for (domain = domain_list(); domain; domain = domain->next) {
+ if ((buf = talloc_asprintf_append_buffer(buf, "%s:%s ",
+ domain->name,
+ domain->online ?
+ "Online":"Offline")) == NULL) {
+ return NULL;
+ }
+ }
+
+ buf = talloc_asprintf_append_buffer(buf, "\n");
+
+ DEBUG(5,("collect_onlinestatus: %s", buf));
+
+ return buf;
+}
+
void winbind_msg_onlinestatus(struct messaging_context *msg_ctx,
void *private_data,
uint32_t msg_type,
struct server_id server_id,
DATA_BLOB *data)
{
- struct winbindd_child *child;
+ TALLOC_CTX *mem_ctx;
+ const char *message;
+ struct server_id *sender;
+
+ DEBUG(5,("winbind_msg_onlinestatus received.\n"));
- DEBUG(10,("winbind_msg_onlinestatus: got onlinestatus message.\n"));
+ if (!data->data) {
+ return;
+ }
- for (child = children; child != NULL; child = child->next) {
- if (child->domain && child->domain->primary) {
- DEBUG(10,("winbind_msg_onlinestatus: "
- "sending message to pid %u of primary domain.\n",
- (unsigned int)child->pid));
- messaging_send_buf(msg_ctx, pid_to_procid(child->pid),
- MSG_WINBIND_ONLINESTATUS,
- (uint8 *)data->data,
- data->length);
- break;
- }
+ sender = (struct server_id *)data->data;
+
+ mem_ctx = talloc_init("winbind_msg_onlinestatus");
+ if (mem_ctx == NULL) {
+ return;
}
+
+ message = collect_onlinestatus(mem_ctx);
+ if (message == NULL) {
+ talloc_destroy(mem_ctx);
+ return;
+ }
+
+ messaging_send_buf(msg_ctx, *sender, MSG_WINBIND_ONLINESTATUS,
+ (uint8 *)message, strlen(message) + 1);
+
+ talloc_destroy(mem_ctx);
}
void winbind_msg_dump_event_list(struct messaging_context *msg_ctx,
static void account_lockout_policy_handler(struct event_context *ctx,
struct timed_event *te,
- const struct timeval *now,
+ struct timeval now,
void *private_data)
{
struct winbindd_child *child =
child->lockout_policy_event = event_add_timed(winbind_event_context(), NULL,
timeval_current_ofs(3600, 0),
- "account_lockout_policy_handler",
account_lockout_policy_handler,
child);
}
+static time_t get_machine_password_timeout(void)
+{
+ /* until we have gpo support use lp setting */
+ return lp_machine_password_timeout();
+}
+
+static bool calculate_next_machine_pwd_change(const char *domain,
+ struct timeval *t)
+{
+ time_t pass_last_set_time;
+ time_t timeout;
+ time_t next_change;
+ char *pw;
+
+ pw = secrets_fetch_machine_password(domain,
+ &pass_last_set_time,
+ NULL);
+
+ if (pw == NULL) {
+ DEBUG(0,("cannot fetch own machine password ????"));
+ return false;
+ }
+
+ SAFE_FREE(pw);
+
+ timeout = get_machine_password_timeout();
+ if (timeout == 0) {
+ DEBUG(10,("machine password never expires\n"));
+ return false;
+ }
+
+ if (time(NULL) < (pass_last_set_time + timeout)) {
+ next_change = pass_last_set_time + timeout;
+ DEBUG(10,("machine password still valid until: %s\n",
+ http_timestring(talloc_tos(), next_change)));
+ *t = timeval_set(next_change, 0);
+ return true;
+ }
+
+ DEBUG(10,("machine password expired, needs immediate change\n"));
+
+ *t = timeval_zero();
+
+ return true;
+}
+
+static void machine_password_change_handler(struct event_context *ctx,
+ struct timed_event *te,
+ struct timeval now,
+ void *private_data)
+{
+ struct winbindd_child *child =
+ (struct winbindd_child *)private_data;
+ struct rpc_pipe_client *netlogon_pipe = NULL;
+ TALLOC_CTX *frame;
+ NTSTATUS result;
+ struct timeval next_change;
+
+ DEBUG(10,("machine_password_change_handler called\n"));
+
+ TALLOC_FREE(child->machine_password_change_event);
+
+ if (!calculate_next_machine_pwd_change(child->domain->name,
+ &next_change)) {
+ return;
+ }
+
+ if (!winbindd_can_contact_domain(child->domain)) {
+ DEBUG(10,("machine_password_change_handler: Removing myself since I "
+ "do not have an incoming trust to domain %s\n",
+ child->domain->name));
+ return;
+ }
+
+ result = cm_connect_netlogon(child->domain, &netlogon_pipe);
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(10,("machine_password_change_handler: "
+ "failed to connect netlogon pipe: %s\n",
+ nt_errstr(result)));
+ return;
+ }
+
+ frame = talloc_stackframe();
+
+ result = trust_pw_find_change_and_store_it(netlogon_pipe,
+ frame,
+ child->domain->name);
+ TALLOC_FREE(frame);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(10,("machine_password_change_handler: "
+ "failed to change machine password: %s\n",
+ nt_errstr(result)));
+ } else {
+ DEBUG(10,("machine_password_change_handler: "
+ "successfully changed machine password\n"));
+ }
+
+ child->machine_password_change_event = event_add_timed(winbind_event_context(), NULL,
+ next_change,
+ machine_password_change_handler,
+ child);
+}
+
/* Deal with a request to go offline. */
static void child_msg_offline(struct messaging_context *msg,
DATA_BLOB *data)
{
struct winbindd_domain *domain;
+ struct winbindd_domain *primary_domain = NULL;
const char *domainname = (const char *)data->data;
if (data->data == NULL || data->length == 0) {
return;
}
+ primary_domain = find_our_domain();
+
/* Mark the requested domain offline. */
for (domain = domain_list(); domain; domain = domain->next) {
if (strequal(domain->name, domainname)) {
DEBUG(5,("child_msg_offline: marking %s offline.\n", domain->name));
set_domain_offline(domain);
+ /* we are in the trusted domain, set the primary domain
+ * offline too */
+ if (domain != primary_domain) {
+ set_domain_offline(primary_domain);
+ }
}
}
}
DATA_BLOB *data)
{
struct winbindd_domain *domain;
+ struct winbindd_domain *primary_domain = NULL;
const char *domainname = (const char *)data->data;
if (data->data == NULL || data->length == 0) {
return;
}
+ primary_domain = find_our_domain();
+
/* Set our global state as online. */
set_global_winbindd_state_online();
DEBUG(5,("child_msg_online: requesting %s to go online.\n", domain->name));
winbindd_flush_negative_conn_cache(domain);
set_domain_online_request(domain);
+
+ /* we can be in trusted domain, which will contact primary domain
+ * we have to bring primary domain online in trusted domain process
+ * see, winbindd_dual_pam_auth() --> winbindd_dual_pam_auth_samlogon()
+ * --> contact_domain = find_our_domain()
+ * */
+ if (domain != primary_domain) {
+ winbindd_flush_negative_conn_cache(primary_domain);
+ set_domain_online_request(primary_domain);
+ }
}
}
}
-static const char *collect_onlinestatus(TALLOC_CTX *mem_ctx)
+static void child_msg_dump_event_list(struct messaging_context *msg,
+ void *private_data,
+ uint32_t msg_type,
+ struct server_id server_id,
+ DATA_BLOB *data)
+{
+ DEBUG(5,("child_msg_dump_event_list received\n"));
+
+ dump_event_list(winbind_event_context());
+}
+
+bool winbindd_reinit_after_fork(const char *logfilename)
{
struct winbindd_domain *domain;
- char *buf = NULL;
+ struct winbindd_child *cl;
- if ((buf = talloc_asprintf(mem_ctx, "global:%s ",
- get_global_winbindd_state_offline() ?
- "Offline":"Online")) == NULL) {
- return NULL;
+ if (!reinit_after_fork(winbind_messaging_context(),
+ winbind_event_context(), true)) {
+ DEBUG(0,("reinit_after_fork() failed\n"));
+ return false;
}
- for (domain = domain_list(); domain; domain = domain->next) {
- if ((buf = talloc_asprintf_append_buffer(buf, "%s:%s ",
- domain->name,
- domain->online ?
- "Online":"Offline")) == NULL) {
- return NULL;
- }
+ close_conns_after_fork();
+
+ if (!override_logfile && logfilename) {
+ lp_set_logfile(logfilename);
+ reopen_logs();
}
- buf = talloc_asprintf_append_buffer(buf, "\n");
+ if (!winbindd_setup_sig_term_handler(false))
+ return false;
+ if (!winbindd_setup_sig_hup_handler(override_logfile ? NULL :
+ logfilename))
+ return false;
- DEBUG(5,("collect_onlinestatus: %s", buf));
+ /* Don't handle the same messages as our parent. */
+ messaging_deregister(winbind_messaging_context(),
+ MSG_SMB_CONF_UPDATED, NULL);
+ messaging_deregister(winbind_messaging_context(),
+ MSG_SHUTDOWN, NULL);
+ messaging_deregister(winbind_messaging_context(),
+ MSG_WINBIND_OFFLINE, NULL);
+ messaging_deregister(winbind_messaging_context(),
+ MSG_WINBIND_ONLINE, NULL);
+ messaging_deregister(winbind_messaging_context(),
+ MSG_WINBIND_ONLINESTATUS, NULL);
+ messaging_deregister(winbind_messaging_context(),
+ MSG_DUMP_EVENT_LIST, NULL);
+ messaging_deregister(winbind_messaging_context(),
+ MSG_WINBIND_DUMP_DOMAIN_LIST, NULL);
+ messaging_deregister(winbind_messaging_context(),
+ MSG_DEBUG, NULL);
- return buf;
-}
+ /* We have destroyed all events in the winbindd_event_context
+ * in reinit_after_fork(), so clean out all possible pending
+ * event pointers. */
-static void child_msg_onlinestatus(struct messaging_context *msg_ctx,
- void *private_data,
- uint32_t msg_type,
- struct server_id server_id,
- DATA_BLOB *data)
-{
- TALLOC_CTX *mem_ctx;
- const char *message;
- struct server_id *sender;
-
- DEBUG(5,("winbind_msg_onlinestatus received.\n"));
+ /* Deal with check_online_events. */
- if (!data->data) {
- return;
+ for (domain = domain_list(); domain; domain = domain->next) {
+ TALLOC_FREE(domain->check_online_event);
}
- sender = (struct server_id *)data->data;
+ /* Ensure we're not handling a credential cache event inherited
+ * from our parent. */
- mem_ctx = talloc_init("winbind_msg_onlinestatus");
- if (mem_ctx == NULL) {
- return;
- }
-
- message = collect_onlinestatus(mem_ctx);
- if (message == NULL) {
- talloc_destroy(mem_ctx);
- return;
- }
+ ccache_remove_all_after_fork();
- messaging_send_buf(msg_ctx, *sender, MSG_WINBIND_ONLINESTATUS,
- (uint8 *)message, strlen(message) + 1);
+ /* Destroy all possible events in child list. */
+ for (cl = children; cl != NULL; cl = cl->next) {
+ struct winbindd_async_request *request;
- talloc_destroy(mem_ctx);
-}
+ for (request = cl->requests; request; request = request->next) {
+ TALLOC_FREE(request->reply_timeout_event);
+ }
+ TALLOC_FREE(cl->lockout_policy_event);
+ TALLOC_FREE(cl->machine_password_change_event);
-static void child_msg_dump_event_list(struct messaging_context *msg,
- void *private_data,
- uint32_t msg_type,
- struct server_id server_id,
- DATA_BLOB *data)
-{
- DEBUG(5,("child_msg_dump_event_list received\n"));
+ /* Children should never be able to send
+ * each other messages, all messages must
+ * go through the parent.
+ */
+ cl->pid = (pid_t)0;
+ }
+ /*
+ * 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;
- dump_event_list(winbind_event_context());
+ return true;
}
-
static bool fork_domain_child(struct winbindd_child *child)
{
int fdpair[2];
struct winbindd_cli_state state;
- struct winbindd_domain *domain;
+ struct winbindd_domain *primary_domain = NULL;
if (child->domain) {
DEBUG(10, ("fork_domain_child called for domain '%s'\n",
ZERO_STRUCT(state);
state.pid = sys_getpid();
- /* Stop zombies */
- CatchChild();
-
child->pid = sys_fork();
if (child->pid == -1) {
DLIST_ADD(children, child);
child->event.fd = fdpair[1];
child->event.flags = 0;
- child->requests = NULL;
add_fd_event(&child->event);
return True;
}
/* Child */
+ DEBUG(10, ("Child process %d\n", (int)sys_getpid()));
+
+ /* Stop zombies in children */
+ CatchChild();
+
state.sock = fdpair[0];
close(fdpair[1]);
- if (!reinit_after_fork(winbind_messaging_context(), true)) {
- DEBUG(0,("reinit_after_fork() failed\n"));
+ if (!winbindd_reinit_after_fork(child->logfilename)) {
_exit(0);
}
- close_conns_after_fork();
-
- if (!override_logfile) {
- lp_set_logfile(child->logfilename);
- reopen_logs();
- }
-
- /*
- * For clustering, we need to re-init our ctdbd connection after the
- * fork
- */
- if (!NT_STATUS_IS_OK(messaging_reinit(winbind_messaging_context())))
- exit(1);
-
- /* Don't handle the same messages as our parent. */
- messaging_deregister(winbind_messaging_context(),
- MSG_SMB_CONF_UPDATED, NULL);
- messaging_deregister(winbind_messaging_context(),
- MSG_SHUTDOWN, NULL);
- messaging_deregister(winbind_messaging_context(),
- MSG_WINBIND_OFFLINE, NULL);
- messaging_deregister(winbind_messaging_context(),
- MSG_WINBIND_ONLINE, NULL);
- messaging_deregister(winbind_messaging_context(),
- MSG_WINBIND_ONLINESTATUS, NULL);
- messaging_deregister(winbind_messaging_context(),
- MSG_DUMP_EVENT_LIST, NULL);
- messaging_deregister(winbind_messaging_context(),
- MSG_WINBIND_DUMP_DOMAIN_LIST, NULL);
-
/* Handle online/offline messages. */
messaging_register(winbind_messaging_context(), NULL,
MSG_WINBIND_OFFLINE, child_msg_offline);
messaging_register(winbind_messaging_context(), NULL,
MSG_WINBIND_ONLINE, child_msg_online);
- messaging_register(winbind_messaging_context(), NULL,
- MSG_WINBIND_ONLINESTATUS, child_msg_onlinestatus);
messaging_register(winbind_messaging_context(), NULL,
MSG_DUMP_EVENT_LIST, child_msg_dump_event_list);
+ messaging_register(winbind_messaging_context(), NULL,
+ MSG_DEBUG, debug_message);
+
+ primary_domain = find_our_domain();
+ if (primary_domain == NULL) {
+ smb_panic("no primary domain found");
+ }
+
+ /* It doesn't matter if we allow cache login,
+ * try to bring domain online after fork. */
if ( child->domain ) {
child->domain->startup = True;
child->domain->startup_time = time(NULL);
- }
-
- /* Ensure we have no pending check_online events other
- than one for this domain. */
-
- for (domain = domain_list(); domain; domain = domain->next) {
- if (domain != child->domain) {
- TALLOC_FREE(domain->check_online_event);
+ /* we can be in primary domain or in trusted domain
+ * If we are in trusted domain, set the primary domain
+ * in start-up mode */
+ if (!(child->domain->internal)) {
+ set_domain_online_request(child->domain);
+ if (!(child->domain->primary)) {
+ primary_domain->startup = True;
+ primary_domain->startup_time = time(NULL);
+ set_domain_online_request(primary_domain);
+ }
}
}
- /* Ensure we're not handling an event inherited from
- our parent. */
-
- cancel_named_event(winbind_event_context(),
- "krb5_ticket_refresh_handler");
+ /*
+ * We are in idmap child, make sure that we set the
+ * check_online_event to bring primary domain online.
+ */
+ if (child == idmap_child()) {
+ set_domain_online_request(primary_domain);
+ }
/* We might be in the idmap child...*/
if (child->domain && !(child->domain->internal) &&
set_domain_online_request(child->domain);
+ if (primary_domain && (primary_domain != child->domain)) {
+ /* We need to talk to the primary
+ * domain as well as the trusted
+ * domain inside a trusted domain
+ * child.
+ * See the code in :
+ * set_dc_type_and_flags_trustinfo()
+ * for details.
+ */
+ set_domain_online_request(primary_domain);
+ }
+
child->lockout_policy_event = event_add_timed(
winbind_event_context(), NULL, timeval_zero(),
- "account_lockout_policy_handler",
account_lockout_policy_handler,
child);
}
- /* Special case for Winbindd on a Samba DC,
- * We want to make sure the child can connect to smbd
- * but not the main daemon */
+ if (child->domain && child->domain->primary &&
+ !USE_KERBEROS_KEYTAB &&
+ lp_server_role() == ROLE_DOMAIN_MEMBER) {
+
+ struct timeval next_change;
- if (child->domain && child->domain->internal && IS_DC) {
- child->domain->methods = &cache_methods;
- child->domain->online = False;
+ if (calculate_next_machine_pwd_change(child->domain->name,
+ &next_change)) {
+ child->machine_password_change_event = event_add_timed(
+ winbind_event_context(), NULL, next_change,
+ machine_password_change_handler,
+ child);
+ }
}
while (1) {
int ret;
- fd_set read_fds;
+ fd_set r_fds;
+ fd_set w_fds;
+ int maxfd;
struct timeval t;
struct timeval *tp;
struct timeval now;
TALLOC_CTX *frame = talloc_stackframe();
- /* check for signals */
- winbind_check_sigterm();
- winbind_check_sighup();
-
- run_events(winbind_event_context(), 0, NULL, NULL);
+ if (run_events(winbind_event_context(), 0, NULL, NULL)) {
+ TALLOC_FREE(frame);
+ continue;
+ }
GetTimeOfDay(&now);
child->domain->startup = False;
}
+ FD_ZERO(&r_fds);
+ FD_ZERO(&w_fds);
+ FD_SET(state.sock, &r_fds);
+ maxfd = state.sock;
+
+ event_add_to_select_args(winbind_event_context(), &now,
+ &r_fds, &w_fds, &t, &maxfd);
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 ));
}
- /* Handle messages */
-
- message_dispatch(winbind_messaging_context());
+ ret = sys_select(maxfd + 1, &r_fds, &w_fds, NULL, tp);
- FD_ZERO(&read_fds);
- FD_SET(state.sock, &read_fds);
-
- ret = sys_select(state.sock + 1, &read_fds, NULL, NULL, tp);
+ if (run_events(winbind_event_context(), ret, &r_fds, &w_fds)) {
+ /* We got a signal - continue. */
+ TALLOC_FREE(frame);
+ continue;
+ }
if (ret == 0) {
DEBUG(11,("nothing is ready yet, continue\n"));
DEBUG(0,("select error occured\n"));
TALLOC_FREE(frame);
perror("select");
- return False;
+ _exit(1);
}
/* fetch a request from the main daemon */
if (state.finished) {
/* we lost contact with our parent */
- exit(0);
+ _exit(0);
}
DEBUG(4,("child daemon request %d\n", (int)state.request.cmd));
cache_store_response(sys_getpid(), &state.response);
- SAFE_FREE(state.response.extra_data.data);
-
/* We just send the result code back, the result
* structure needs to be fetched via the
* winbindd_cache. Hmm. That needs fixing... */