diff options
author | Gleydson Soares <gsoares@cvs.openbsd.org> | 2017-02-24 14:28:32 +0000 |
---|---|---|
committer | Gleydson Soares <gsoares@cvs.openbsd.org> | 2017-02-24 14:28:32 +0000 |
commit | 4da33b673a58e4aca5fe4e519e8c32ce3a5c43ba (patch) | |
tree | 219828761bf43676c4437fef414a1c8da3aa31f8 /usr.sbin/ldapd | |
parent | 44c1e0f03070f9de85d5267fd4bce4cfafd65da2 (diff) |
Implement fork+exec model
OK jmatthew@
Diffstat (limited to 'usr.sbin/ldapd')
-rw-r--r-- | usr.sbin/ldapd/ldapd.c | 81 | ||||
-rw-r--r-- | usr.sbin/ldapd/ldapd.h | 12 | ||||
-rw-r--r-- | usr.sbin/ldapd/ldape.c | 26 |
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 |