1 |
|
|
/* $OpenBSD: ntp_dns.c,v 1.20 2017/04/17 16:03:15 otto Exp $ */ |
2 |
|
|
|
3 |
|
|
/* |
4 |
|
|
* Copyright (c) 2003-2008 Henning Brauer <henning@openbsd.org> |
5 |
|
|
* |
6 |
|
|
* Permission to use, copy, modify, and distribute this software for any |
7 |
|
|
* purpose with or without fee is hereby granted, provided that the above |
8 |
|
|
* copyright notice and this permission notice appear in all copies. |
9 |
|
|
* |
10 |
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
11 |
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
12 |
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
13 |
|
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
14 |
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
15 |
|
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
16 |
|
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
17 |
|
|
*/ |
18 |
|
|
|
19 |
|
|
#include <sys/types.h> |
20 |
|
|
#include <sys/resource.h> |
21 |
|
|
#include <sys/time.h> |
22 |
|
|
|
23 |
|
|
#include <err.h> |
24 |
|
|
#include <errno.h> |
25 |
|
|
#include <poll.h> |
26 |
|
|
#include <fcntl.h> |
27 |
|
|
#include <signal.h> |
28 |
|
|
#include <stdlib.h> |
29 |
|
|
#include <string.h> |
30 |
|
|
#include <syslog.h> |
31 |
|
|
#include <unistd.h> |
32 |
|
|
|
33 |
|
|
#include "ntpd.h" |
34 |
|
|
|
35 |
|
|
volatile sig_atomic_t quit_dns = 0; |
36 |
|
|
struct imsgbuf *ibuf_dns; |
37 |
|
|
|
38 |
|
|
void sighdlr_dns(int); |
39 |
|
|
int dns_dispatch_imsg(void); |
40 |
|
|
|
41 |
|
|
void |
42 |
|
|
sighdlr_dns(int sig) |
43 |
|
|
{ |
44 |
|
|
switch (sig) { |
45 |
|
|
case SIGTERM: |
46 |
|
|
case SIGINT: |
47 |
|
|
quit_dns = 1; |
48 |
|
|
break; |
49 |
|
|
} |
50 |
|
|
} |
51 |
|
|
|
52 |
|
|
void |
53 |
|
|
ntp_dns(struct ntpd_conf *nconf, struct passwd *pw) |
54 |
|
|
{ |
55 |
|
|
struct pollfd pfd[1]; |
56 |
|
|
int nfds, nullfd; |
57 |
|
|
|
58 |
|
|
if (setpriority(PRIO_PROCESS, 0, 0) == -1) |
59 |
|
|
log_warn("could not set priority"); |
60 |
|
|
|
61 |
|
|
/* in this case the parent didn't init logging and didn't daemonize */ |
62 |
|
|
if (nconf->settime && !nconf->debug) { |
63 |
|
|
log_init(nconf->debug, LOG_DAEMON); |
64 |
|
|
if (setsid() == -1) |
65 |
|
|
fatal("setsid"); |
66 |
|
|
} |
67 |
|
|
log_procinit("dns"); |
68 |
|
|
|
69 |
|
|
if ((nullfd = open("/dev/null", O_RDWR, 0)) == -1) |
70 |
|
|
fatal(NULL); |
71 |
|
|
|
72 |
|
|
if (!nconf->debug) { |
73 |
|
|
dup2(nullfd, STDIN_FILENO); |
74 |
|
|
dup2(nullfd, STDOUT_FILENO); |
75 |
|
|
dup2(nullfd, STDERR_FILENO); |
76 |
|
|
} |
77 |
|
|
close(nullfd); |
78 |
|
|
|
79 |
|
|
setproctitle("dns engine"); |
80 |
|
|
|
81 |
|
|
if (setgroups(1, &pw->pw_gid) || |
82 |
|
|
setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || |
83 |
|
|
setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) |
84 |
|
|
fatal("can't drop privileges"); |
85 |
|
|
|
86 |
|
|
signal(SIGTERM, sighdlr_dns); |
87 |
|
|
signal(SIGINT, sighdlr_dns); |
88 |
|
|
signal(SIGHUP, SIG_IGN); |
89 |
|
|
|
90 |
|
|
if ((ibuf_dns = malloc(sizeof(struct imsgbuf))) == NULL) |
91 |
|
|
fatal(NULL); |
92 |
|
|
imsg_init(ibuf_dns, PARENT_SOCK_FILENO); |
93 |
|
|
|
94 |
|
|
if (pledge("stdio dns flock rpath cpath wpath", NULL) == -1) |
95 |
|
|
err(1, "pledge"); |
96 |
|
|
|
97 |
|
|
while (quit_dns == 0) { |
98 |
|
|
pfd[0].fd = ibuf_dns->fd; |
99 |
|
|
pfd[0].events = POLLIN; |
100 |
|
|
if (ibuf_dns->w.queued) |
101 |
|
|
pfd[0].events |= POLLOUT; |
102 |
|
|
|
103 |
|
|
if ((nfds = poll(pfd, 1, INFTIM)) == -1) |
104 |
|
|
if (errno != EINTR) { |
105 |
|
|
log_warn("poll error"); |
106 |
|
|
quit_dns = 1; |
107 |
|
|
} |
108 |
|
|
|
109 |
|
|
if (nfds > 0 && (pfd[0].revents & POLLOUT)) |
110 |
|
|
if (msgbuf_write(&ibuf_dns->w) <= 0 && |
111 |
|
|
errno != EAGAIN) { |
112 |
|
|
log_warn("pipe write error (to ntp engine)"); |
113 |
|
|
quit_dns = 1; |
114 |
|
|
} |
115 |
|
|
|
116 |
|
|
if (nfds > 0 && pfd[0].revents & POLLIN) { |
117 |
|
|
nfds--; |
118 |
|
|
if (dns_dispatch_imsg() == -1) |
119 |
|
|
quit_dns = 1; |
120 |
|
|
} |
121 |
|
|
} |
122 |
|
|
|
123 |
|
|
msgbuf_clear(&ibuf_dns->w); |
124 |
|
|
free(ibuf_dns); |
125 |
|
|
exit(0); |
126 |
|
|
} |
127 |
|
|
|
128 |
|
|
int |
129 |
|
|
dns_dispatch_imsg(void) |
130 |
|
|
{ |
131 |
|
|
struct imsg imsg; |
132 |
|
|
int n, cnt; |
133 |
|
|
char *name; |
134 |
|
|
struct ntp_addr *h, *hn; |
135 |
|
|
struct ibuf *buf; |
136 |
|
|
const char *str; |
137 |
|
|
size_t len; |
138 |
|
|
|
139 |
|
|
if (((n = imsg_read(ibuf_dns)) == -1 && errno != EAGAIN) || n == 0) |
140 |
|
|
return (-1); |
141 |
|
|
|
142 |
|
|
for (;;) { |
143 |
|
|
if ((n = imsg_get(ibuf_dns, &imsg)) == -1) |
144 |
|
|
return (-1); |
145 |
|
|
|
146 |
|
|
if (n == 0) |
147 |
|
|
break; |
148 |
|
|
|
149 |
|
|
switch (imsg.hdr.type) { |
150 |
|
|
case IMSG_HOST_DNS: |
151 |
|
|
case IMSG_CONSTRAINT_DNS: |
152 |
|
|
if (imsg.hdr.type == IMSG_HOST_DNS) |
153 |
|
|
str = "IMSG_HOST_DNS"; |
154 |
|
|
else |
155 |
|
|
str = "IMSG_CONSTRAINT_DNS"; |
156 |
|
|
name = imsg.data; |
157 |
|
|
if (imsg.hdr.len < 1 + IMSG_HEADER_SIZE) |
158 |
|
|
fatalx("invalid %s received", str); |
159 |
|
|
len = imsg.hdr.len - 1 - IMSG_HEADER_SIZE; |
160 |
|
|
if (name[len] != '\0' || |
161 |
|
|
strlen(name) != len) |
162 |
|
|
fatalx("invalid %s received", str); |
163 |
|
|
if ((cnt = host_dns(name, &hn)) == -1) |
164 |
|
|
break; |
165 |
|
|
buf = imsg_create(ibuf_dns, imsg.hdr.type, |
166 |
|
|
imsg.hdr.peerid, 0, |
167 |
|
|
cnt * sizeof(struct sockaddr_storage)); |
168 |
|
|
if (cnt > 0) { |
169 |
|
|
if (buf) { |
170 |
|
|
for (h = hn; h != NULL; h = h->next) |
171 |
|
|
if (imsg_add(buf, &h->ss, |
172 |
|
|
sizeof(h->ss)) == -1) { |
173 |
|
|
buf = NULL; |
174 |
|
|
break; |
175 |
|
|
} |
176 |
|
|
} |
177 |
|
|
host_dns_free(hn); |
178 |
|
|
hn = NULL; |
179 |
|
|
} |
180 |
|
|
if (buf) |
181 |
|
|
imsg_close(ibuf_dns, buf); |
182 |
|
|
break; |
183 |
|
|
default: |
184 |
|
|
break; |
185 |
|
|
} |
186 |
|
|
imsg_free(&imsg); |
187 |
|
|
} |
188 |
|
|
return (0); |
189 |
|
|
} |