Commit Diff
Diff:
2f2e49453a66a9e2b587a9ea12ccac76e3e54a30
e40ccd69c1346a82b9f55bb2ffaa827082511dbc
Commit:
e40ccd69c1346a82b9f55bb2ffaa827082511dbc
Tree:
f84dd567c5a2569933c41ab3633bfe577743b4a8
Author:
pjp <pjp@delphinusdns.org>
Committer:
pjp <pjp@delphinusdns.org>
Date:
Tue Jan 29 16:32:54 2019 UTC
Message:
introduce UNIX sockets for delphinusdnsd, pidfiles are gone. dddctl gets its restart, stop and start updated to specify -s path for the socket. The delphinusdnsd will still react on signals as before. tested on OpenBSD
blob - 987dc8c6b0c83dc611fe4f1ce8a946f8457bbe68
blob + 76e007a56b3bf2017090433f4723275d78721b0c
--- ddd-db.h
+++ ddd-db.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005-2015 Peter J. Philipp
+ * Copyright (c) 2005-2019 Peter J. Philipp
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -27,7 +27,7 @@
*/
/*
- * $Id: ddd-db.h,v 1.9 2018/03/03 10:41:02 pjp Exp $
+ * $Id: ddd-db.h,v 1.10 2019/01/29 16:32:54 pjp Exp $
*/
#ifndef _DB_H
@@ -45,6 +45,8 @@
#define IMSG_XFRFD_MESSAGE 3 /* forward message fd to axfr proc */
#define IMSG_PARSE_MESSAGE 4 /* pass message to pledge parser */
#define IMSG_PARSEREPLY_MESSAGE 5 /* return message from pledge parser */
+#define IMSG_SHUTDOWN_MESSAGE 6 /* shut the server down */
+#define IMSG_RELOAD_MESSAGE 7 /* reload/restart the server */
#define ERR_DROP 0x1
#define ERR_NXDOMAIN 0x2
@@ -443,6 +445,17 @@ struct logging {
char *logport;
u_int16_t logport2;
char *logpasswd;
+};
+
+
+/* ddd command socket */
+
+#define SOCKPATH "/var/run/delphinusdnsd.sock"
+struct dddcomm {
+ int command;
+ union {
+ pid_t rpid;
+ } ret;
};
blob - 71cb27a75bc8e5af0c76cc891b59b30624cdfd52
blob + 9ef35a25830e73835417a36436c7591fcb3224c6
--- ddd-include.h
+++ ddd-include.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005-2015 Peter J. Philipp
+ * Copyright (c) 2005-2019 Peter J. Philipp
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -27,7 +27,7 @@
*/
/*
- * $Id: ddd-include.h,v 1.8 2017/10/26 15:49:29 pjp Exp $
+ * $Id: ddd-include.h,v 1.9 2019/01/29 16:32:54 pjp Exp $
*/
#ifndef _INCLUDES_H
@@ -42,6 +42,7 @@
#include <sys/queue.h>
#include <sys/mman.h>
#include <sys/wait.h>
+#include <sys/un.h>
#include <net/if.h>
@@ -93,16 +94,6 @@
#ifndef NTOHS
#include "endian.h"
-#endif
-
-#if !defined __OpenBSD__ && !defined __NetBSD__
-struct ip6_hdr_pseudo {
- struct in6_addr ip6ph_src;
- struct in6_addr ip6ph_dst;
- u_int32_t ip6ph_len;
- u_int8_t ip6ph_zero[3];
- u_int8_t ip6ph_nxt;
-} __packed;
#endif
#endif
blob - a6ddaae9e004843fad08bcfb198ac316aaa8087e
blob + dcc8bf938d80c16f3595500e5b3fa52b6ca9b2a2
--- dddctl.c
+++ dddctl.c
@@ -27,7 +27,7 @@
*/
/*
- * $Id: dddctl.c,v 1.29 2019/01/10 13:43:56 pjp Exp $
+ * $Id: dddctl.c,v 1.30 2019/01/29 16:32:54 pjp Exp $
*/
#include "ddd-include.h"
@@ -132,6 +132,7 @@ void init_keys(void);
uint32_t getkeypid(char *);
pid_t getdaemonpid(void);
void debug_bindump(const char *, int);
+int command_socket(char *);
#if OPENSSL_VERSION_NUMBER < 0x10100000L
@@ -6787,9 +6788,9 @@ usage(int argc, char *argv[])
fprintf(stderr, "\thelp [command]\n");
fprintf(stderr, "\tsign [-KZ] [-a algorithm] [-B bits] [-e seconds]\n\t\t[-I iterations] [-i inputfile] [-k KSK] [-m mask] [-n zonename]\n\t\t[-o output] [-S pid] [-s salt] [-t ttl] [-z ZSK]\n");
fprintf(stderr, "\tsshfp hostname [-k keyfile] [-t ttl]\n");
- fprintf(stderr, "\tstart [configfile]\n");
- fprintf(stderr, "\tstop\n");
- fprintf(stderr, "\trestart\n");
+ fprintf(stderr, "\tstart [-f configfile] [-s socket]\n");
+ fprintf(stderr, "\tstop [-s socket]\n");
+ fprintf(stderr, "\trestart [-s socket]\n");
retval = 0;
}
@@ -6799,9 +6800,33 @@ usage(int argc, char *argv[])
int
start(int argc, char *argv[])
{
+ struct stat sb;
char buf[MAXPATHLEN];
char *path = NULL;
+ char *socketpath = SOCKPATH;
+ char *configfile = CONFFILE;
+ int ch;
+ while ((ch = getopt(argc, argv, "f:s:")) != -1) {
+ switch (ch) {
+ case 'f':
+ configfile = optarg;
+ break;
+ case 's':
+ socketpath = optarg;
+ break;
+ default:
+ usage(argc, argv);
+ exit(1);
+ }
+ }
+
+ if (lstat(socketpath, &sb) != -1) {
+ fprintf(stderr, "%s exists, not clobbering\n", socketpath);
+ exit(1);
+ }
+
+
if (geteuid() != 0) {
fprintf(stderr, "must be root\n");
exit(1);
@@ -6826,66 +6851,146 @@ start(int argc, char *argv[])
fprintf(stderr, "starting delphinusdnsd\n");
- if (argc == 2) {
- path = realpath(argv[1], buf);
- if (path == NULL) {
- perror("realpath");
- exit(1);
- }
+ path = realpath(configfile, buf);
+ if (path == NULL) {
+ perror("realpath");
+ exit(1);
+ }
- if (execl("/usr/local/sbin/delphinusdnsd", "delphinusdnsd", "-f", path, NULL) < 0) {
- perror("execl");
- exit(1);
- }
- } else {
- if (execl("/usr/local/sbin/delphinusdnsd", "delphinusdnsd", NULL) < 0) {
- perror("execl");
- exit(1);
- }
+ if (execl("/usr/local/sbin/delphinusdnsd", "delphinusdnsd", "-f", path,
+ "-s", socketpath, NULL) < 0) {
+ perror("execl");
+ exit(1);
}
return 1;
}
+int
+command_socket(char *sockpath)
+{
+ int so;
+ struct sockaddr_un sun;
+
+ so = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (so < 0) {
+ return -1;
+ }
+
+ memset(&sun, 0, sizeof(sun));
+ sun.sun_family = AF_UNIX;
+ if (strlcpy(sun.sun_path, sockpath, sizeof(sun.sun_path)) >= sizeof(sun.sun_path)) {
+ close(so);
+ return -1;
+ }
+ sun.sun_len = SUN_LEN(&sun);
+
+ if (connect(so, (struct sockaddr *)&sun, sizeof(sun)) < 0) {
+ close(so);
+ return -1;
+ }
+
+ return (so);
+}
+
int
restart(int argc, char *argv[])
{
- pid_t pid;
+ char buf[512];
+ char *socketpath = SOCKPATH;
+ struct dddcomm *dc;
+ int so;
+ int ch, len;
+ while ((ch = getopt(argc, argv, "s:")) != -1) {
+ switch (ch) {
+ case 's':
+ socketpath = optarg;
+ break;
+ default:
+ usage(argc, argv);
+ exit(1);
+ }
+ }
+
if (geteuid() != 0) {
fprintf(stderr, "must be root\n");
exit(1);
}
+
fprintf(stderr, "restarting delphinusdnsd\n");
- /* read the pid file */
- pid = getdaemonpid();
-
- if (kill(pid, SIGHUP) < 0) {
- fprintf(stderr, "unable to kill -HUP the master process\n");
+ if ((so = command_socket(socketpath)) < 0) {
+ perror(socketpath);
exit(1);
+ }
+
+ memset(&buf, 0, sizeof(buf));
+ dc = (struct dddcomm *)&buf[0];
+ dc->command = IMSG_RELOAD_MESSAGE;
+ if (send(so, buf, sizeof(struct dddcomm), 0) < 0) {
+ perror("send");
+ close(so);
+ exit(1);
}
-
- return 0;
+ if ((len = recv(so, buf, sizeof(struct dddcomm), 0)) < 0) {
+ perror("recv");
+ close(so);
+ exit(1);
+ }
+ close(so);
+
+ return (0);
}
int
stop(int argc, char *argv[])
{
- pid_t pid;
+ char buf[512];
+ char *socketpath = SOCKPATH;
+ struct dddcomm *dc;
+ int so;
+ int ch, len;
+ while ((ch = getopt(argc, argv, "s:")) != -1) {
+ switch (ch) {
+ case 's':
+ socketpath = optarg;
+ break;
+ default:
+ usage(argc, argv);
+ exit(1);
+ }
+ }
+
if (geteuid() != 0) {
fprintf(stderr, "must be root\n");
exit(1);
}
+
fprintf(stderr, "stopping delphinusdnsd\n");
- pid = getdaemonpid();
-
- if (kill(pid, SIGTERM) < 0) {
- fprintf(stderr, "unable to kill -TERM the master process\n");
+
+ if ((so = command_socket(socketpath)) < 0) {
+ perror(socketpath);
exit(1);
+ }
+
+ memset(&buf, 0, sizeof(buf));
+ dc = (struct dddcomm *)&buf[0];
+ dc->command = IMSG_SHUTDOWN_MESSAGE;
+ if (send(so, buf, sizeof(struct dddcomm), 0) < 0) {
+ perror("send");
+ close(so);
+ exit(1);
}
- return 0;
+ if ((len = recv(so, buf, sizeof(struct dddcomm), 0)) < 0) {
+ perror("recv");
+ close(so);
+ exit(1);
+ }
+ close(so);
+
+ return (0);
}
int
blob - bd3651bbb147417a3f4703908257dd0c4d9ee0a0
blob + 13068a5473ba970860de2f4fa5e0a657f30d2071
--- delphinusdnsd.c
+++ delphinusdnsd.c
@@ -27,7 +27,7 @@
*/
/*
- * $Id: delphinusdnsd.c,v 1.46 2019/01/25 21:04:18 pjp Exp $
+ * $Id: delphinusdnsd.c,v 1.47 2019/01/29 16:32:54 pjp Exp $
*/
#include "ddd-include.h"
@@ -107,7 +107,8 @@ void mainloop(struct cfg *, struct imsgbuf **);
void master_reload(int);
void master_shutdown(int);
void recurseheader(struct srecurseheader *, int, struct sockaddr_storage *, struct sockaddr_storage *, int);
-void setup_master(ddDB *, char **, struct imsgbuf *ibuf);
+void setup_master(ddDB *, char **, char *, struct imsgbuf *ibuf);
+void setup_unixsocket(char *, struct imsgbuf *);
void slave_signal(int);
void tcploop(struct cfg *, struct imsgbuf **);
void parseloop(struct cfg *, struct imsgbuf **);
@@ -118,7 +119,6 @@ void parseloop(struct cfg *, struct imsgbuf **);
#define DEFAULT_PRIVILEGE "_ddd"
#endif
-#define PIDFILE "/var/run/delphinusdnsd.pid"
#define MYDB_PATH "/var/db/delphinusdns"
/* structs */
@@ -228,6 +228,7 @@ main(int argc, char *argv[], char *environ[])
char *conffile = CONFFILE;
char buf[512];
char **av = NULL;
+ char *socketpath = SOCKPATH;
struct passwd *pw;
struct addrinfo hints, *res0, *res;
@@ -251,7 +252,7 @@ main(int argc, char *argv[], char *environ[])
#endif
- while ((ch = getopt(argc, argv, "b:df:i:ln:p:v")) != -1) {
+ while ((ch = getopt(argc, argv, "b:df:i:ln:p:s:v")) != -1) {
switch (ch) {
case 'b':
bflag = 1;
@@ -284,6 +285,9 @@ main(int argc, char *argv[], char *environ[])
case 'p':
port = atoi(optarg) & 0xffff;
break;
+ case 's':
+ socketpath = optarg;
+ break;
case 'v':
verbose++;
break;
@@ -385,8 +389,6 @@ main(int argc, char *argv[], char *environ[])
exit(1);
}
- /* make a master program that holds the pidfile, boss of ... eek */
-
if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, PF_UNSPEC, &cfg->my_imsg[MY_IMSG_MASTER].imsg_fds[0]) < 0) {
dolog(LOG_INFO, "socketpair() failed\n");
slave_shutdown();
@@ -405,11 +407,25 @@ main(int argc, char *argv[], char *environ[])
default:
close(cfg->my_imsg[MY_IMSG_MASTER].imsg_fds[1]);
imsg_init(parent_ibuf[MY_IMSG_MASTER], cfg->my_imsg[MY_IMSG_MASTER].imsg_fds[0]);
- setup_master(db, av, parent_ibuf[MY_IMSG_MASTER]);
+
+ setup_master(db, av, socketpath, parent_ibuf[MY_IMSG_MASTER]);
/* NOTREACHED */
exit(1);
}
+ switch (pid = fork()) {
+ case -1:
+ dolog(LOG_ERR, "fork(): %s\n", strerror(errno));
+ exit(1);
+ case 0:
+ setup_unixsocket(socketpath, child_ibuf[MY_IMSG_MASTER]);
+ slave_shutdown();
+ exit(1);
+ default:
+ break;
+ }
+
+
/* end of setup_master code */
init_region();
@@ -2343,11 +2359,9 @@ recurseheader(struct srecurseheader *rh, int proto, st
*/
void
-setup_master(ddDB *db, char **av, struct imsgbuf *ibuf)
+setup_master(ddDB *db, char **av, char *socketpath, struct imsgbuf *ibuf)
{
- char buf[512];
pid_t pid;
- int fd;
int sel, max = 0;
ssize_t n;
@@ -2358,7 +2372,7 @@ setup_master(ddDB *db, char **av, struct imsgbuf *ibuf
struct imsg imsg;
#if __OpenBSD__
- if (unveil(PIDFILE, "rwc") < 0) {
+ if (unveil(socketpath, "rwc") < 0) {
perror("unveil");
exit(1);
}
@@ -2382,20 +2396,8 @@ setup_master(ddDB *db, char **av, struct imsgbuf *ibuf
setproctitle("delphinusdnsd master");
- fd = open(PIDFILE, O_WRONLY | O_APPEND | O_CREAT, 0644);
- if (fd < 0) {
- dolog(LOG_ERR, "couldn't install pid file, exiting...\n");
- pid = getpgrp();
- killpg(pid, SIGTERM);
- exit(1);
- }
-
pid = getpid();
- snprintf(buf, sizeof(buf), "%u\n", pid);
- write(fd, buf, strlen(buf));
- close(fd);
-
signal(SIGTERM, master_shutdown);
signal(SIGINT, master_shutdown);
signal(SIGQUIT, master_shutdown);
@@ -2403,7 +2405,7 @@ setup_master(ddDB *db, char **av, struct imsgbuf *ibuf
FD_ZERO(&rset);
for (;;) {
- tv.tv_sec = 10;
+ tv.tv_sec = 1;
tv.tv_usec = 0;
FD_SET(ibuf->fd, &rset);
@@ -2420,7 +2422,7 @@ setup_master(ddDB *db, char **av, struct imsgbuf *ibuf
if (mshutdown) {
dolog(LOG_INFO, "shutting down on signal %d\n", msig);
- unlink(PIDFILE);
+ unlink(socketpath);
pid = getpgrp();
killpg(pid, msig);
@@ -2437,9 +2439,9 @@ setup_master(ddDB *db, char **av, struct imsgbuf *ibuf
dolog(LOG_ERR, "munmap: %s\n", strerror(errno));
}
- unlink(PIDFILE);
+ unlink(socketpath);
- dolog(LOG_INFO, "restarting on SIGHUP\n");
+ dolog(LOG_INFO, "restarting on SIGHUP or command\n");
closelog();
if (execvp("/usr/local/sbin/delphinusdnsd", av) < 0) {
@@ -2475,6 +2477,13 @@ setup_master(ddDB *db, char **av, struct imsgbuf *ibuf
case IMSG_HELLO_MESSAGE:
/* dolog(LOG_DEBUG, "received hello from child\n"); */
break;
+ case IMSG_RELOAD_MESSAGE:
+ reload = 1;
+ break;
+ case IMSG_SHUTDOWN_MESSAGE:
+ mshutdown = 1;
+ msig = SIGTERM;
+ break;
}
imsg_free(&imsg);
@@ -3370,4 +3379,168 @@ convert_question(struct parsequestion *pq)
q->badvers = pq->badvers;
return (q);
+}
+
+void
+setup_unixsocket(char *socketpath, struct imsgbuf *ibuf)
+{
+ int so, nso;
+ int sel, slen;
+ int len;
+ char buf[512];
+ struct sockaddr_un sun, *psun;
+ struct timeval tv;
+ struct dddcomm *dc;
+ struct passwd *pw;
+ fd_set rset;
+ uid_t uid;
+ gid_t gid;
+
+ setproctitle("delphinusdnsd unix socket");
+
+ memset(&sun, 0, sizeof(sun));
+ sun.sun_family = AF_UNIX;
+ if (strlcpy(sun.sun_path, socketpath, sizeof(sun.sun_path)) >= sizeof(sun.sun_path)) {
+ slave_shutdown();
+ exit(1);
+ }
+ sun.sun_len = SUN_LEN(&sun);
+
+ if (umask(027) < 0) {
+ slave_shutdown();
+ exit(1);
+ }
+
+ so = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (so < 0) {
+ slave_shutdown();
+ exit(1);
+ }
+
+ if (bind(so, (struct sockaddr *)&sun, sizeof(sun)) < 0) {
+ slave_shutdown();
+ exit(1);
+ }
+
+ pw = getpwnam(DEFAULT_PRIVILEGE);
+ if (pw == NULL) {
+ perror("getpwnam");
+ slave_shutdown();
+ exit(1);
+ }
+
+ /* chroot to the drop priv user home directory */
+ if (chroot(pw->pw_dir) < 0) {
+ perror("chroot");
+ slave_shutdown();
+ exit(1);
+ }
+
+ if (chdir("/") < 0) {
+ perror("chdir");
+ slave_shutdown();
+ exit(1);
+ }
+
+ if (setgroups(1, &pw->pw_gid) < 0) {
+ perror("setgroups");
+ slave_shutdown();
+ exit(1);
+ }
+
+#if defined __OpenBSD__ || defined __FreeBSD__
+ if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) < 0) {
+ perror("setresgid");
+ slave_shutdown();
+ exit(1);
+ }
+
+ if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) < 0) {
+ perror("setresuid");
+ slave_shutdown();
+ exit(1);
+ }
+
+#else
+ if (setgid(pw->pw_gid) < 0) {
+ perror("setgid");
+ slave_shutdown();
+ exit(1);
+ }
+ if (setuid(pw->pw_uid) < 0) {
+ perror("setuid");
+ slave_shutdown();
+ exit(1);
+ }
+#endif
+
+ listen(so, 5);
+
+#if __OpenBSD__
+ if (unveil(NULL, NULL) < 0) {
+ perror("unveil");
+ slave_shutdown();
+ exit(1);
+ }
+
+ if (pledge("stdio rpath wpath cpath unix proc", NULL) < 0) {
+ perror("pledge");
+ slave_shutdown();
+ exit(1);
+ }
+#endif
+
+
+ for (;;) {
+ FD_ZERO(&rset);
+ FD_SET(so, &rset);
+
+ sel = select(so + 1, &rset, NULL, NULL, NULL);
+ if (sel < 0) {
+ continue;
+ }
+
+
+ if (FD_ISSET(so, &rset)) {
+ if ((nso = accept(so, (struct sockaddr*)&psun, &slen)) < 0)
+ continue;
+
+#if __OpenBSD__
+ if (getpeereid(nso, &uid, &gid) < 0) {
+ close(nso);
+ continue;
+ }
+#endif
+ tv.tv_sec = 2;
+ tv.tv_usec = 0;
+ if (setsockopt(so, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
+ close(nso);
+ continue;
+ }
+
+ len = recv(nso, buf, sizeof(buf), 0);
+ if (len < 0 || len < sizeof(struct dddcomm)) {
+ close(nso);
+ continue;
+ }
+
+ dc = (struct dddcomm *)&buf[0];
+ if (dc->command == IMSG_RELOAD_MESSAGE ||
+ dc->command == IMSG_SHUTDOWN_MESSAGE) {
+ int idata;
+
+ idata = 1;
+ imsg_compose(ibuf, dc->command,
+ 0, 0, -1, &idata, sizeof(idata));
+ msgbuf_write(&ibuf->w);
+ send(nso, buf, len, 0);
+ close(nso);
+ exit(0);
+ }
+ send(nso, buf, len, 0);
+ close(nso);
+ } /* FD_ISSET */
+ } /* for (;;) */
+
+ /* NOTREACHED */
}
repomaster@centroid.eu