summaryrefslogtreecommitdiff
path: root/source3/winbindd/winbindd_dual.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/winbindd/winbindd_dual.c')
-rw-r--r--source3/winbindd/winbindd_dual.c68
1 files changed, 56 insertions, 12 deletions
diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c
index 0a1534cae1..5bf90b1222 100644
--- a/source3/winbindd/winbindd_dual.c
+++ b/source3/winbindd/winbindd_dual.c
@@ -35,7 +35,7 @@
#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
@@ -127,7 +127,7 @@ struct tevent_req *wb_child_request_send(TALLOC_CTX *mem_ctx,
if (!tevent_queue_add(child->queue, ev, req,
wb_child_request_trigger, NULL)) {
- tevent_req_nomem(NULL, req);
+ tevent_req_oom(req);
return tevent_req_post(req, ev);
}
return req;
@@ -510,6 +510,11 @@ void winbind_child_died(pid_t pid)
DLIST_REMOVE(winbindd_children, child);
child->pid = 0;
+
+ if (child->sock != -1) {
+ close(child->sock);
+ child->sock = -1;
+ }
}
/* Ensure any negative cache entries with the netbios or realm names are removed. */
@@ -741,7 +746,7 @@ void winbind_msg_onlinestatus(struct messaging_context *msg_ctx,
}
messaging_send_buf(msg_ctx, *sender, MSG_WINBIND_ONLINESTATUS,
- (uint8 *)message, strlen(message) + 1);
+ (const uint8 *)message, strlen(message) + 1);
talloc_destroy(mem_ctx);
}
@@ -818,7 +823,7 @@ void winbind_msg_dump_domain_list(struct messaging_context *msg_ctx,
messaging_send_buf(msg_ctx, *sender,
MSG_WINBIND_DUMP_DOMAIN_LIST,
- (uint8_t *)message, strlen(message) + 1);
+ (const uint8_t *)message, strlen(message) + 1);
talloc_destroy(mem_ctx);
@@ -1166,7 +1171,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)
+NTSTATUS winbindd_reinit_after_fork(const struct winbindd_child *myself,
+ const char *logfilename)
{
struct winbindd_domain *domain;
struct winbindd_child *cl;
@@ -1179,7 +1185,7 @@ bool winbindd_reinit_after_fork(const char *logfilename)
true);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("reinit_after_fork() failed\n"));
- return false;
+ return status;
}
close_conns_after_fork();
@@ -1190,10 +1196,10 @@ bool winbindd_reinit_after_fork(const char *logfilename)
}
if (!winbindd_setup_sig_term_handler(false))
- return false;
+ return NT_STATUS_NO_MEMORY;
if (!winbindd_setup_sig_hup_handler(override_logfile ? NULL :
logfilename))
- return false;
+ return NT_STATUS_NO_MEMORY;
/* Stop zombies in children */
CatchChild();
@@ -1241,6 +1247,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
@@ -1261,7 +1275,7 @@ bool winbindd_reinit_after_fork(const char *logfilename)
cl = idmap_child();
cl->pid = (pid_t)0;
- return true;
+ return NT_STATUS_OK;
}
/*
@@ -1281,6 +1295,8 @@ static bool fork_domain_child(struct winbindd_child *child)
struct winbindd_request request;
struct winbindd_response response;
struct winbindd_domain *primary_domain = NULL;
+ NTSTATUS status;
+ ssize_t nwritten;
if (child->domain) {
DEBUG(10, ("fork_domain_child called for domain '%s'\n",
@@ -1309,7 +1325,25 @@ static bool fork_domain_child(struct winbindd_child *child)
if (child->pid != 0) {
/* Parent */
+ ssize_t nread;
+
close(fdpair[0]);
+
+ nread = read(fdpair[1], &status, sizeof(status));
+ if (nread != sizeof(status)) {
+ DEBUG(1, ("fork_domain_child: Could not read child status: "
+ "nread=%d, error=%s\n", (int)nread,
+ strerror(errno)));
+ close(fdpair[1]);
+ return false;
+ }
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1, ("fork_domain_child: Child status is %s\n",
+ nt_errstr(status)));
+ close(fdpair[1]);
+ return false;
+ }
+
child->next = child->prev = NULL;
DLIST_ADD(winbindd_children, child);
child->sock = fdpair[1];
@@ -1324,7 +1358,18 @@ static bool fork_domain_child(struct winbindd_child *child)
state.sock = fdpair[0];
close(fdpair[1]);
- if (!winbindd_reinit_after_fork(child->logfilename)) {
+ status = winbindd_reinit_after_fork(child, child->logfilename);
+
+ nwritten = write(state.sock, &status, sizeof(status));
+ if (nwritten != sizeof(status)) {
+ DEBUG(1, ("fork_domain_child: Could not write status: "
+ "nwritten=%d, error=%s\n", (int)nwritten,
+ strerror(errno)));
+ _exit(0);
+ }
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1, ("winbindd_reinit_after_fork failed: %s\n",
+ nt_errstr(status)));
_exit(0);
}
@@ -1424,7 +1469,6 @@ static bool fork_domain_child(struct winbindd_child *child)
TALLOC_CTX *frame = talloc_stackframe();
struct iovec iov[2];
int iov_count;
- NTSTATUS status;
if (run_events_poll(winbind_event_context(), 0, NULL, 0)) {
TALLOC_FREE(frame);
@@ -1439,7 +1483,7 @@ static bool fork_domain_child(struct winbindd_child *child)
child->domain->startup = False;
}
- pfds = TALLOC_ZERO_P(talloc_tos(), struct pollfd);
+ pfds = talloc_zero(talloc_tos(), struct pollfd);
if (pfds == NULL) {
DEBUG(1, ("talloc failed\n"));
_exit(1);