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);
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;
}
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;
/* Set our domains as offline and forward the offline message to our children. */
-void winbind_msg_offline(struct messaging_context *msg_ctx,
- void *private_data,
- uint32_t msg_type,
- struct server_id server_id,
- DATA_BLOB *data)
+void winbind_msg_offline(int msg_type, struct process_id src,
+ void *buf, size_t len, void *private_data)
{
struct winbindd_child *child;
struct winbindd_domain *domain;
}
DEBUG(5,("winbind_msg_offline: marking %s offline.\n", domain->name));
set_domain_offline(domain);
+
+ /* Send an offline message to the idmap child when our
+ primary domain goes offline */
+
+ if ( domain->primary ) {
+ struct winbindd_child *idmap = idmap_child();
+
+ if ( idmap->pid != 0 ) {
+ message_send_pid(pid_to_procid(idmap->pid),
+ MSG_WINBIND_OFFLINE,
+ domain->name,
+ strlen(domain->name)+1,
+ False);
+ }
+ }
}
for (child = children; child != NULL; child = child->next) {
DEBUG(10,("winbind_msg_offline: sending message to pid %u for domain %s.\n",
(unsigned int)child->pid, domain->name ));
- messaging_send_buf(msg_ctx, pid_to_procid(child->pid),
- MSG_WINBIND_OFFLINE,
- (uint8 *)child->domain->name,
- strlen(child->domain->name)+1);
+ message_send_pid(pid_to_procid(child->pid), MSG_WINBIND_OFFLINE, child->domain->name,
+ strlen(child->domain->name)+1, False);
}
}
/* Set our domains as online and forward the online message to our children. */
-void winbind_msg_online(struct messaging_context *msg_ctx,
- void *private_data,
- uint32_t msg_type,
- struct server_id server_id,
- DATA_BLOB *data)
+void winbind_msg_online(int msg_type, struct process_id src,
+ void *buf, size_t len, void *private_data)
{
struct winbindd_child *child;
struct winbindd_domain *domain;
struct winbindd_child *idmap = idmap_child();
if ( idmap->pid != 0 ) {
- messaging_send_buf(msg_ctx,
- pid_to_procid(idmap->pid),
- MSG_WINBIND_ONLINE,
- (uint8 *)domain->name,
- strlen(domain->name)+1);
+ message_send_pid(pid_to_procid(idmap->pid),
+ MSG_WINBIND_ONLINE,
+ domain->name,
+ strlen(domain->name)+1,
+ False);
}
}
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,
- (uint8 *)child->domain->name,
- strlen(child->domain->name)+1);
+ message_send_pid(pid_to_procid(child->pid), MSG_WINBIND_ONLINE, child->domain->name,
+ strlen(child->domain->name)+1, False);
}
}
/* Forward the online/offline messages to our children. */
-void winbind_msg_onlinestatus(struct messaging_context *msg_ctx,
- void *private_data,
- uint32_t msg_type,
- struct server_id server_id,
- DATA_BLOB *data)
+void winbind_msg_onlinestatus(int msg_type, struct process_id src,
+ void *buf, size_t len, void *private_data)
{
struct winbindd_child *child;
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);
+ message_send_pid(pid_to_procid(child->pid),
+ MSG_WINBIND_ONLINESTATUS, buf, len, False);
break;
}
}
}
-void winbind_msg_dump_event_list(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_dump_event_list received\n"));
-
- dump_event_list(winbind_event_context());
-
- for (child = children; child != NULL; child = child->next) {
-
- DEBUG(10,("winbind_msg_dump_event_list: sending message to pid %u\n",
- (unsigned int)child->pid));
-
- messaging_send_buf(msg_ctx, pid_to_procid(child->pid),
- MSG_DUMP_EVENT_LIST,
- NULL, 0);
- }
-
-}
static void account_lockout_policy_handler(struct event_context *ctx,
struct timed_event *te,
TALLOC_FREE(child->lockout_policy_event);
- if ( !winbindd_can_contact_domain( child->domain ) ) {
- DEBUG(10,("account_lockout_policy_handler: Removing myself since I "
- "do not have an incoming trust to domain %s\n",
- child->domain->name));
-
- return;
- }
-
methods = child->domain->methods;
mem_ctx = talloc_init("account_lockout_policy_handler ctx");
/* Deal with a request to go offline. */
-static void child_msg_offline(struct messaging_context *msg,
- void *private_data,
- uint32_t msg_type,
- struct server_id server_id,
- DATA_BLOB *data)
+static void child_msg_offline(int msg_type, struct process_id src,
+ void *buf, size_t len, void *private_data)
{
struct winbindd_domain *domain;
- const char *domainname = (const char *)data->data;
+ const char *domainname = (const char *)buf;
- if (data->data == NULL || data->length == 0) {
+ if (buf == NULL || len == 0) {
return;
}
return;
}
+ /* Set our global state as offline. */
+ if (!set_global_winbindd_state_offline()) {
+ DEBUG(10,("child_msg_offline: offline request failed.\n"));
+ return;
+ }
+
/* Mark the requested domain offline. */
for (domain = domain_list(); domain; domain = domain->next) {
/* Deal with a request to go online. */
-static void child_msg_online(struct messaging_context *msg,
- void *private_data,
- uint32_t msg_type,
- struct server_id server_id,
- DATA_BLOB *data)
+static void child_msg_online(int msg_type, struct process_id src,
+ void *buf, size_t len, void *private_data)
{
struct winbindd_domain *domain;
- const char *domainname = (const char *)data->data;
+ const char *domainname = (const char *)buf;
- if (data->data == NULL || data->length == 0) {
+ if (buf == NULL || len == 0) {
return;
}
return buf;
}
-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)
+static void child_msg_onlinestatus(int msg_type, struct process_id src,
+ void *buf, size_t len, void *private_data)
{
TALLOC_CTX *mem_ctx;
const char *message;
- struct server_id *sender;
+ struct process_id *sender;
DEBUG(5,("winbind_msg_onlinestatus received.\n"));
- if (!data->data) {
+ if (!buf) {
return;
}
- sender = (struct server_id *)data->data;
+ sender = (struct process_id *)buf;
mem_ctx = talloc_init("winbind_msg_onlinestatus");
if (mem_ctx == NULL) {
return;
}
- messaging_send_buf(msg_ctx, *sender, MSG_WINBIND_ONLINESTATUS,
- (uint8 *)message, strlen(message) + 1);
+ message_send_pid(*sender, MSG_WINBIND_ONLINESTATUS,
+ message, strlen(message) + 1, True);
talloc_destroy(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());
-}
-
-
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 (socketpair(AF_UNIX, SOCK_STREAM, 0, fdpair) != 0) {
DEBUG(0, ("Could not open child pipe: %s\n",
ZERO_STRUCT(state);
state.pid = sys_getpid();
- /* Stop zombies */
- CatchChild();
+ /* Ensure we don't process messages whilst we're
+ changing the disposition for the child. */
+ message_block();
child->pid = sys_fork();
if (child->pid == -1) {
DEBUG(0, ("Could not fork: %s\n", strerror(errno)));
+ message_unblock();
return False;
}
child->event.flags = 0;
child->requests = NULL;
add_fd_event(&child->event);
+ /* We're ok with online/offline messages now. */
+ message_unblock();
return True;
}
/* Child */
+ /* Stop zombies in children */
+ CatchChild();
+
state.sock = fdpair[0];
close(fdpair[1]);
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);
+ message_deregister(MSG_SMB_CONF_UPDATED);
+ message_deregister(MSG_SHUTDOWN);
+ message_deregister(MSG_WINBIND_OFFLINE);
+ message_deregister(MSG_WINBIND_ONLINE);
+ message_deregister(MSG_WINBIND_ONLINESTATUS);
+
+ /* The child is ok with online/offline messages now. */
+ message_unblock();
/* 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);
+ message_register(MSG_WINBIND_OFFLINE, child_msg_offline, NULL);
+ message_register(MSG_WINBIND_ONLINE, child_msg_online, NULL);
+ message_register(MSG_WINBIND_ONLINESTATUS, child_msg_onlinestatus,
+ NULL);
if ( child->domain ) {
child->domain->startup = True;
}
/* Ensure we have no pending check_online events other
- than one for this domain. */
+ than one for this domain or the primary domain. */
for (domain = domain_list(); domain; domain = domain->next) {
- if (domain != child->domain) {
+ if (domain->primary) {
+ primary_domain = domain;
+ }
+ if ((domain != child->domain) && !domain->primary) {
TALLOC_FREE(domain->check_online_event);
}
}
set_domain_online_request(child->domain);
+ if (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 :
+ * winbindd_dual_pam_auth_samlogon()
+ * especially the calling of
+ * contact_domain = find_our_domain()
+ * in the non-DC case 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",
lp_TALLOC_FREE();
main_loop_TALLOC_FREE();
+ /* check for signals */
+ winbind_check_sigterm(false);
+ winbind_check_sighup(override_logfile ? NULL :
+ child->logfilename);
+
run_events(winbind_event_context(), 0, NULL, NULL);
GetTimeOfDay(&now);
/* Handle messages */
- message_dispatch(winbind_messaging_context());
+ message_dispatch();
FD_ZERO(&read_fds);
FD_SET(state.sock, &read_fds);