1 /* $OpenBSD: config.c,v 1.32 2019/07/07 07:14:57 otto Exp $ */ 2 3 /* 4 * Copyright (c) 2003, 2004 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/socket.h> 21 #include <sys/stat.h> 22 23 #include <netinet/in.h> 24 25 #include <errno.h> 26 #include <stdlib.h> 27 #include <string.h> 28 #include <resolv.h> 29 #include <unistd.h> 30 31 #include "ntpd.h" 32 33 struct ntp_addr *host_ip(const char *); 34 int host_dns1(const char *, struct ntp_addr **, int); 35 36 static u_int32_t maxid = 0; 37 static u_int32_t constraint_maxid = 0; 38 39 void 40 host(const char *s, struct ntp_addr **hn) 41 { 42 struct ntp_addr *h; 43 44 if (!strcmp(s, "*")) { 45 if ((h = calloc(1, sizeof(*h))) == NULL) 46 fatal(NULL); 47 } else { 48 if ((h = host_ip(s)) == NULL) 49 return; 50 } 51 52 *hn = h; 53 } 54 55 struct ntp_addr * 56 host_ip(const char *s) 57 { 58 struct addrinfo hints, *res; 59 struct ntp_addr *h = NULL; 60 61 memset(&hints, 0, sizeof(hints)); 62 hints.ai_family = AF_UNSPEC; 63 hints.ai_socktype = SOCK_DGRAM; /*dummy*/ 64 hints.ai_flags = AI_NUMERICHOST; 65 if (getaddrinfo(s, "0", &hints, &res) == 0) { 66 if (res->ai_family == AF_INET || 67 res->ai_family == AF_INET6) { 68 if ((h = calloc(1, sizeof(*h))) == NULL) 69 fatal(NULL); 70 memcpy(&h->ss, res->ai_addr, res->ai_addrlen); 71 } 72 freeaddrinfo(res); 73 } 74 75 return (h); 76 } 77 78 void 79 host_dns_free(struct ntp_addr *hn) 80 { 81 struct ntp_addr *h = hn, *tmp; 82 while (h) { 83 tmp = h; 84 h = h->next; 85 free(tmp); 86 } 87 } 88 89 int 90 host_dns1(const char *s, struct ntp_addr **hn, int notauth) 91 { 92 struct addrinfo hints, *res0, *res; 93 int error, cnt = 0; 94 struct ntp_addr *h, *hh = NULL; 95 96 memset(&hints, 0, sizeof(hints)); 97 hints.ai_family = AF_UNSPEC; 98 hints.ai_socktype = SOCK_DGRAM; /* DUMMY */ 99 hints.ai_flags = AI_ADDRCONFIG; 100 error = getaddrinfo(s, NULL, &hints, &res0); 101 if (error == EAI_AGAIN || error == EAI_NODATA || error == EAI_NONAME) 102 return (0); 103 if (error) { 104 log_warnx("could not parse \"%s\": %s", s, 105 gai_strerror(error)); 106 return (-1); 107 } 108 109 for (res = res0; res && cnt < MAX_SERVERS_DNS; res = res->ai_next) { 110 if (res->ai_family != AF_INET && 111 res->ai_family != AF_INET6) 112 continue; 113 if ((h = calloc(1, sizeof(*h))) == NULL) 114 fatal(NULL); 115 memcpy(&h->ss, res->ai_addr, res->ai_addrlen); 116 h->notauth = notauth; 117 118 h->next = hh; 119 hh = h; 120 cnt++; 121 } 122 freeaddrinfo(res0); 123 124 *hn = hh; 125 return (cnt); 126 } 127 128 int 129 host_dns(const char *s, int synced, struct ntp_addr **hn) 130 { 131 int error, save_opts; 132 133 log_debug("trying to resolve %s", s); 134 error = host_dns1(s, hn, 0); 135 if (!synced && error <= 0) { 136 log_debug("no luck, trying to resolve %s without checking", s); 137 save_opts = _res.options; 138 _res.options |= RES_USE_CD; 139 error = host_dns1(s, hn, 1); 140 _res.options = save_opts; 141 } 142 log_debug("resolve %s done: %d", s, error); 143 return error; 144 } 145 146 struct ntp_peer * 147 new_peer(void) 148 { 149 struct ntp_peer *p; 150 151 if ((p = calloc(1, sizeof(struct ntp_peer))) == NULL) 152 fatal("new_peer calloc"); 153 p->id = ++maxid; 154 155 return (p); 156 } 157 158 struct ntp_conf_sensor * 159 new_sensor(char *device) 160 { 161 struct ntp_conf_sensor *s; 162 163 if ((s = calloc(1, sizeof(struct ntp_conf_sensor))) == NULL) 164 fatal("new_sensor calloc"); 165 if ((s->device = strdup(device)) == NULL) 166 fatal("new_sensor strdup"); 167 168 return (s); 169 } 170 171 struct constraint * 172 new_constraint(void) 173 { 174 struct constraint *p; 175 176 if ((p = calloc(1, sizeof(struct constraint))) == NULL) 177 fatal("new_constraint calloc"); 178 p->id = ++constraint_maxid; 179 p->fd = -1; 180 181 return (p); 182 } 183 184