summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/ntpd/control.c4
-rw-r--r--usr.sbin/ntpd/ntp.c38
-rw-r--r--usr.sbin/ntpd/ntp_dns.c23
-rw-r--r--usr.sbin/ntpd/ntpd.c40
-rw-r--r--usr.sbin/ntpd/ntpd.h13
-rw-r--r--usr.sbin/ntpd/util.c81
6 files changed, 142 insertions, 57 deletions
diff --git a/usr.sbin/ntpd/control.c b/usr.sbin/ntpd/control.c
index 1fc7375c246..a9a3941a7ca 100644
--- a/usr.sbin/ntpd/control.c
+++ b/usr.sbin/ntpd/control.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: control.c,v 1.10 2016/03/27 11:16:12 krw Exp $ */
+/* $OpenBSD: control.c,v 1.11 2016/09/14 13:20:16 rzalamena Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -43,7 +43,7 @@ control_init(char *path)
int fd;
mode_t old_umask;
- if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
+ if ((fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0)) == -1) {
log_warn("control_init: socket");
return (-1);
}
diff --git a/usr.sbin/ntpd/ntp.c b/usr.sbin/ntpd/ntp.c
index 76b04f25efe..9c03747e33f 100644
--- a/usr.sbin/ntpd/ntp.c
+++ b/usr.sbin/ntpd/ntp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ntp.c,v 1.142 2016/09/03 11:52:06 reyk Exp $ */
+/* $OpenBSD: ntp.c,v 1.143 2016/09/14 13:20:16 rzalamena Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -66,17 +66,16 @@ ntp_sighdlr(int sig)
}
}
-pid_t
-ntp_main(int pipe_prnt[2], int fd_ctl, struct ntpd_conf *nconf,
- struct passwd *pw)
+void
+ntp_main(struct ntpd_conf *nconf, struct passwd *pw, int argc, char **argv)
{
int a, b, nfds, i, j, idx_peers, timeout;
int nullfd, pipe_dns[2], idx_clients;
int ctls;
+ int fd_ctl;
u_int pfd_elms = 0, idx2peer_elms = 0;
u_int listener_cnt, new_cnt, sent_cnt, trial_cnt;
u_int ctl_cnt;
- pid_t pid;
struct pollfd *pfd = NULL;
struct servent *se;
struct listen_addr *la;
@@ -90,15 +89,11 @@ ntp_main(int pipe_prnt[2], int fd_ctl, struct ntpd_conf *nconf,
time_t nextaction, last_sensor_scan = 0, now;
void *newp;
- switch (pid = fork()) {
- case -1:
- fatal("cannot fork");
- break;
- case 0:
- break;
- default:
- return (pid);
- }
+ if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, PF_UNSPEC,
+ pipe_dns) == -1)
+ fatal("socketpair");
+
+ start_child(NTPDNS_PROC_NAME, pipe_dns[1], argc, argv);
/* in this case the parent didn't init logging and didn't daemonize */
if (nconf->settime && !nconf->debug) {
@@ -111,15 +106,14 @@ ntp_main(int pipe_prnt[2], int fd_ctl, struct ntpd_conf *nconf,
if ((se = getservbyname("ntp", "udp")) == NULL)
fatal("getservbyname");
+ /* Start control socket. */
+ if ((fd_ctl = control_init(CTLSOCKET)) == -1)
+ fatalx("control socket init failed");
+ if (control_listen(fd_ctl) == -1)
+ fatalx("control socket listen failed");
if ((nullfd = open("/dev/null", O_RDWR, 0)) == -1)
fatal(NULL);
- close(pipe_prnt[0]);
- if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_dns) == -1)
- fatal("socketpair");
- ntp_dns(pipe_dns, nconf, pw);
- close(pipe_dns[1]);
-
if (stat(pw->pw_dir, &stb) == -1) {
fatal("privsep dir %s could not be opened", pw->pw_dir);
}
@@ -163,7 +157,7 @@ ntp_main(int pipe_prnt[2], int fd_ctl, struct ntpd_conf *nconf,
if ((ibuf_main = malloc(sizeof(struct imsgbuf))) == NULL)
fatal(NULL);
- imsg_init(ibuf_main, pipe_prnt[1]);
+ imsg_init(ibuf_main, PARENT_SOCK_FILENO);
if ((ibuf_dns = malloc(sizeof(struct imsgbuf))) == NULL)
fatal(NULL);
imsg_init(ibuf_dns, pipe_dns[0]);
@@ -422,7 +416,7 @@ ntp_main(int pipe_prnt[2], int fd_ctl, struct ntpd_conf *nconf,
free(ibuf_dns);
log_info("ntp engine exiting");
- _exit(0);
+ exit(0);
}
int
diff --git a/usr.sbin/ntpd/ntp_dns.c b/usr.sbin/ntpd/ntp_dns.c
index 044cb4fe7a4..a8dcf98c60b 100644
--- a/usr.sbin/ntpd/ntp_dns.c
+++ b/usr.sbin/ntpd/ntp_dns.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ntp_dns.c,v 1.17 2016/09/03 11:52:06 reyk Exp $ */
+/* $OpenBSD: ntp_dns.c,v 1.18 2016/09/14 13:20:16 rzalamena Exp $ */
/*
* Copyright (c) 2003-2008 Henning Brauer <henning@openbsd.org>
@@ -49,23 +49,12 @@ sighdlr_dns(int sig)
}
}
-pid_t
-ntp_dns(int pipe_ntp[2], struct ntpd_conf *nconf, struct passwd *pw)
+void
+ntp_dns(struct ntpd_conf *nconf, struct passwd *pw)
{
- pid_t pid;
struct pollfd pfd[1];
int nfds, nullfd;
- switch (pid = fork()) {
- case -1:
- fatal("cannot fork");
- break;
- case 0:
- break;
- default:
- return (pid);
- }
-
if (setpriority(PRIO_PROCESS, 0, 0) == -1)
log_warn("could not set priority");
@@ -89,8 +78,6 @@ ntp_dns(int pipe_ntp[2], struct ntpd_conf *nconf, struct passwd *pw)
setproctitle("dns engine");
- close(pipe_ntp[0]);
-
if (setgroups(1, &pw->pw_gid) ||
setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
@@ -102,7 +89,7 @@ ntp_dns(int pipe_ntp[2], struct ntpd_conf *nconf, struct passwd *pw)
if ((ibuf_dns = malloc(sizeof(struct imsgbuf))) == NULL)
fatal(NULL);
- imsg_init(ibuf_dns, pipe_ntp[1]);
+ imsg_init(ibuf_dns, PARENT_SOCK_FILENO);
if (pledge("stdio dns", NULL) == -1)
err(1, "pledge");
@@ -135,7 +122,7 @@ ntp_dns(int pipe_ntp[2], struct ntpd_conf *nconf, struct passwd *pw)
msgbuf_clear(&ibuf_dns->w);
free(ibuf_dns);
- _exit(0);
+ exit(0);
}
int
diff --git a/usr.sbin/ntpd/ntpd.c b/usr.sbin/ntpd/ntpd.c
index 7e15213271b..2df47e84852 100644
--- a/usr.sbin/ntpd/ntpd.c
+++ b/usr.sbin/ntpd/ntpd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ntpd.c,v 1.108 2016/09/03 11:52:06 reyk Exp $ */
+/* $OpenBSD: ntpd.c,v 1.109 2016/09/14 13:20:16 rzalamena Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -112,7 +112,7 @@ main(int argc, char *argv[])
struct pollfd *pfd = NULL;
pid_t chld_pid = 0, pid;
const char *conffile;
- int fd_ctl, ch, nfds, i, j;
+ int ch, nfds, i, j;
int pipe_chld[2];
extern char *__progname;
u_int pfd_elms = 0, new_cnt;
@@ -122,6 +122,9 @@ main(int argc, char *argv[])
uid_t pw_uid;
gid_t pw_gid;
void *newp;
+ int argc0 = argc;
+ char **argv0 = argv;
+ char *pname = NULL;
if (strcmp(__progname, "ntpctl") == 0) {
ctl_main(argc, argv);
@@ -132,7 +135,7 @@ main(int argc, char *argv[])
memset(&lconf, 0, sizeof(lconf));
- while ((ch = getopt(argc, argv, "df:nsSv")) != -1) {
+ while ((ch = getopt(argc, argv, "df:nP:sSv")) != -1) {
switch (ch) {
case 'd':
lconf.debug = 2;
@@ -144,6 +147,9 @@ main(int argc, char *argv[])
lconf.debug = 2;
lconf.noaction = 1;
break;
+ case 'P':
+ pname = optarg;
+ break;
case 's':
lconf.settime = 1;
break;
@@ -181,6 +187,22 @@ main(int argc, char *argv[])
if ((pw = getpwnam(NTPD_USER)) == NULL)
errx(1, "unknown user %s", NTPD_USER);
+ if (pname != NULL) {
+ /* Remove our proc arguments, so child doesn't need to. */
+ if (sanitize_argv(&argc0, &argv0) == -1)
+ fatalx("sanitize_argv");
+
+ if (strcmp(NTP_PROC_NAME, pname) == 0)
+ ntp_main(&lconf, pw, argc0, argv0);
+ else if (strcmp(NTPDNS_PROC_NAME, pname) == 0)
+ ntp_dns(&lconf, pw);
+ else
+ fatalx("%s: invalid process name '%s'", __func__,
+ pname);
+
+ fatalx("%s: process '%s' failed", __func__, pname);
+ }
+
pw_dir = strdup(pw->pw_dir);
pw_uid = pw->pw_uid;
pw_gid = pw->pw_gid;
@@ -198,17 +220,14 @@ main(int argc, char *argv[])
} else
timeout = SETTIME_TIMEOUT * 1000;
- if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_chld) == -1)
+ if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, PF_UNSPEC,
+ pipe_chld) == -1)
fatal("socketpair");
- if ((fd_ctl = control_init(CTLSOCKET)) == -1)
- fatalx("control socket init failed");
- if (control_listen(fd_ctl) == -1)
- fatalx("control socket listen failed");
-
signal(SIGCHLD, sighdlr);
+
/* fork child process */
- chld_pid = ntp_main(pipe_chld, fd_ctl, &lconf, pw);
+ chld_pid = start_child(NTP_PROC_NAME, pipe_chld[1], argc0, argv0);
log_procinit("[priv]");
readfreq();
@@ -217,7 +236,6 @@ main(int argc, char *argv[])
signal(SIGINT, sighdlr);
signal(SIGHUP, sighdlr);
- close(pipe_chld[1]);
constraint_purge();
if ((ibuf = malloc(sizeof(struct imsgbuf))) == NULL)
diff --git a/usr.sbin/ntpd/ntpd.h b/usr.sbin/ntpd/ntpd.h
index ae774d8bb37..8a67470219b 100644
--- a/usr.sbin/ntpd/ntpd.h
+++ b/usr.sbin/ntpd/ntpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ntpd.h,v 1.131 2016/09/03 11:52:06 reyk Exp $ */
+/* $OpenBSD: ntpd.h,v 1.132 2016/09/14 13:20:16 rzalamena Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -82,6 +82,11 @@
#define CONSTRAINT_PASSFD (STDERR_FILENO + 1)
#define CONSTRAINT_CA "/etc/ssl/cert.pem"
+#define PARENT_SOCK_FILENO 3
+
+#define NTP_PROC_NAME "ntp_main"
+#define NTPDNS_PROC_NAME "ntp_dns"
+
enum client_state {
STATE_NONE,
STATE_DNS_INPROGRESS,
@@ -302,7 +307,7 @@ enum ctl_actions {
/* prototypes */
/* ntp.c */
-pid_t ntp_main(int[2], int, struct ntpd_conf *, struct passwd *);
+void ntp_main(struct ntpd_conf *, struct passwd *, int, char **);
int priv_adjtime(void);
void priv_settime(double);
void priv_dns(int, char *, u_int32_t);
@@ -372,6 +377,8 @@ double sfp_to_d(struct s_fixedpt);
struct s_fixedpt d_to_sfp(double);
char *print_rtable(int);
const char *log_sockaddr(struct sockaddr *);
+pid_t start_child(char *, int, int, char **);
+int sanitize_argv(int *, char ***);
/* sensors.c */
void sensor_init(void);
@@ -379,7 +386,7 @@ int sensor_scan(void);
void sensor_query(struct ntp_sensor *);
/* ntp_dns.c */
-pid_t ntp_dns(int[2], struct ntpd_conf *, struct passwd *);
+void ntp_dns(struct ntpd_conf *, struct passwd *);
/* control.c */
int control_init(char *);
diff --git a/usr.sbin/ntpd/util.c b/usr.sbin/ntpd/util.c
index e15b1f863b4..146834b5eca 100644
--- a/usr.sbin/ntpd/util.c
+++ b/usr.sbin/ntpd/util.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: util.c,v 1.21 2016/09/14 08:24:08 reyk Exp $ */
+/* $OpenBSD: util.c,v 1.22 2016/09/14 13:20:16 rzalamena Exp $ */
/*
* Copyright (c) 2004 Alexander Guy <alexander.guy@andern.org>
@@ -18,7 +18,9 @@
#include <limits.h>
#include <stdio.h>
+#include <stdlib.h>
#include <time.h>
+#include <unistd.h>
#include "ntpd.h"
@@ -151,3 +153,80 @@ log_sockaddr(struct sockaddr *sa)
else
return (buf);
}
+
+pid_t
+start_child(char *pname, int cfd, int argc, char **argv)
+{
+ char **nargv;
+ int nargc, i;
+ pid_t pid;
+
+ /* Prepare the child process new argv. */
+ nargv = calloc(argc + 3, sizeof(char *));
+ if (nargv == NULL)
+ fatal("%s: calloc", __func__);
+
+ /* Copy the program name first. */
+ nargc = 0;
+ nargv[nargc++] = argv[0];
+
+ /* Set the process name and copy the original args. */
+ nargv[nargc++] = "-P";
+ nargv[nargc++] = pname;
+ for (i = 1; i < argc; i++)
+ nargv[nargc++] = argv[i];
+
+ nargv[nargc] = 0;
+
+ switch (pid = fork()) {
+ case -1:
+ fatal("%s: fork", __func__);
+ break;
+ case 0:
+ /* Prepare the parent socket and execute. */
+ dup2(cfd, PARENT_SOCK_FILENO);
+
+ execvp(argv[0], nargv);
+ fatal("%s: execvp", __func__);
+ break;
+
+ default:
+ /* Close child's socket end. */
+ close(cfd);
+ break;
+ }
+
+ free(nargv);
+ return (pid);
+}
+
+int
+sanitize_argv(int *argc, char ***argv)
+{
+ char **nargv;
+ int nargc;
+ int i;
+
+ /*
+ * We need at least three arguments:
+ * Example: '/usr/sbin/ntpd' '-P' 'foobar'.
+ */
+ if (*argc < 3)
+ return (-1);
+
+ *argc -= 2;
+
+ /* Allocate new arguments vector and copy pointers. */
+ nargv = calloc((*argc) + 1, sizeof(char *));
+ if (nargv == NULL)
+ return (-1);
+
+ nargc = 0;
+ nargv[nargc++] = (*argv)[0];
+ for (i = 1; i < *argc; i++)
+ nargv[nargc++] = (*argv)[i + 2];
+
+ nargv[nargc] = NULL;
+ *argv = nargv;
+ return (0);
+}