summaryrefslogtreecommitdiffstats
path: root/usr.sbin/ldapd
diff options
context:
space:
mode:
authorgsoares <gsoares@openbsd.org>2017-02-24 14:28:31 +0000
committergsoares <gsoares@openbsd.org>2017-02-24 14:28:31 +0000
commitd8c958863fe9db01804c0125c4ee21e4157e0d1a (patch)
tree7c8f8edf623b35b14b6eddfeef571514ccbb2d40 /usr.sbin/ldapd
parentIn a scenario where a config reload happens during an IKE_AUTH exchange, (diff)
downloadwireguard-openbsd-d8c958863fe9db01804c0125c4ee21e4157e0d1a.tar.xz
wireguard-openbsd-d8c958863fe9db01804c0125c4ee21e4157e0d1a.zip
Implement fork+exec model
OK jmatthew@
Diffstat (limited to 'usr.sbin/ldapd')
-rw-r--r--usr.sbin/ldapd/ldapd.c81
-rw-r--r--usr.sbin/ldapd/ldapd.h12
-rw-r--r--usr.sbin/ldapd/ldape.c26
3 files changed, 91 insertions, 28 deletions
diff --git a/usr.sbin/ldapd/ldapd.c b/usr.sbin/ldapd/ldapd.c
index b5b819b1b97..4929cf3090b 100644
--- a/usr.sbin/ldapd/ldapd.c
+++ b/usr.sbin/ldapd/ldapd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldapd.c,v 1.21 2017/01/20 11:55:08 benno Exp $ */
+/* $OpenBSD: ldapd.c,v 1.22 2017/02/24 14:28:31 gsoares Exp $ */
/*
* Copyright (c) 2009, 2010 Martin Hedenfalk <martin@bzero.se>
@@ -49,6 +49,8 @@ static void ldapd_auth_request(struct imsgev *iev, struct imsg *imsg);
static void ldapd_open_request(struct imsgev *iev, struct imsg *imsg);
static void ldapd_log_verbose(struct imsg *imsg);
static void ldapd_cleanup(char *);
+static pid_t start_child(enum ldapd_process, char *, int, int, int,
+ char *, char *);
struct ldapd_stats stats;
pid_t ldape_pid;
@@ -108,12 +110,12 @@ int
main(int argc, char *argv[])
{
int c;
- int debug = 0, verbose = 0;
+ int debug = 0, verbose = 0, eflag = 0;
int configtest = 0, skip_chroot = 0;
int pipe_parent2ldap[2];
char *conffile = CONFFILE;
char *csockpath = LDAPD_SOCKET;
- struct passwd *pw = NULL;
+ char *saved_argv0;
struct imsgev *iev_ldape;
struct event ev_sigint;
struct event ev_sigterm;
@@ -123,7 +125,12 @@ main(int argc, char *argv[])
log_init(1); /* log to stderr until daemonized */
- while ((c = getopt(argc, argv, "dhvD:f:nr:s:")) != -1) {
+ saved_argv0 = argv[0];
+ if (saved_argv0 == NULL)
+ saved_argv0 = "ldapd";
+
+ while ((c = getopt(argc, argv, "dhvD:f:nr:s:E")) != -1) {
+
switch (c) {
case 'd':
debug = 1;
@@ -152,6 +159,9 @@ main(int argc, char *argv[])
case 'v':
verbose++;
break;
+ case 'E':
+ eflag = 1;
+ break;
default:
usage();
/* NOTREACHED */
@@ -174,6 +184,9 @@ main(int argc, char *argv[])
exit(0);
}
+ if (eflag)
+ ldape(debug, verbose, csockpath);
+
if (geteuid()) {
if (!debug)
errx(1, "need root privileges");
@@ -185,7 +198,7 @@ main(int argc, char *argv[])
if (!S_ISDIR(sb.st_mode))
errx(1, "%s is not a directory", datadir);
- if (!skip_chroot && (pw = getpwnam(LDAPD_USER)) == NULL)
+ if (!skip_chroot && (getpwnam(LDAPD_USER) == NULL))
err(1, "%s", LDAPD_USER);
if (!debug) {
@@ -196,11 +209,12 @@ main(int argc, char *argv[])
log_init(debug);
log_info("startup");
- if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, PF_UNSPEC,
- pipe_parent2ldap) != 0)
+ if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
+ PF_UNSPEC, pipe_parent2ldap) != 0)
fatal("socketpair");
-
- ldape_pid = ldape(pw, csockpath, pipe_parent2ldap);
+
+ ldape_pid = start_child(PROC_LDAP_SERVER, saved_argv0,
+ pipe_parent2ldap[1], debug, verbose, csockpath, conffile);
setproctitle("auth");
event_init();
@@ -215,8 +229,6 @@ main(int argc, char *argv[])
signal_add(&ev_sighup, NULL);
signal(SIGPIPE, SIG_IGN);
- close(pipe_parent2ldap[1]);
-
if ((iev_ldape = calloc(1, sizeof(struct imsgev))) == NULL)
fatal("calloc");
imsgev_init(iev_ldape, pipe_parent2ldap[0], NULL, ldapd_imsgev,
@@ -397,3 +409,50 @@ ldapd_open_request(struct imsgev *iev, struct imsg *imsg)
sizeof(*oreq));
}
+static pid_t
+start_child(enum ldapd_process p, char *argv0, int fd, int debug,
+ int verbose, char *csockpath, char *conffile)
+{
+ char *argv[9];
+ int argc = 0;
+ pid_t pid;
+
+ switch (pid = fork()) {
+ case -1:
+ fatal("cannot fork");
+ case 0:
+ break;
+ default:
+ close(fd);
+ return (pid);
+ }
+
+ if (dup2(fd, PROC_PARENT_SOCK_FILENO) == -1)
+ fatal("cannot setup imsg fd");
+
+ argv[argc++] = argv0;
+ switch (p) {
+ case PROC_MAIN_AUTH:
+ fatalx("Can not start main process");
+ case PROC_LDAP_SERVER:
+ argv[argc++] = "-E";
+ break;
+ }
+ if (debug)
+ argv[argc++] = "-d";
+ if (verbose)
+ argv[argc++] = "-v";
+ if (csockpath) {
+ argv[argc++] = "-s";
+ argv[argc++] = csockpath;
+ }
+ if (conffile) {
+ argv[argc++] = "-f";
+ argv[argc++] = conffile;
+ }
+
+ argv[argc++] = NULL;
+
+ execvp(argv0, argv);
+ fatal("execvp");
+}
diff --git a/usr.sbin/ldapd/ldapd.h b/usr.sbin/ldapd/ldapd.h
index 590c39c2dc9..92e19188141 100644
--- a/usr.sbin/ldapd/ldapd.h
+++ b/usr.sbin/ldapd/ldapd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldapd.h,v 1.27 2017/01/20 11:55:08 benno Exp $ */
+/* $OpenBSD: ldapd.h,v 1.28 2017/02/24 14:28:31 gsoares Exp $ */
/*
* Copyright (c) 2009, 2010 Martin Hedenfalk <martin@bzero.se>
@@ -327,6 +327,13 @@ struct control_sock {
int cs_restricted;
};
+enum ldapd_process {
+ PROC_MAIN_AUTH,
+ PROC_LDAP_SERVER
+};
+
+#define PROC_PARENT_SOCK_FILENO 3
+
/* ldapd.c */
extern struct ldapd_stats stats;
extern struct ldapd_config *conf;
@@ -351,8 +358,7 @@ void request_dispatch(struct request *req);
void request_free(struct request *req);
/* ldape.c */
-pid_t ldape(struct passwd *pw, char *csockpath,
- int pipe_parent2ldap[2]);
+void ldape(int, int, char *);
int ldap_abandon(struct request *req);
int ldap_unbind(struct request *req);
int ldap_compare(struct request *req);
diff --git a/usr.sbin/ldapd/ldape.c b/usr.sbin/ldapd/ldape.c
index 1d88c38c1af..ecfc24d11b8 100644
--- a/usr.sbin/ldapd/ldape.c
+++ b/usr.sbin/ldapd/ldape.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldape.c,v 1.25 2017/01/20 11:55:08 benno Exp $ */
+/* $OpenBSD: ldape.c,v 1.26 2017/02/24 14:28:31 gsoares Exp $ */
/*
* Copyright (c) 2009, 2010 Martin Hedenfalk <martin@bzero.se>
@@ -330,11 +330,10 @@ done:
return 0;
}
-pid_t
-ldape(struct passwd *pw, char *csockpath, int pipe_parent2ldap[2])
+void
+ldape(int debug, int verbose, char *csockpath)
{
int on = 1;
- pid_t pid;
struct namespace *ns;
struct listener *l;
struct sockaddr_un *sun = NULL;
@@ -343,17 +342,15 @@ ldape(struct passwd *pw, char *csockpath, int pipe_parent2ldap[2])
struct event ev_sigchld;
struct event ev_sighup;
struct ssl key;
+ struct passwd *pw;
char host[128];
mode_t old_umask = 0;
+
+ log_init(debug);
+ log_verbose(verbose);
TAILQ_INIT(&conn_list);
- pid = fork();
- if (pid < 0)
- fatal("ldape: fork");
- if (pid > 0)
- return pid;
-
setproctitle("ldap server");
event_init();
@@ -367,12 +364,10 @@ ldape(struct passwd *pw, char *csockpath, int pipe_parent2ldap[2])
signal_add(&ev_sighup, NULL);
signal(SIGPIPE, SIG_IGN);
- close(pipe_parent2ldap[0]);
-
/* Initialize parent imsg events. */
if ((iev_ldapd = calloc(1, sizeof(struct imsgev))) == NULL)
fatal("calloc");
- imsgev_init(iev_ldapd, pipe_parent2ldap[1], NULL, ldape_imsgev,
+ imsgev_init(iev_ldapd, PROC_PARENT_SOCK_FILENO, NULL, ldape_imsgev,
ldape_needfd);
/* Initialize control socket. */
@@ -451,6 +446,9 @@ ldape(struct passwd *pw, char *csockpath, int pipe_parent2ldap[2])
fatal(ns->suffix);
}
+ if ((pw = getpwnam(LDAPD_USER)) == NULL)
+ fatal("getpwnam");
+
if (pw != NULL) {
if (chroot(pw->pw_dir) == -1)
fatal("chroot");
@@ -475,7 +473,7 @@ ldape(struct passwd *pw, char *csockpath, int pipe_parent2ldap[2])
control_cleanup(&csock);
log_info("ldape: exiting");
- _exit(0);
+ exit(0);
}
static void