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