xref: /freebsd/contrib/openbsm/bin/auditdistd/parse.y (revision aa77200569e397d6ff1fdb4d255d0fa254d0a128)
1*aa772005SRobert Watson %{
2*aa772005SRobert Watson /*-
3*aa772005SRobert Watson  * Copyright (c) 2012 The FreeBSD Foundation
4*aa772005SRobert Watson  * All rights reserved.
5*aa772005SRobert Watson  *
6*aa772005SRobert Watson  * This software was developed by Pawel Jakub Dawidek under sponsorship from
7*aa772005SRobert Watson  * the FreeBSD Foundation.
8*aa772005SRobert Watson  *
9*aa772005SRobert Watson  * Redistribution and use in source and binary forms, with or without
10*aa772005SRobert Watson  * modification, are permitted provided that the following conditions
11*aa772005SRobert Watson  * are met:
12*aa772005SRobert Watson  * 1. Redistributions of source code must retain the above copyright
13*aa772005SRobert Watson  *    notice, this list of conditions and the following disclaimer.
14*aa772005SRobert Watson  * 2. Redistributions in binary form must reproduce the above copyright
15*aa772005SRobert Watson  *    notice, this list of conditions and the following disclaimer in the
16*aa772005SRobert Watson  *    documentation and/or other materials provided with the distribution.
17*aa772005SRobert Watson  *
18*aa772005SRobert Watson  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
19*aa772005SRobert Watson  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20*aa772005SRobert Watson  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21*aa772005SRobert Watson  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
22*aa772005SRobert Watson  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23*aa772005SRobert Watson  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24*aa772005SRobert Watson  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25*aa772005SRobert Watson  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26*aa772005SRobert Watson  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27*aa772005SRobert Watson  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28*aa772005SRobert Watson  * SUCH DAMAGE.
29*aa772005SRobert Watson  *
30*aa772005SRobert Watson  * $P4: //depot/projects/trustedbsd/openbsm/bin/auditdistd/parse.y#5 $
31*aa772005SRobert Watson  */
32*aa772005SRobert Watson 
33*aa772005SRobert Watson #include <config/config.h>
34*aa772005SRobert Watson 
35*aa772005SRobert Watson #include <sys/types.h>
36*aa772005SRobert Watson #include <sys/queue.h>
37*aa772005SRobert Watson #include <sys/sysctl.h>
38*aa772005SRobert Watson 
39*aa772005SRobert Watson #include <arpa/inet.h>
40*aa772005SRobert Watson 
41*aa772005SRobert Watson #include <err.h>
42*aa772005SRobert Watson #include <errno.h>
43*aa772005SRobert Watson #include <stdio.h>
44*aa772005SRobert Watson #include <string.h>
45*aa772005SRobert Watson #include <sysexits.h>
46*aa772005SRobert Watson #include <unistd.h>
47*aa772005SRobert Watson #ifndef HAVE_STRLCPY
48*aa772005SRobert Watson #include <compat/strlcpy.h>
49*aa772005SRobert Watson #endif
50*aa772005SRobert Watson 
51*aa772005SRobert Watson #include "auditdistd.h"
52*aa772005SRobert Watson #include "pjdlog.h"
53*aa772005SRobert Watson 
54*aa772005SRobert Watson extern int depth;
55*aa772005SRobert Watson extern int lineno;
56*aa772005SRobert Watson 
57*aa772005SRobert Watson extern FILE *yyin;
58*aa772005SRobert Watson extern char *yytext;
59*aa772005SRobert Watson 
60*aa772005SRobert Watson static struct adist_config *lconfig;
61*aa772005SRobert Watson static struct adist_host *curhost;
62*aa772005SRobert Watson #define	SECTION_GLOBAL		0
63*aa772005SRobert Watson #define	SECTION_SENDER		1
64*aa772005SRobert Watson #define	SECTION_RECEIVER	2
65*aa772005SRobert Watson static int cursection;
66*aa772005SRobert Watson 
67*aa772005SRobert Watson /* Sender section. */
68*aa772005SRobert Watson static char depth1_source[ADIST_ADDRSIZE];
69*aa772005SRobert Watson static int depth1_checksum;
70*aa772005SRobert Watson static int depth1_compression;
71*aa772005SRobert Watson /* Sender and receiver sections. */
72*aa772005SRobert Watson static char depth1_directory[PATH_MAX];
73*aa772005SRobert Watson 
74*aa772005SRobert Watson static bool adjust_directory(char *path);
75*aa772005SRobert Watson static bool family_supported(int family);
76*aa772005SRobert Watson 
77*aa772005SRobert Watson extern void yyrestart(FILE *);
78*aa772005SRobert Watson %}
79*aa772005SRobert Watson 
80*aa772005SRobert Watson %token CB
81*aa772005SRobert Watson %token CERTFILE
82*aa772005SRobert Watson %token DIRECTORY
83*aa772005SRobert Watson %token FINGERPRINT
84*aa772005SRobert Watson %token HOST
85*aa772005SRobert Watson %token KEYFILE
86*aa772005SRobert Watson %token LISTEN
87*aa772005SRobert Watson %token NAME
88*aa772005SRobert Watson %token OB
89*aa772005SRobert Watson %token PASSWORD
90*aa772005SRobert Watson %token PIDFILE
91*aa772005SRobert Watson %token RECEIVER REMOTE
92*aa772005SRobert Watson %token SENDER SOURCE
93*aa772005SRobert Watson %token TIMEOUT
94*aa772005SRobert Watson 
95*aa772005SRobert Watson /*
96*aa772005SRobert Watson %type <num> checksum_type
97*aa772005SRobert Watson %type <num> compression_type
98*aa772005SRobert Watson */
99*aa772005SRobert Watson 
100*aa772005SRobert Watson %union
101*aa772005SRobert Watson {
102*aa772005SRobert Watson 	int num;
103*aa772005SRobert Watson 	char *str;
104*aa772005SRobert Watson }
105*aa772005SRobert Watson 
106*aa772005SRobert Watson %token <num> NUM
107*aa772005SRobert Watson %token <str> STR
108*aa772005SRobert Watson 
109*aa772005SRobert Watson %%
110*aa772005SRobert Watson 
111*aa772005SRobert Watson statements:
112*aa772005SRobert Watson 	|
113*aa772005SRobert Watson 	statements statement
114*aa772005SRobert Watson 	;
115*aa772005SRobert Watson 
116*aa772005SRobert Watson statement:
117*aa772005SRobert Watson 	name_statement
118*aa772005SRobert Watson 	|
119*aa772005SRobert Watson 	pidfile_statement
120*aa772005SRobert Watson 	|
121*aa772005SRobert Watson 	timeout_statement
122*aa772005SRobert Watson 	|
123*aa772005SRobert Watson 	sender_statement
124*aa772005SRobert Watson 	|
125*aa772005SRobert Watson 	receiver_statement
126*aa772005SRobert Watson 	;
127*aa772005SRobert Watson 
128*aa772005SRobert Watson name_statement:	NAME STR
129*aa772005SRobert Watson 	{
130*aa772005SRobert Watson 		PJDLOG_RASSERT(depth == 0,
131*aa772005SRobert Watson 		    "The name variable can only be specificed in the global section.");
132*aa772005SRobert Watson 
133*aa772005SRobert Watson 		if (lconfig->adc_name[0] != '\0') {
134*aa772005SRobert Watson 			pjdlog_error("The name variable is specified twice.");
135*aa772005SRobert Watson 			free($2);
136*aa772005SRobert Watson 			return (1);
137*aa772005SRobert Watson 		}
138*aa772005SRobert Watson 		if (strlcpy(lconfig->adc_name, $2,
139*aa772005SRobert Watson 		    sizeof(lconfig->adc_name)) >=
140*aa772005SRobert Watson 		    sizeof(lconfig->adc_name)) {
141*aa772005SRobert Watson 			pjdlog_error("The name value is too long.");
142*aa772005SRobert Watson 			free($2);
143*aa772005SRobert Watson 			return (1);
144*aa772005SRobert Watson 		}
145*aa772005SRobert Watson 		free($2);
146*aa772005SRobert Watson 	}
147*aa772005SRobert Watson 	;
148*aa772005SRobert Watson 
149*aa772005SRobert Watson pidfile_statement:	PIDFILE STR
150*aa772005SRobert Watson 	{
151*aa772005SRobert Watson 		PJDLOG_RASSERT(depth == 0,
152*aa772005SRobert Watson 		    "The pidfile variable can only be specificed in the global section.");
153*aa772005SRobert Watson 
154*aa772005SRobert Watson 		if (lconfig->adc_pidfile[0] != '\0') {
155*aa772005SRobert Watson 			pjdlog_error("The pidfile variable is specified twice.");
156*aa772005SRobert Watson 			free($2);
157*aa772005SRobert Watson 			return (1);
158*aa772005SRobert Watson 		}
159*aa772005SRobert Watson 		if (strcmp($2, "none") != 0 && $2[0] != '/') {
160*aa772005SRobert Watson 			pjdlog_error("The pidfile variable must be set to absolute pathname or \"none\".");
161*aa772005SRobert Watson 			free($2);
162*aa772005SRobert Watson 			return (1);
163*aa772005SRobert Watson 		}
164*aa772005SRobert Watson 		if (strlcpy(lconfig->adc_pidfile, $2,
165*aa772005SRobert Watson 		    sizeof(lconfig->adc_pidfile)) >=
166*aa772005SRobert Watson 		    sizeof(lconfig->adc_pidfile)) {
167*aa772005SRobert Watson 			pjdlog_error("The pidfile value is too long.");
168*aa772005SRobert Watson 			free($2);
169*aa772005SRobert Watson 			return (1);
170*aa772005SRobert Watson 		}
171*aa772005SRobert Watson 		free($2);
172*aa772005SRobert Watson 	}
173*aa772005SRobert Watson 	;
174*aa772005SRobert Watson 
175*aa772005SRobert Watson timeout_statement:	TIMEOUT NUM
176*aa772005SRobert Watson 	{
177*aa772005SRobert Watson 		PJDLOG_ASSERT(depth == 0);
178*aa772005SRobert Watson 
179*aa772005SRobert Watson 		lconfig->adc_timeout = $2;
180*aa772005SRobert Watson 	}
181*aa772005SRobert Watson 	;
182*aa772005SRobert Watson 
183*aa772005SRobert Watson sender_statement:	SENDER sender_start sender_entries CB
184*aa772005SRobert Watson 	{
185*aa772005SRobert Watson 		PJDLOG_ASSERT(depth == 0);
186*aa772005SRobert Watson 		PJDLOG_ASSERT(cursection == SECTION_SENDER);
187*aa772005SRobert Watson 
188*aa772005SRobert Watson 		/* Configure defaults. */
189*aa772005SRobert Watson 		if (depth1_checksum == -1)
190*aa772005SRobert Watson 			depth1_checksum = ADIST_CHECKSUM_NONE;
191*aa772005SRobert Watson 		if (depth1_compression == -1)
192*aa772005SRobert Watson 			depth1_compression = ADIST_COMPRESSION_NONE;
193*aa772005SRobert Watson 		if (depth1_directory[0] == '\0') {
194*aa772005SRobert Watson 			(void)strlcpy(depth1_directory, ADIST_DIRECTORY_SENDER,
195*aa772005SRobert Watson 			    sizeof(depth1_directory));
196*aa772005SRobert Watson 		}
197*aa772005SRobert Watson 		/* Empty depth1_source is ok. */
198*aa772005SRobert Watson 		TAILQ_FOREACH(curhost, &lconfig->adc_hosts, adh_next) {
199*aa772005SRobert Watson 			if (curhost->adh_role != ADIST_ROLE_SENDER)
200*aa772005SRobert Watson 				continue;
201*aa772005SRobert Watson 			if (curhost->adh_checksum == -1)
202*aa772005SRobert Watson 				curhost->adh_checksum = depth1_checksum;
203*aa772005SRobert Watson 			if (curhost->adh_compression == -1)
204*aa772005SRobert Watson 				curhost->adh_compression = depth1_compression;
205*aa772005SRobert Watson 			if (curhost->adh_directory[0] == '\0') {
206*aa772005SRobert Watson 				(void)strlcpy(curhost->adh_directory,
207*aa772005SRobert Watson 				    depth1_directory,
208*aa772005SRobert Watson 				    sizeof(curhost->adh_directory));
209*aa772005SRobert Watson 			}
210*aa772005SRobert Watson 			if (curhost->adh_localaddr[0] == '\0') {
211*aa772005SRobert Watson 				(void)strlcpy(curhost->adh_localaddr,
212*aa772005SRobert Watson 				    depth1_source,
213*aa772005SRobert Watson 				    sizeof(curhost->adh_localaddr));
214*aa772005SRobert Watson 			}
215*aa772005SRobert Watson 		}
216*aa772005SRobert Watson 		cursection = SECTION_GLOBAL;
217*aa772005SRobert Watson 	}
218*aa772005SRobert Watson 	;
219*aa772005SRobert Watson 
220*aa772005SRobert Watson sender_start:	OB
221*aa772005SRobert Watson 	{
222*aa772005SRobert Watson 		PJDLOG_ASSERT(depth == 1);
223*aa772005SRobert Watson 		PJDLOG_ASSERT(cursection == SECTION_GLOBAL);
224*aa772005SRobert Watson 
225*aa772005SRobert Watson 		cursection = SECTION_SENDER;
226*aa772005SRobert Watson 		depth1_checksum = -1;
227*aa772005SRobert Watson 		depth1_compression = -1;
228*aa772005SRobert Watson 		depth1_source[0] = '\0';
229*aa772005SRobert Watson 		depth1_directory[0] = '\0';
230*aa772005SRobert Watson 
231*aa772005SRobert Watson #ifndef HAVE_AUDIT_SYSCALLS
232*aa772005SRobert Watson 		pjdlog_error("Sender functionality is not available.");
233*aa772005SRobert Watson 		return (1);
234*aa772005SRobert Watson #endif
235*aa772005SRobert Watson 	}
236*aa772005SRobert Watson 	;
237*aa772005SRobert Watson 
238*aa772005SRobert Watson sender_entries:
239*aa772005SRobert Watson 	|
240*aa772005SRobert Watson 	sender_entries sender_entry
241*aa772005SRobert Watson 	;
242*aa772005SRobert Watson 
243*aa772005SRobert Watson sender_entry:
244*aa772005SRobert Watson 	source_statement
245*aa772005SRobert Watson 	|
246*aa772005SRobert Watson 	directory_statement
247*aa772005SRobert Watson /*
248*aa772005SRobert Watson 	|
249*aa772005SRobert Watson 	checksum_statement
250*aa772005SRobert Watson 	|
251*aa772005SRobert Watson 	compression_statement
252*aa772005SRobert Watson */
253*aa772005SRobert Watson 	|
254*aa772005SRobert Watson 	sender_host_statement
255*aa772005SRobert Watson 	;
256*aa772005SRobert Watson 
257*aa772005SRobert Watson receiver_statement:	RECEIVER receiver_start receiver_entries CB
258*aa772005SRobert Watson 	{
259*aa772005SRobert Watson 		PJDLOG_ASSERT(depth == 0);
260*aa772005SRobert Watson 		PJDLOG_ASSERT(cursection == SECTION_RECEIVER);
261*aa772005SRobert Watson 
262*aa772005SRobert Watson 		/*
263*aa772005SRobert Watson 		 * If not listen addresses were specified,
264*aa772005SRobert Watson 		 * configure default ones.
265*aa772005SRobert Watson 		 */
266*aa772005SRobert Watson 		if (TAILQ_EMPTY(&lconfig->adc_listen)) {
267*aa772005SRobert Watson 			struct adist_listen *lst;
268*aa772005SRobert Watson 
269*aa772005SRobert Watson 			if (family_supported(AF_INET)) {
270*aa772005SRobert Watson 				lst = calloc(1, sizeof(*lst));
271*aa772005SRobert Watson 				if (lst == NULL) {
272*aa772005SRobert Watson 					pjdlog_error("Unable to allocate memory for listen address.");
273*aa772005SRobert Watson 					return (1);
274*aa772005SRobert Watson 				}
275*aa772005SRobert Watson 				(void)strlcpy(lst->adl_addr,
276*aa772005SRobert Watson 				    ADIST_LISTEN_TLS_TCP4,
277*aa772005SRobert Watson 				    sizeof(lst->adl_addr));
278*aa772005SRobert Watson 				TAILQ_INSERT_TAIL(&lconfig->adc_listen, lst, adl_next);
279*aa772005SRobert Watson 			} else {
280*aa772005SRobert Watson 				pjdlog_debug(1,
281*aa772005SRobert Watson 				    "No IPv4 support in the kernel, not listening on IPv4 address.");
282*aa772005SRobert Watson 			}
283*aa772005SRobert Watson 			if (family_supported(AF_INET6)) {
284*aa772005SRobert Watson 				lst = calloc(1, sizeof(*lst));
285*aa772005SRobert Watson 				if (lst == NULL) {
286*aa772005SRobert Watson 					pjdlog_error("Unable to allocate memory for listen address.");
287*aa772005SRobert Watson 					return (1);
288*aa772005SRobert Watson 				}
289*aa772005SRobert Watson 				(void)strlcpy(lst->adl_addr,
290*aa772005SRobert Watson 				    ADIST_LISTEN_TLS_TCP6,
291*aa772005SRobert Watson 				    sizeof(lst->adl_addr));
292*aa772005SRobert Watson 				TAILQ_INSERT_TAIL(&lconfig->adc_listen, lst, adl_next);
293*aa772005SRobert Watson 			} else {
294*aa772005SRobert Watson 				pjdlog_debug(1,
295*aa772005SRobert Watson 				    "No IPv6 support in the kernel, not listening on IPv6 address.");
296*aa772005SRobert Watson 			}
297*aa772005SRobert Watson 			if (TAILQ_EMPTY(&lconfig->adc_listen)) {
298*aa772005SRobert Watson 				pjdlog_error("No address to listen on.");
299*aa772005SRobert Watson 				return (1);
300*aa772005SRobert Watson 			}
301*aa772005SRobert Watson 		}
302*aa772005SRobert Watson 		/* Configure defaults. */
303*aa772005SRobert Watson 		if (depth1_directory[0] == '\0') {
304*aa772005SRobert Watson 			(void)strlcpy(depth1_directory,
305*aa772005SRobert Watson 			    ADIST_DIRECTORY_RECEIVER,
306*aa772005SRobert Watson 			    sizeof(depth1_directory));
307*aa772005SRobert Watson 		}
308*aa772005SRobert Watson 		TAILQ_FOREACH(curhost, &lconfig->adc_hosts, adh_next) {
309*aa772005SRobert Watson 			if (curhost->adh_role != ADIST_ROLE_RECEIVER)
310*aa772005SRobert Watson 				continue;
311*aa772005SRobert Watson 			if (curhost->adh_directory[0] == '\0') {
312*aa772005SRobert Watson 				if (snprintf(curhost->adh_directory,
313*aa772005SRobert Watson 				    sizeof(curhost->adh_directory), "%s/%s",
314*aa772005SRobert Watson 				    depth1_directory, curhost->adh_name) >=
315*aa772005SRobert Watson 				    (ssize_t)sizeof(curhost->adh_directory)) {
316*aa772005SRobert Watson 					pjdlog_error("Directory value is too long.");
317*aa772005SRobert Watson 					return (1);
318*aa772005SRobert Watson 				}
319*aa772005SRobert Watson 			}
320*aa772005SRobert Watson 		}
321*aa772005SRobert Watson 		cursection = SECTION_GLOBAL;
322*aa772005SRobert Watson 	}
323*aa772005SRobert Watson 	;
324*aa772005SRobert Watson 
325*aa772005SRobert Watson receiver_start:	OB
326*aa772005SRobert Watson 	{
327*aa772005SRobert Watson 		PJDLOG_ASSERT(depth == 1);
328*aa772005SRobert Watson 		PJDLOG_ASSERT(cursection == SECTION_GLOBAL);
329*aa772005SRobert Watson 
330*aa772005SRobert Watson 		cursection = SECTION_RECEIVER;
331*aa772005SRobert Watson 		depth1_directory[0] = '\0';
332*aa772005SRobert Watson 	}
333*aa772005SRobert Watson 	;
334*aa772005SRobert Watson 
335*aa772005SRobert Watson receiver_entries:
336*aa772005SRobert Watson 	|
337*aa772005SRobert Watson 	receiver_entries receiver_entry
338*aa772005SRobert Watson 	;
339*aa772005SRobert Watson 
340*aa772005SRobert Watson receiver_entry:
341*aa772005SRobert Watson 	listen_statement
342*aa772005SRobert Watson 	|
343*aa772005SRobert Watson 	directory_statement
344*aa772005SRobert Watson 	|
345*aa772005SRobert Watson 	certfile_statement
346*aa772005SRobert Watson 	|
347*aa772005SRobert Watson 	keyfile_statement
348*aa772005SRobert Watson 	|
349*aa772005SRobert Watson 	receiver_host_statement
350*aa772005SRobert Watson 	;
351*aa772005SRobert Watson 
352*aa772005SRobert Watson /*
353*aa772005SRobert Watson checksum_statement:	CHECKSUM checksum_type
354*aa772005SRobert Watson 	{
355*aa772005SRobert Watson 		PJDLOG_ASSERT(cursection == SECTION_SENDER);
356*aa772005SRobert Watson 
357*aa772005SRobert Watson 		switch (depth) {
358*aa772005SRobert Watson 		case 1:
359*aa772005SRobert Watson 			depth1_checksum = $2;
360*aa772005SRobert Watson 			break;
361*aa772005SRobert Watson 		case 2:
362*aa772005SRobert Watson 			PJDLOG_ASSERT(curhost != NULL);
363*aa772005SRobert Watson 			curhost->adh_checksum = $2;
364*aa772005SRobert Watson 			break;
365*aa772005SRobert Watson 		default:
366*aa772005SRobert Watson 			PJDLOG_ABORT("checksum at wrong depth level");
367*aa772005SRobert Watson 		}
368*aa772005SRobert Watson 	}
369*aa772005SRobert Watson 	;
370*aa772005SRobert Watson 
371*aa772005SRobert Watson checksum_type:
372*aa772005SRobert Watson 	NONE		{ $$ = ADIST_CHECKSUM_NONE; }
373*aa772005SRobert Watson 	|
374*aa772005SRobert Watson 	CRC32		{ $$ = ADIST_CHECKSUM_CRC32; }
375*aa772005SRobert Watson 	|
376*aa772005SRobert Watson 	SHA256		{ $$ = ADIST_CHECKSUM_SHA256; }
377*aa772005SRobert Watson 	;
378*aa772005SRobert Watson 
379*aa772005SRobert Watson compression_statement:	COMPRESSION compression_type
380*aa772005SRobert Watson 	{
381*aa772005SRobert Watson 		PJDLOG_ASSERT(cursection == SECTION_SENDER);
382*aa772005SRobert Watson 
383*aa772005SRobert Watson 		switch (depth) {
384*aa772005SRobert Watson 		case 1:
385*aa772005SRobert Watson 			depth1_compression = $2;
386*aa772005SRobert Watson 			break;
387*aa772005SRobert Watson 		case 2:
388*aa772005SRobert Watson 			PJDLOG_ASSERT(curhost != NULL);
389*aa772005SRobert Watson 			curhost->adh_compression = $2;
390*aa772005SRobert Watson 			break;
391*aa772005SRobert Watson 		default:
392*aa772005SRobert Watson 			PJDLOG_ABORT("compression at wrong depth level");
393*aa772005SRobert Watson 		}
394*aa772005SRobert Watson 	}
395*aa772005SRobert Watson 	;
396*aa772005SRobert Watson 
397*aa772005SRobert Watson compression_type:
398*aa772005SRobert Watson 	NONE		{ $$ = ADIST_COMPRESSION_NONE; }
399*aa772005SRobert Watson 	|
400*aa772005SRobert Watson 	LZF		{ $$ = ADIST_COMPRESSION_LZF; }
401*aa772005SRobert Watson 	;
402*aa772005SRobert Watson */
403*aa772005SRobert Watson 
404*aa772005SRobert Watson directory_statement:	DIRECTORY STR
405*aa772005SRobert Watson 	{
406*aa772005SRobert Watson 		PJDLOG_ASSERT(cursection == SECTION_SENDER ||
407*aa772005SRobert Watson 		    cursection == SECTION_RECEIVER);
408*aa772005SRobert Watson 
409*aa772005SRobert Watson 		switch (depth) {
410*aa772005SRobert Watson 		case 1:
411*aa772005SRobert Watson 			if (strlcpy(depth1_directory, $2,
412*aa772005SRobert Watson 			    sizeof(depth1_directory)) >=
413*aa772005SRobert Watson 			    sizeof(depth1_directory)) {
414*aa772005SRobert Watson 				pjdlog_error("Directory value is too long.");
415*aa772005SRobert Watson 				free($2);
416*aa772005SRobert Watson 				return (1);
417*aa772005SRobert Watson 			}
418*aa772005SRobert Watson 			if (!adjust_directory(depth1_directory))
419*aa772005SRobert Watson 				return (1);
420*aa772005SRobert Watson 			break;
421*aa772005SRobert Watson 		case 2:
422*aa772005SRobert Watson 			if (cursection == SECTION_SENDER || $2[0] == '/') {
423*aa772005SRobert Watson 				if (strlcpy(curhost->adh_directory, $2,
424*aa772005SRobert Watson 				    sizeof(curhost->adh_directory)) >=
425*aa772005SRobert Watson 				    sizeof(curhost->adh_directory)) {
426*aa772005SRobert Watson 					pjdlog_error("Directory value is too long.");
427*aa772005SRobert Watson 					free($2);
428*aa772005SRobert Watson 					return (1);
429*aa772005SRobert Watson 				}
430*aa772005SRobert Watson 			} else /* if (cursection == SECTION_RECEIVER) */ {
431*aa772005SRobert Watson 				if (depth1_directory[0] == '\0') {
432*aa772005SRobert Watson 					pjdlog_error("Directory path must be absolute.");
433*aa772005SRobert Watson 					free($2);
434*aa772005SRobert Watson 					return (1);
435*aa772005SRobert Watson 				}
436*aa772005SRobert Watson 				if (snprintf(curhost->adh_directory,
437*aa772005SRobert Watson 				    sizeof(curhost->adh_directory), "%s/%s",
438*aa772005SRobert Watson 				    depth1_directory, $2) >=
439*aa772005SRobert Watson 				    (ssize_t)sizeof(curhost->adh_directory)) {
440*aa772005SRobert Watson 					pjdlog_error("Directory value is too long.");
441*aa772005SRobert Watson 					free($2);
442*aa772005SRobert Watson 					return (1);
443*aa772005SRobert Watson 				}
444*aa772005SRobert Watson 			}
445*aa772005SRobert Watson 			break;
446*aa772005SRobert Watson 		default:
447*aa772005SRobert Watson 			PJDLOG_ABORT("directory at wrong depth level");
448*aa772005SRobert Watson 		}
449*aa772005SRobert Watson 		free($2);
450*aa772005SRobert Watson 	}
451*aa772005SRobert Watson 	;
452*aa772005SRobert Watson 
453*aa772005SRobert Watson source_statement:	SOURCE STR
454*aa772005SRobert Watson 	{
455*aa772005SRobert Watson 		PJDLOG_RASSERT(cursection == SECTION_SENDER,
456*aa772005SRobert Watson 		    "The source variable must be in sender section.");
457*aa772005SRobert Watson 
458*aa772005SRobert Watson 		switch (depth) {
459*aa772005SRobert Watson 		case 1:
460*aa772005SRobert Watson 			if (strlcpy(depth1_source, $2,
461*aa772005SRobert Watson 			    sizeof(depth1_source)) >=
462*aa772005SRobert Watson 			    sizeof(depth1_source)) {
463*aa772005SRobert Watson 				pjdlog_error("Source value is too long.");
464*aa772005SRobert Watson 				free($2);
465*aa772005SRobert Watson 				return (1);
466*aa772005SRobert Watson 			}
467*aa772005SRobert Watson 			break;
468*aa772005SRobert Watson 		case 2:
469*aa772005SRobert Watson 			if (strlcpy(curhost->adh_localaddr, $2,
470*aa772005SRobert Watson 			    sizeof(curhost->adh_localaddr)) >=
471*aa772005SRobert Watson 			    sizeof(curhost->adh_localaddr)) {
472*aa772005SRobert Watson 				pjdlog_error("Source value is too long.");
473*aa772005SRobert Watson 				free($2);
474*aa772005SRobert Watson 				return (1);
475*aa772005SRobert Watson 			}
476*aa772005SRobert Watson 			break;
477*aa772005SRobert Watson 		}
478*aa772005SRobert Watson 		free($2);
479*aa772005SRobert Watson 	}
480*aa772005SRobert Watson 	;
481*aa772005SRobert Watson 
482*aa772005SRobert Watson fingerprint_statement:	FINGERPRINT STR
483*aa772005SRobert Watson 	{
484*aa772005SRobert Watson 		PJDLOG_ASSERT(cursection == SECTION_SENDER);
485*aa772005SRobert Watson 		PJDLOG_ASSERT(depth == 2);
486*aa772005SRobert Watson 
487*aa772005SRobert Watson 		if (strncasecmp($2, "SHA256=", 7) != 0) {
488*aa772005SRobert Watson 			pjdlog_error("Invalid fingerprint value.");
489*aa772005SRobert Watson 			free($2);
490*aa772005SRobert Watson 			return (1);
491*aa772005SRobert Watson 		}
492*aa772005SRobert Watson 		if (strlcpy(curhost->adh_fingerprint, $2,
493*aa772005SRobert Watson 		    sizeof(curhost->adh_fingerprint)) >=
494*aa772005SRobert Watson 		    sizeof(curhost->adh_fingerprint)) {
495*aa772005SRobert Watson 			pjdlog_error("Fingerprint value is too long.");
496*aa772005SRobert Watson 			free($2);
497*aa772005SRobert Watson 			return (1);
498*aa772005SRobert Watson 		}
499*aa772005SRobert Watson 		free($2);
500*aa772005SRobert Watson 	}
501*aa772005SRobert Watson 	;
502*aa772005SRobert Watson 
503*aa772005SRobert Watson password_statement:	PASSWORD STR
504*aa772005SRobert Watson 	{
505*aa772005SRobert Watson 		PJDLOG_ASSERT(cursection == SECTION_SENDER ||
506*aa772005SRobert Watson 		    cursection == SECTION_RECEIVER);
507*aa772005SRobert Watson 		PJDLOG_ASSERT(depth == 2);
508*aa772005SRobert Watson 
509*aa772005SRobert Watson 		if (strlcpy(curhost->adh_password, $2,
510*aa772005SRobert Watson 		    sizeof(curhost->adh_password)) >=
511*aa772005SRobert Watson 		    sizeof(curhost->adh_password)) {
512*aa772005SRobert Watson 			pjdlog_error("Password value is too long.");
513*aa772005SRobert Watson 			bzero($2, strlen($2));
514*aa772005SRobert Watson 			free($2);
515*aa772005SRobert Watson 			return (1);
516*aa772005SRobert Watson 		}
517*aa772005SRobert Watson 		bzero($2, strlen($2));
518*aa772005SRobert Watson 		free($2);
519*aa772005SRobert Watson 	}
520*aa772005SRobert Watson 	;
521*aa772005SRobert Watson 
522*aa772005SRobert Watson certfile_statement:	CERTFILE STR
523*aa772005SRobert Watson 	{
524*aa772005SRobert Watson 		PJDLOG_ASSERT(cursection == SECTION_RECEIVER);
525*aa772005SRobert Watson 		PJDLOG_ASSERT(depth == 1);
526*aa772005SRobert Watson 
527*aa772005SRobert Watson 		if (strlcpy(lconfig->adc_certfile, $2,
528*aa772005SRobert Watson 		    sizeof(lconfig->adc_certfile)) >=
529*aa772005SRobert Watson 		    sizeof(lconfig->adc_certfile)) {
530*aa772005SRobert Watson 			pjdlog_error("Certfile value is too long.");
531*aa772005SRobert Watson 			free($2);
532*aa772005SRobert Watson 			return (1);
533*aa772005SRobert Watson 		}
534*aa772005SRobert Watson 		free($2);
535*aa772005SRobert Watson 	}
536*aa772005SRobert Watson 	;
537*aa772005SRobert Watson 
538*aa772005SRobert Watson keyfile_statement:	KEYFILE STR
539*aa772005SRobert Watson 	{
540*aa772005SRobert Watson 		PJDLOG_ASSERT(cursection == SECTION_RECEIVER);
541*aa772005SRobert Watson 		PJDLOG_ASSERT(depth == 1);
542*aa772005SRobert Watson 
543*aa772005SRobert Watson 		if (strlcpy(lconfig->adc_keyfile, $2,
544*aa772005SRobert Watson 		    sizeof(lconfig->adc_keyfile)) >=
545*aa772005SRobert Watson 		    sizeof(lconfig->adc_keyfile)) {
546*aa772005SRobert Watson 			pjdlog_error("Keyfile value is too long.");
547*aa772005SRobert Watson 			free($2);
548*aa772005SRobert Watson 			return (1);
549*aa772005SRobert Watson 		}
550*aa772005SRobert Watson 		free($2);
551*aa772005SRobert Watson 	}
552*aa772005SRobert Watson 	;
553*aa772005SRobert Watson 
554*aa772005SRobert Watson listen_statement:	LISTEN STR
555*aa772005SRobert Watson 	{
556*aa772005SRobert Watson 		struct adist_listen *lst;
557*aa772005SRobert Watson 
558*aa772005SRobert Watson 		PJDLOG_ASSERT(depth == 1);
559*aa772005SRobert Watson 		PJDLOG_ASSERT(cursection == SECTION_RECEIVER);
560*aa772005SRobert Watson 
561*aa772005SRobert Watson 		lst = calloc(1, sizeof(*lst));
562*aa772005SRobert Watson 		if (lst == NULL) {
563*aa772005SRobert Watson 			pjdlog_error("Unable to allocate memory for listen address.");
564*aa772005SRobert Watson 			free($2);
565*aa772005SRobert Watson 			return (1);
566*aa772005SRobert Watson 		}
567*aa772005SRobert Watson 		if (strlcpy(lst->adl_addr, $2, sizeof(lst->adl_addr)) >=
568*aa772005SRobert Watson 		    sizeof(lst->adl_addr)) {
569*aa772005SRobert Watson 			pjdlog_error("listen argument is too long.");
570*aa772005SRobert Watson 			free($2);
571*aa772005SRobert Watson 			free(lst);
572*aa772005SRobert Watson 			return (1);
573*aa772005SRobert Watson 		}
574*aa772005SRobert Watson 		TAILQ_INSERT_TAIL(&lconfig->adc_listen, lst, adl_next);
575*aa772005SRobert Watson 		free($2);
576*aa772005SRobert Watson 	}
577*aa772005SRobert Watson 	;
578*aa772005SRobert Watson 
579*aa772005SRobert Watson sender_host_statement:	HOST host_start OB sender_host_entries CB
580*aa772005SRobert Watson 	{
581*aa772005SRobert Watson 		/* Put it onto host list. */
582*aa772005SRobert Watson 		TAILQ_INSERT_TAIL(&lconfig->adc_hosts, curhost, adh_next);
583*aa772005SRobert Watson 		curhost = NULL;
584*aa772005SRobert Watson 	}
585*aa772005SRobert Watson 	;
586*aa772005SRobert Watson 
587*aa772005SRobert Watson receiver_host_statement:	HOST host_start OB receiver_host_entries CB
588*aa772005SRobert Watson 	{
589*aa772005SRobert Watson 		/* Put it onto host list. */
590*aa772005SRobert Watson 		TAILQ_INSERT_TAIL(&lconfig->adc_hosts, curhost, adh_next);
591*aa772005SRobert Watson 		curhost = NULL;
592*aa772005SRobert Watson 	}
593*aa772005SRobert Watson 	;
594*aa772005SRobert Watson 
595*aa772005SRobert Watson host_start:	STR
596*aa772005SRobert Watson 	{
597*aa772005SRobert Watson 		/* Check if there is no duplicate entry. */
598*aa772005SRobert Watson 		TAILQ_FOREACH(curhost, &lconfig->adc_hosts, adh_next) {
599*aa772005SRobert Watson 			if (strcmp(curhost->adh_name, $1) != 0)
600*aa772005SRobert Watson 				continue;
601*aa772005SRobert Watson 			if (curhost->adh_role == ADIST_ROLE_SENDER &&
602*aa772005SRobert Watson 			    cursection == SECTION_RECEIVER) {
603*aa772005SRobert Watson 				continue;
604*aa772005SRobert Watson 			}
605*aa772005SRobert Watson 			if (curhost->adh_role == ADIST_ROLE_RECEIVER &&
606*aa772005SRobert Watson 			    cursection == SECTION_SENDER) {
607*aa772005SRobert Watson 				continue;
608*aa772005SRobert Watson 			}
609*aa772005SRobert Watson 			pjdlog_error("%s host %s is configured more than once.",
610*aa772005SRobert Watson 			    curhost->adh_role == ADIST_ROLE_SENDER ?
611*aa772005SRobert Watson 			    "Sender" : "Receiver", curhost->adh_name);
612*aa772005SRobert Watson 			free($1);
613*aa772005SRobert Watson 			return (1);
614*aa772005SRobert Watson 		}
615*aa772005SRobert Watson 
616*aa772005SRobert Watson 		curhost = calloc(1, sizeof(*curhost));
617*aa772005SRobert Watson 		if (curhost == NULL) {
618*aa772005SRobert Watson 			pjdlog_error("Unable to allocate memory for host configuration.");
619*aa772005SRobert Watson 			free($1);
620*aa772005SRobert Watson 			return (1);
621*aa772005SRobert Watson 		}
622*aa772005SRobert Watson 		if (strlcpy(curhost->adh_name, $1, sizeof(curhost->adh_name)) >=
623*aa772005SRobert Watson 		    sizeof(curhost->adh_name)) {
624*aa772005SRobert Watson 			pjdlog_error("Host name is too long.");
625*aa772005SRobert Watson 			free($1);
626*aa772005SRobert Watson 			return (1);
627*aa772005SRobert Watson 		}
628*aa772005SRobert Watson 		free($1);
629*aa772005SRobert Watson 		curhost->adh_role = cursection == SECTION_SENDER ?
630*aa772005SRobert Watson 		    ADIST_ROLE_SENDER : ADIST_ROLE_RECEIVER;
631*aa772005SRobert Watson 		curhost->adh_version = ADIST_VERSION;
632*aa772005SRobert Watson 		curhost->adh_localaddr[0] = '\0';
633*aa772005SRobert Watson 		curhost->adh_remoteaddr[0] = '\0';
634*aa772005SRobert Watson 		curhost->adh_remote = NULL;
635*aa772005SRobert Watson 		curhost->adh_directory[0] = '\0';
636*aa772005SRobert Watson 		curhost->adh_password[0] = '\0';
637*aa772005SRobert Watson 		curhost->adh_fingerprint[0] = '\0';
638*aa772005SRobert Watson 		curhost->adh_worker_pid = 0;
639*aa772005SRobert Watson 		curhost->adh_conn = NULL;
640*aa772005SRobert Watson 	}
641*aa772005SRobert Watson 	;
642*aa772005SRobert Watson 
643*aa772005SRobert Watson sender_host_entries:
644*aa772005SRobert Watson 	|
645*aa772005SRobert Watson 	sender_host_entries sender_host_entry
646*aa772005SRobert Watson 	;
647*aa772005SRobert Watson 
648*aa772005SRobert Watson sender_host_entry:
649*aa772005SRobert Watson 	source_statement
650*aa772005SRobert Watson 	|
651*aa772005SRobert Watson 	remote_statement
652*aa772005SRobert Watson 	|
653*aa772005SRobert Watson 	directory_statement
654*aa772005SRobert Watson 	|
655*aa772005SRobert Watson 	fingerprint_statement
656*aa772005SRobert Watson 	|
657*aa772005SRobert Watson 	password_statement
658*aa772005SRobert Watson /*
659*aa772005SRobert Watson 	|
660*aa772005SRobert Watson 	checksum_statement
661*aa772005SRobert Watson 	|
662*aa772005SRobert Watson 	compression_statement
663*aa772005SRobert Watson */
664*aa772005SRobert Watson 	;
665*aa772005SRobert Watson 
666*aa772005SRobert Watson receiver_host_entries:
667*aa772005SRobert Watson 	|
668*aa772005SRobert Watson 	receiver_host_entries receiver_host_entry
669*aa772005SRobert Watson 	;
670*aa772005SRobert Watson 
671*aa772005SRobert Watson receiver_host_entry:
672*aa772005SRobert Watson 	remote_statement
673*aa772005SRobert Watson 	|
674*aa772005SRobert Watson 	directory_statement
675*aa772005SRobert Watson 	|
676*aa772005SRobert Watson 	password_statement
677*aa772005SRobert Watson 	;
678*aa772005SRobert Watson 
679*aa772005SRobert Watson remote_statement:	REMOTE STR
680*aa772005SRobert Watson 	{
681*aa772005SRobert Watson 		PJDLOG_ASSERT(depth == 2);
682*aa772005SRobert Watson 		PJDLOG_ASSERT(cursection == SECTION_SENDER ||
683*aa772005SRobert Watson 		    cursection == SECTION_RECEIVER);
684*aa772005SRobert Watson 
685*aa772005SRobert Watson 		if (strlcpy(curhost->adh_remoteaddr, $2,
686*aa772005SRobert Watson 		    sizeof(curhost->adh_remoteaddr)) >=
687*aa772005SRobert Watson 		    sizeof(curhost->adh_remoteaddr)) {
688*aa772005SRobert Watson 			pjdlog_error("Remote value is too long.");
689*aa772005SRobert Watson 			free($2);
690*aa772005SRobert Watson 			return (1);
691*aa772005SRobert Watson 		}
692*aa772005SRobert Watson 		free($2);
693*aa772005SRobert Watson 	}
694*aa772005SRobert Watson 	;
695*aa772005SRobert Watson 
696*aa772005SRobert Watson %%
697*aa772005SRobert Watson 
698*aa772005SRobert Watson static bool
699*aa772005SRobert Watson family_supported(int family)
700*aa772005SRobert Watson {
701*aa772005SRobert Watson 	int sock;
702*aa772005SRobert Watson 
703*aa772005SRobert Watson 	sock = socket(family, SOCK_STREAM, 0);
704*aa772005SRobert Watson 	if (sock == -1 && errno == EPROTONOSUPPORT)
705*aa772005SRobert Watson 		return (false);
706*aa772005SRobert Watson 	if (sock >= 0)
707*aa772005SRobert Watson 		(void)close(sock);
708*aa772005SRobert Watson 	return (true);
709*aa772005SRobert Watson }
710*aa772005SRobert Watson 
711*aa772005SRobert Watson static bool
712*aa772005SRobert Watson adjust_directory(char *path)
713*aa772005SRobert Watson {
714*aa772005SRobert Watson 	size_t len;
715*aa772005SRobert Watson 
716*aa772005SRobert Watson 	len = strlen(path);
717*aa772005SRobert Watson 	for (;;) {
718*aa772005SRobert Watson 		if (len == 0) {
719*aa772005SRobert Watson 			pjdlog_error("Directory path is empty.");
720*aa772005SRobert Watson 			return (false);
721*aa772005SRobert Watson 		}
722*aa772005SRobert Watson 		if (path[len - 1] != '/')
723*aa772005SRobert Watson 			break;
724*aa772005SRobert Watson 		len--;
725*aa772005SRobert Watson 		path[len] = '\0';
726*aa772005SRobert Watson 	}
727*aa772005SRobert Watson 	if (path[0] != '/') {
728*aa772005SRobert Watson 		pjdlog_error("Directory path must be absolute.");
729*aa772005SRobert Watson 		return (false);
730*aa772005SRobert Watson 	}
731*aa772005SRobert Watson 	return (true);
732*aa772005SRobert Watson }
733*aa772005SRobert Watson 
734*aa772005SRobert Watson static int
735*aa772005SRobert Watson my_name(char *name, size_t size)
736*aa772005SRobert Watson {
737*aa772005SRobert Watson 	char buf[MAXHOSTNAMELEN];
738*aa772005SRobert Watson 	char *pos;
739*aa772005SRobert Watson 
740*aa772005SRobert Watson 	if (gethostname(buf, sizeof(buf)) < 0) {
741*aa772005SRobert Watson 		pjdlog_errno(LOG_ERR, "gethostname() failed");
742*aa772005SRobert Watson 		return (-1);
743*aa772005SRobert Watson 	}
744*aa772005SRobert Watson 
745*aa772005SRobert Watson 	/* First component of the host name. */
746*aa772005SRobert Watson 	pos = strchr(buf, '.');
747*aa772005SRobert Watson 	if (pos == NULL)
748*aa772005SRobert Watson 		(void)strlcpy(name, buf, size);
749*aa772005SRobert Watson 	else
750*aa772005SRobert Watson 		(void)strlcpy(name, buf, MIN((size_t)(pos - buf + 1), size));
751*aa772005SRobert Watson 
752*aa772005SRobert Watson 	if (name[0] == '\0') {
753*aa772005SRobert Watson 		pjdlog_error("Empty host name.");
754*aa772005SRobert Watson 		return (-1);
755*aa772005SRobert Watson 	}
756*aa772005SRobert Watson 
757*aa772005SRobert Watson 	return (0);
758*aa772005SRobert Watson }
759*aa772005SRobert Watson 
760*aa772005SRobert Watson void
761*aa772005SRobert Watson yyerror(const char *str)
762*aa772005SRobert Watson {
763*aa772005SRobert Watson 
764*aa772005SRobert Watson 	pjdlog_error("Unable to parse configuration file at line %d near '%s': %s",
765*aa772005SRobert Watson 	    lineno, yytext, str);
766*aa772005SRobert Watson }
767*aa772005SRobert Watson 
768*aa772005SRobert Watson struct adist_config *
769*aa772005SRobert Watson yy_config_parse(const char *config, bool exitonerror)
770*aa772005SRobert Watson {
771*aa772005SRobert Watson 	int ret;
772*aa772005SRobert Watson 
773*aa772005SRobert Watson 	curhost = NULL;
774*aa772005SRobert Watson 	cursection = SECTION_GLOBAL;
775*aa772005SRobert Watson 	depth = 0;
776*aa772005SRobert Watson 	lineno = 0;
777*aa772005SRobert Watson 
778*aa772005SRobert Watson 	lconfig = calloc(1, sizeof(*lconfig));
779*aa772005SRobert Watson 	if (lconfig == NULL) {
780*aa772005SRobert Watson 		pjdlog_error("Unable to allocate memory for configuration.");
781*aa772005SRobert Watson 		if (exitonerror)
782*aa772005SRobert Watson 			exit(EX_TEMPFAIL);
783*aa772005SRobert Watson 		return (NULL);
784*aa772005SRobert Watson 	}
785*aa772005SRobert Watson 	TAILQ_INIT(&lconfig->adc_hosts);
786*aa772005SRobert Watson 	TAILQ_INIT(&lconfig->adc_listen);
787*aa772005SRobert Watson 	lconfig->adc_name[0] = '\0';
788*aa772005SRobert Watson 	lconfig->adc_timeout = -1;
789*aa772005SRobert Watson 	lconfig->adc_pidfile[0] = '\0';
790*aa772005SRobert Watson 	lconfig->adc_certfile[0] = '\0';
791*aa772005SRobert Watson 	lconfig->adc_keyfile[0] = '\0';
792*aa772005SRobert Watson 
793*aa772005SRobert Watson 	yyin = fopen(config, "r");
794*aa772005SRobert Watson 	if (yyin == NULL) {
795*aa772005SRobert Watson 		pjdlog_errno(LOG_ERR, "Unable to open configuration file %s",
796*aa772005SRobert Watson 		    config);
797*aa772005SRobert Watson 		yy_config_free(lconfig);
798*aa772005SRobert Watson 		if (exitonerror)
799*aa772005SRobert Watson 			exit(EX_OSFILE);
800*aa772005SRobert Watson 		return (NULL);
801*aa772005SRobert Watson 	}
802*aa772005SRobert Watson 	yyrestart(yyin);
803*aa772005SRobert Watson 	ret = yyparse();
804*aa772005SRobert Watson 	fclose(yyin);
805*aa772005SRobert Watson 	if (ret != 0) {
806*aa772005SRobert Watson 		yy_config_free(lconfig);
807*aa772005SRobert Watson 		if (exitonerror)
808*aa772005SRobert Watson 			exit(EX_CONFIG);
809*aa772005SRobert Watson 		return (NULL);
810*aa772005SRobert Watson 	}
811*aa772005SRobert Watson 
812*aa772005SRobert Watson 	/*
813*aa772005SRobert Watson 	 * Let's see if everything is set up.
814*aa772005SRobert Watson 	 */
815*aa772005SRobert Watson 	if (lconfig->adc_name[0] == '\0' && my_name(lconfig->adc_name,
816*aa772005SRobert Watson 	    sizeof(lconfig->adc_name)) == -1) {
817*aa772005SRobert Watson 		yy_config_free(lconfig);
818*aa772005SRobert Watson 		if (exitonerror)
819*aa772005SRobert Watson 			exit(EX_CONFIG);
820*aa772005SRobert Watson 		return (NULL);
821*aa772005SRobert Watson 	}
822*aa772005SRobert Watson 	if (lconfig->adc_timeout == -1)
823*aa772005SRobert Watson 		lconfig->adc_timeout = ADIST_TIMEOUT;
824*aa772005SRobert Watson 	if (lconfig->adc_pidfile[0] == '\0') {
825*aa772005SRobert Watson 		(void)strlcpy(lconfig->adc_pidfile, ADIST_PIDFILE,
826*aa772005SRobert Watson 		    sizeof(lconfig->adc_pidfile));
827*aa772005SRobert Watson 	}
828*aa772005SRobert Watson 	if (lconfig->adc_certfile[0] == '\0') {
829*aa772005SRobert Watson 		(void)strlcpy(lconfig->adc_certfile, ADIST_CERTFILE,
830*aa772005SRobert Watson 		    sizeof(lconfig->adc_certfile));
831*aa772005SRobert Watson 	}
832*aa772005SRobert Watson 	if (lconfig->adc_keyfile[0] == '\0') {
833*aa772005SRobert Watson 		(void)strlcpy(lconfig->adc_keyfile, ADIST_KEYFILE,
834*aa772005SRobert Watson 		    sizeof(lconfig->adc_keyfile));
835*aa772005SRobert Watson 	}
836*aa772005SRobert Watson 
837*aa772005SRobert Watson 	return (lconfig);
838*aa772005SRobert Watson }
839*aa772005SRobert Watson 
840*aa772005SRobert Watson void
841*aa772005SRobert Watson yy_config_free(struct adist_config *config)
842*aa772005SRobert Watson {
843*aa772005SRobert Watson 	struct adist_host *adhost;
844*aa772005SRobert Watson 	struct adist_listen *lst;
845*aa772005SRobert Watson 
846*aa772005SRobert Watson 	while ((lst = TAILQ_FIRST(&config->adc_listen)) != NULL) {
847*aa772005SRobert Watson 		TAILQ_REMOVE(&config->adc_listen, lst, adl_next);
848*aa772005SRobert Watson 		free(lst);
849*aa772005SRobert Watson 	}
850*aa772005SRobert Watson 	while ((adhost = TAILQ_FIRST(&config->adc_hosts)) != NULL) {
851*aa772005SRobert Watson 		TAILQ_REMOVE(&config->adc_hosts, adhost, adh_next);
852*aa772005SRobert Watson 		bzero(adhost, sizeof(*adhost));
853*aa772005SRobert Watson 		free(adhost);
854*aa772005SRobert Watson 	}
855*aa772005SRobert Watson 	free(config);
856*aa772005SRobert Watson }
857