1 /* $OpenBSD: ntp_dns.c,v 1.3 2010/05/26 13:56:08 nicm 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 MIND, USE, DATA OR PROFITS, WHETHER 15 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/param.h> 20 #include <sys/time.h> 21 #include <errno.h> 22 #include <poll.h> 23 #include <signal.h> 24 #include <stdlib.h> 25 #include <string.h> 26 #include <unistd.h> 27 28 #include "ntpd.h" 29 30 volatile sig_atomic_t quit_dns = 0; 31 struct imsgbuf *ibuf_dns; 32 33 void sighdlr_dns(int); 34 int dns_dispatch_imsg(void); 35 36 void 37 sighdlr_dns(int sig) 38 { 39 switch (sig) { 40 case SIGTERM: 41 case SIGINT: 42 quit_dns = 1; 43 break; 44 } 45 } 46 47 pid_t 48 ntp_dns(int pipe_ntp[2], struct ntpd_conf *nconf, struct passwd *pw) 49 { 50 pid_t pid; 51 struct pollfd pfd[1]; 52 int nfds; 53 54 switch (pid = fork()) { 55 case -1: 56 fatal("cannot fork"); 57 break; 58 case 0: 59 break; 60 default: 61 return (pid); 62 } 63 64 /* in this case the parent didn't init logging and didn't daemonize */ 65 if (nconf->settime && !nconf->debug) { 66 log_init(nconf->debug); 67 if (setsid() == -1) 68 fatal("setsid"); 69 } 70 71 setproctitle("dns engine"); 72 close(pipe_ntp[0]); 73 74 if (setgroups(1, &pw->pw_gid) || 75 setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || 76 setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) 77 fatal("can't drop privileges"); 78 79 signal(SIGTERM, sighdlr_dns); 80 signal(SIGINT, sighdlr_dns); 81 signal(SIGHUP, sighdlr_dns); 82 83 if ((ibuf_dns = malloc(sizeof(struct imsgbuf))) == NULL) 84 fatal(NULL); 85 imsg_init(ibuf_dns, pipe_ntp[1]); 86 87 while (quit_dns == 0) { 88 pfd[0].fd = ibuf_dns->fd; 89 pfd[0].events = POLLIN; 90 if (ibuf_dns->w.queued) 91 pfd[0].events |= POLLOUT; 92 93 if ((nfds = poll(pfd, 1, INFTIM)) == -1) 94 if (errno != EINTR) { 95 log_warn("poll error"); 96 quit_dns = 1; 97 } 98 99 if (nfds > 0 && (pfd[0].revents & POLLOUT)) 100 if (msgbuf_write(&ibuf_dns->w) < 0) { 101 log_warn("pipe write error (to ntp engine)"); 102 quit_dns = 1; 103 } 104 105 if (nfds > 0 && pfd[0].revents & POLLIN) { 106 nfds--; 107 if (dns_dispatch_imsg() == -1) 108 quit_dns = 1; 109 } 110 } 111 112 msgbuf_clear(&ibuf_dns->w); 113 free(ibuf_dns); 114 _exit(0); 115 } 116 117 int 118 dns_dispatch_imsg(void) 119 { 120 struct imsg imsg; 121 int n, cnt; 122 char *name; 123 struct ntp_addr *h, *hn; 124 struct ibuf *buf; 125 126 if ((n = imsg_read(ibuf_dns)) == -1) 127 return (-1); 128 129 if (n == 0) { /* connection closed */ 130 log_warnx("dispatch_imsg in main: pipe closed"); 131 return (-1); 132 } 133 134 for (;;) { 135 if ((n = imsg_get(ibuf_dns, &imsg)) == -1) 136 return (-1); 137 138 if (n == 0) 139 break; 140 141 switch (imsg.hdr.type) { 142 case IMSG_HOST_DNS: 143 name = imsg.data; 144 if (imsg.hdr.len < 1 + IMSG_HEADER_SIZE) 145 fatalx("invalid IMSG_HOST_DNS received"); 146 imsg.hdr.len -= 1 + IMSG_HEADER_SIZE; 147 if (name[imsg.hdr.len] != '\0' || 148 strlen(name) != imsg.hdr.len) 149 fatalx("invalid IMSG_HOST_DNS received"); 150 if ((cnt = host_dns(name, &hn)) == -1) 151 break; 152 buf = imsg_create(ibuf_dns, IMSG_HOST_DNS, 153 imsg.hdr.peerid, 0, 154 cnt * sizeof(struct sockaddr_storage)); 155 if (buf == NULL) 156 break; 157 if (cnt > 0) 158 for (h = hn; h != NULL; h = h->next) 159 imsg_add(buf, &h->ss, sizeof(h->ss)); 160 161 imsg_close(ibuf_dns, buf); 162 break; 163 default: 164 break; 165 } 166 imsg_free(&imsg); 167 } 168 return (0); 169 } 170