xref: /openbsd-src/usr.sbin/ntpd/config.c (revision 911793fe94d3a68c0d102b6f8a6306f5ca7514b7)
1*911793feSotto /*	$OpenBSD: config.c,v 1.33 2020/04/12 14:20:56 otto Exp $ */
2f64d3c3cShenning 
3f64d3c3cShenning /*
4f64d3c3cShenning  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
5f64d3c3cShenning  *
6f64d3c3cShenning  * Permission to use, copy, modify, and distribute this software for any
7f64d3c3cShenning  * purpose with or without fee is hereby granted, provided that the above
8f64d3c3cShenning  * copyright notice and this permission notice appear in all copies.
9f64d3c3cShenning  *
10f64d3c3cShenning  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11f64d3c3cShenning  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12f64d3c3cShenning  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13f64d3c3cShenning  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14f64d3c3cShenning  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15f64d3c3cShenning  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16f64d3c3cShenning  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17f64d3c3cShenning  */
18f64d3c3cShenning 
19f64d3c3cShenning #include <sys/types.h>
20f64d3c3cShenning #include <sys/socket.h>
21f64d3c3cShenning #include <sys/stat.h>
22f64d3c3cShenning 
2397c9f460Shenning #include <netinet/in.h>
2497c9f460Shenning 
25f64d3c3cShenning #include <errno.h>
26f64d3c3cShenning #include <stdlib.h>
27f64d3c3cShenning #include <string.h>
28b98b0a5cSotto #include <resolv.h>
29f64d3c3cShenning #include <unistd.h>
30f64d3c3cShenning 
31f64d3c3cShenning #include "ntpd.h"
32f64d3c3cShenning 
33f8e1109cSkn struct ntp_addr	*host_ip(const char *);
34b98b0a5cSotto int		 host_dns1(const char *, struct ntp_addr **, int);
35f64d3c3cShenning 
3697c9f460Shenning static u_int32_t		 maxid = 0;
37bc58a738Sreyk static u_int32_t		 constraint_maxid = 0;
38*911793feSotto int				 non_numeric;
3997c9f460Shenning 
402388a8b4Stedu void
host(const char * s,struct ntp_addr ** hn)41547afbf8Shenning host(const char *s, struct ntp_addr **hn)
42f64d3c3cShenning {
43f8e1109cSkn 	struct ntp_addr		*h;
44f64d3c3cShenning 
45f8e1109cSkn 	if (!strcmp(s, "*")) {
46f8e1109cSkn 		if ((h = calloc(1, sizeof(*h))) == NULL)
47005baf58Shenning 			fatal(NULL);
48f8e1109cSkn 	} else {
49*911793feSotto 		if ((h = host_ip(s)) == NULL) {
50*911793feSotto 			non_numeric = 1;
512388a8b4Stedu 			return;
52f8e1109cSkn 		}
53*911793feSotto 	}
546aaaa6e3Shenning 
556aaaa6e3Shenning 	*hn = h;
56f64d3c3cShenning }
57f64d3c3cShenning 
58204af22aShenning struct ntp_addr	*
host_ip(const char * s)59f8e1109cSkn host_ip(const char *s)
60f64d3c3cShenning {
61f64d3c3cShenning 	struct addrinfo		 hints, *res;
62204af22aShenning 	struct ntp_addr		*h = NULL;
63f64d3c3cShenning 
64842d7e97Sbcook 	memset(&hints, 0, sizeof(hints));
65f8e1109cSkn 	hints.ai_family = AF_UNSPEC;
66f64d3c3cShenning 	hints.ai_socktype = SOCK_DGRAM; /*dummy*/
67f64d3c3cShenning 	hints.ai_flags = AI_NUMERICHOST;
68f64d3c3cShenning 	if (getaddrinfo(s, "0", &hints, &res) == 0) {
69f8e1109cSkn 		if (res->ai_family == AF_INET ||
70f8e1109cSkn 		    res->ai_family == AF_INET6) {
71f8e1109cSkn 			if ((h = calloc(1, sizeof(*h))) == NULL)
72204af22aShenning 				fatal(NULL);
73f8e1109cSkn 			memcpy(&h->ss, res->ai_addr, res->ai_addrlen);
74f8e1109cSkn 		}
75f64d3c3cShenning 		freeaddrinfo(res);
76f64d3c3cShenning 	}
77f64d3c3cShenning 
78204af22aShenning 	return (h);
79f64d3c3cShenning }
807667fb33Shenning 
81c0cb3bf1Sbcook void
host_dns_free(struct ntp_addr * hn)82c0cb3bf1Sbcook host_dns_free(struct ntp_addr *hn)
83c0cb3bf1Sbcook {
84c0cb3bf1Sbcook 	struct ntp_addr	*h = hn, *tmp;
85c0cb3bf1Sbcook 	while (h) {
86c0cb3bf1Sbcook 		tmp = h;
87c0cb3bf1Sbcook 		h = h->next;
88c0cb3bf1Sbcook 		free(tmp);
89c0cb3bf1Sbcook 	}
90c0cb3bf1Sbcook }
91c0cb3bf1Sbcook 
92547afbf8Shenning int
host_dns1(const char * s,struct ntp_addr ** hn,int notauth)93b98b0a5cSotto host_dns1(const char *s, struct ntp_addr **hn, int notauth)
947667fb33Shenning {
957667fb33Shenning 	struct addrinfo		 hints, *res0, *res;
96547afbf8Shenning 	int			 error, cnt = 0;
97204af22aShenning 	struct ntp_addr		*h, *hh = NULL;
987667fb33Shenning 
99842d7e97Sbcook 	memset(&hints, 0, sizeof(hints));
100f8e1109cSkn 	hints.ai_family = AF_UNSPEC;
10197c9f460Shenning 	hints.ai_socktype = SOCK_DGRAM; /* DUMMY */
1026a6b450eSotto 	hints.ai_flags = AI_ADDRCONFIG;
1037667fb33Shenning 	error = getaddrinfo(s, NULL, &hints, &res0);
10496959c71Shenning 	if (error == EAI_AGAIN || error == EAI_NODATA || error == EAI_NONAME)
10596959c71Shenning 			return (0);
106547afbf8Shenning 	if (error) {
107547afbf8Shenning 		log_warnx("could not parse \"%s\": %s", s,
108547afbf8Shenning 		    gai_strerror(error));
109547afbf8Shenning 		return (-1);
110547afbf8Shenning 	}
1117667fb33Shenning 
112b683bdcaSdtucker 	for (res = res0; res && cnt < MAX_SERVERS_DNS; res = res->ai_next) {
1137667fb33Shenning 		if (res->ai_family != AF_INET &&
1147667fb33Shenning 		    res->ai_family != AF_INET6)
1157667fb33Shenning 			continue;
116f8e1109cSkn 		if ((h = calloc(1, sizeof(*h))) == NULL)
117204af22aShenning 			fatal(NULL);
118f8e1109cSkn 		memcpy(&h->ss, res->ai_addr, res->ai_addrlen);
119b98b0a5cSotto 		h->notauth = notauth;
1207667fb33Shenning 
121204af22aShenning 		h->next = hh;
122204af22aShenning 		hh = h;
123547afbf8Shenning 		cnt++;
1247667fb33Shenning 	}
1257667fb33Shenning 	freeaddrinfo(res0);
1267667fb33Shenning 
127547afbf8Shenning 	*hn = hh;
128547afbf8Shenning 	return (cnt);
1297667fb33Shenning }
13097c9f460Shenning 
131b98b0a5cSotto int
host_dns(const char * s,int synced,struct ntp_addr ** hn)132c9addb91Sotto host_dns(const char *s, int synced, struct ntp_addr **hn)
133b98b0a5cSotto {
134b98b0a5cSotto 	int error, save_opts;
135b98b0a5cSotto 
136b98b0a5cSotto 	log_debug("trying to resolve %s", s);
137b98b0a5cSotto 	error = host_dns1(s, hn, 0);
138c9addb91Sotto 	if (!synced && error <= 0) {
139b98b0a5cSotto 		log_debug("no luck, trying to resolve %s without checking", s);
140b98b0a5cSotto 		save_opts = _res.options;
141b98b0a5cSotto 		_res.options |= RES_USE_CD;
142b98b0a5cSotto 		error = host_dns1(s, hn, 1);
143b98b0a5cSotto 		_res.options = save_opts;
144b98b0a5cSotto 	}
145b98b0a5cSotto 	log_debug("resolve %s done: %d", s, error);
146b98b0a5cSotto 	return error;
147b98b0a5cSotto }
148b98b0a5cSotto 
14997c9f460Shenning struct ntp_peer *
new_peer(void)15097c9f460Shenning new_peer(void)
15197c9f460Shenning {
15297c9f460Shenning 	struct ntp_peer	*p;
15397c9f460Shenning 
15497c9f460Shenning 	if ((p = calloc(1, sizeof(struct ntp_peer))) == NULL)
155009f3548Shenning 		fatal("new_peer calloc");
15697c9f460Shenning 	p->id = ++maxid;
15797c9f460Shenning 
15897c9f460Shenning 	return (p);
15997c9f460Shenning }
160009f3548Shenning 
161009f3548Shenning struct ntp_conf_sensor *
new_sensor(char * device)162009f3548Shenning new_sensor(char *device)
163009f3548Shenning {
164009f3548Shenning 	struct ntp_conf_sensor	*s;
165009f3548Shenning 
166009f3548Shenning 	if ((s = calloc(1, sizeof(struct ntp_conf_sensor))) == NULL)
167009f3548Shenning 		fatal("new_sensor calloc");
168009f3548Shenning 	if ((s->device = strdup(device)) == NULL)
169009f3548Shenning 		fatal("new_sensor strdup");
170009f3548Shenning 
171009f3548Shenning 	return (s);
172009f3548Shenning }
173bc58a738Sreyk 
174bc58a738Sreyk struct constraint *
new_constraint(void)175bc58a738Sreyk new_constraint(void)
176bc58a738Sreyk {
177bc58a738Sreyk 	struct constraint	*p;
178bc58a738Sreyk 
179bc58a738Sreyk 	if ((p = calloc(1, sizeof(struct constraint))) == NULL)
180bc58a738Sreyk 		fatal("new_constraint calloc");
181bc58a738Sreyk 	p->id = ++constraint_maxid;
182a257dd04Sreyk 	p->fd = -1;
183bc58a738Sreyk 
184bc58a738Sreyk 	return (p);
185bc58a738Sreyk }
186bc58a738Sreyk 
187