xref: /titanic_54/usr/src/cmd/tsol/tnchkdb/tnchkdb.c (revision f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01)
1*f875b4ebSrica /*
2*f875b4ebSrica  * CDDL HEADER START
3*f875b4ebSrica  *
4*f875b4ebSrica  * The contents of this file are subject to the terms of the
5*f875b4ebSrica  * Common Development and Distribution License (the "License").
6*f875b4ebSrica  * You may not use this file except in compliance with the License.
7*f875b4ebSrica  *
8*f875b4ebSrica  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*f875b4ebSrica  * or http://www.opensolaris.org/os/licensing.
10*f875b4ebSrica  * See the License for the specific language governing permissions
11*f875b4ebSrica  * and limitations under the License.
12*f875b4ebSrica  *
13*f875b4ebSrica  * When distributing Covered Code, include this CDDL HEADER in each
14*f875b4ebSrica  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*f875b4ebSrica  * If applicable, add the following below this CDDL HEADER, with the
16*f875b4ebSrica  * fields enclosed by brackets "[]" replaced with your own identifying
17*f875b4ebSrica  * information: Portions Copyright [yyyy] [name of copyright owner]
18*f875b4ebSrica  *
19*f875b4ebSrica  * CDDL HEADER END
20*f875b4ebSrica  */
21*f875b4ebSrica 
22*f875b4ebSrica /*
23*f875b4ebSrica  *  Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24*f875b4ebSrica  *  Use is subject to license terms.
25*f875b4ebSrica  */
26*f875b4ebSrica 
27*f875b4ebSrica #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*f875b4ebSrica 
29*f875b4ebSrica /*
30*f875b4ebSrica  * tnchkdb.c - Trusted network database checking utility
31*f875b4ebSrica  */
32*f875b4ebSrica #include <stdio.h>
33*f875b4ebSrica #include <stdlib.h>
34*f875b4ebSrica #include <errno.h>
35*f875b4ebSrica #include <locale.h>
36*f875b4ebSrica #include <malloc.h>
37*f875b4ebSrica #include <string.h>
38*f875b4ebSrica #include <libtsnet.h>
39*f875b4ebSrica #include <netinet/in.h>
40*f875b4ebSrica #include <nss_dbdefs.h>
41*f875b4ebSrica 
42*f875b4ebSrica static void usage(void);
43*f875b4ebSrica static void check_tnrhtp(const char *);
44*f875b4ebSrica static void check_tnrhdb(const char *);
45*f875b4ebSrica static void check_tnzonecfg(const char *);
46*f875b4ebSrica 
47*f875b4ebSrica static boolean_t tnrhtp_bad;
48*f875b4ebSrica static int exitval;
49*f875b4ebSrica 
50*f875b4ebSrica struct tsol_name_list {
51*f875b4ebSrica 	struct tsol_name_list *next;
52*f875b4ebSrica 	int linenum;
53*f875b4ebSrica 	char name[TNTNAMSIZ];
54*f875b4ebSrica };
55*f875b4ebSrica 
56*f875b4ebSrica struct tsol_addr_list {
57*f875b4ebSrica 	struct tsol_addr_list *next;
58*f875b4ebSrica 	int linenum;
59*f875b4ebSrica 	int prefix_len;
60*f875b4ebSrica 	in6_addr_t addr;
61*f875b4ebSrica };
62*f875b4ebSrica 
63*f875b4ebSrica static struct tsol_name_list *tp_list_head;
64*f875b4ebSrica static struct tsol_addr_list *rh_list_head;
65*f875b4ebSrica static struct tsol_name_list *zc_list_head;
66*f875b4ebSrica 
67*f875b4ebSrica typedef struct mlp_info_list_s {
68*f875b4ebSrica 	struct mlp_info_list_s *next;
69*f875b4ebSrica 	int linenum;
70*f875b4ebSrica 	tsol_mlp_t mlp;
71*f875b4ebSrica 	char name[TNTNAMSIZ];
72*f875b4ebSrica } mlp_info_list_t;
73*f875b4ebSrica 
74*f875b4ebSrica static mlp_info_list_t *global_mlps;
75*f875b4ebSrica 
76*f875b4ebSrica static void
77*f875b4ebSrica add_name(struct tsol_name_list **head, const char *name, int linenum)
78*f875b4ebSrica {
79*f875b4ebSrica 	int err;
80*f875b4ebSrica 	struct tsol_name_list *entry;
81*f875b4ebSrica 
82*f875b4ebSrica 	entry = malloc(sizeof (struct tsol_name_list));
83*f875b4ebSrica 	if (entry == NULL) {
84*f875b4ebSrica 		err = errno;
85*f875b4ebSrica 
86*f875b4ebSrica 		(void) fprintf(stderr,
87*f875b4ebSrica 		    gettext("tnchkdb: allocating name list: %s\n"),
88*f875b4ebSrica 		    strerror(err));
89*f875b4ebSrica 		exit(1);
90*f875b4ebSrica 	}
91*f875b4ebSrica 	(void) strlcpy(entry->name, name, sizeof (entry->name));
92*f875b4ebSrica 	entry->next = *head;
93*f875b4ebSrica 	entry->linenum = linenum;
94*f875b4ebSrica 	*head = entry;
95*f875b4ebSrica }
96*f875b4ebSrica 
97*f875b4ebSrica static struct tsol_name_list *
98*f875b4ebSrica find_name(struct tsol_name_list *head, const char *name)
99*f875b4ebSrica {
100*f875b4ebSrica 	struct tsol_name_list *entry;
101*f875b4ebSrica 
102*f875b4ebSrica 	for (entry = head; entry != NULL; entry = entry->next)
103*f875b4ebSrica 		if (strcmp(entry->name, name) == 0)
104*f875b4ebSrica 			break;
105*f875b4ebSrica 	return (entry);
106*f875b4ebSrica }
107*f875b4ebSrica 
108*f875b4ebSrica static void
109*f875b4ebSrica add_addr(struct tsol_addr_list **head, int prefix_len, in6_addr_t addr,
110*f875b4ebSrica     int linenum)
111*f875b4ebSrica {
112*f875b4ebSrica 	int err;
113*f875b4ebSrica 	struct tsol_addr_list *entry;
114*f875b4ebSrica 
115*f875b4ebSrica 	entry = malloc(sizeof (struct tsol_addr_list));
116*f875b4ebSrica 	if (entry == NULL) {
117*f875b4ebSrica 		err = errno;
118*f875b4ebSrica 
119*f875b4ebSrica 		(void) fprintf(stderr,
120*f875b4ebSrica 		    gettext("tnchkdb: allocating addr list: %s\n"),
121*f875b4ebSrica 		    strerror(err));
122*f875b4ebSrica 		exit(2);
123*f875b4ebSrica 	}
124*f875b4ebSrica 	entry->prefix_len = prefix_len;
125*f875b4ebSrica 	entry->addr = addr;
126*f875b4ebSrica 	entry->next = *head;
127*f875b4ebSrica 	entry->linenum = linenum;
128*f875b4ebSrica 	*head = entry;
129*f875b4ebSrica }
130*f875b4ebSrica 
131*f875b4ebSrica static struct tsol_addr_list *
132*f875b4ebSrica find_addr(struct tsol_addr_list *head, int prefix_len, in6_addr_t addr)
133*f875b4ebSrica {
134*f875b4ebSrica 	struct tsol_addr_list *entry;
135*f875b4ebSrica 
136*f875b4ebSrica 	for (entry = head; entry != NULL; entry = entry->next)
137*f875b4ebSrica 		if (entry->prefix_len == prefix_len &&
138*f875b4ebSrica 		    IN6_ARE_ADDR_EQUAL(&entry->addr, &addr))
139*f875b4ebSrica 			break;
140*f875b4ebSrica 	return (entry);
141*f875b4ebSrica }
142*f875b4ebSrica 
143*f875b4ebSrica static void
144*f875b4ebSrica add_template(const char *name, int linenum)
145*f875b4ebSrica {
146*f875b4ebSrica 	add_name(&tp_list_head, name, linenum);
147*f875b4ebSrica }
148*f875b4ebSrica 
149*f875b4ebSrica static struct tsol_name_list *
150*f875b4ebSrica find_template(const char *name)
151*f875b4ebSrica {
152*f875b4ebSrica 	return (find_name(tp_list_head, name));
153*f875b4ebSrica }
154*f875b4ebSrica 
155*f875b4ebSrica static void
156*f875b4ebSrica add_host(int prefix_len, in6_addr_t addr, int linenum)
157*f875b4ebSrica {
158*f875b4ebSrica 	add_addr(&rh_list_head, prefix_len, addr, linenum);
159*f875b4ebSrica }
160*f875b4ebSrica 
161*f875b4ebSrica static struct tsol_addr_list *
162*f875b4ebSrica find_host(int prefix_len, in6_addr_t addr)
163*f875b4ebSrica {
164*f875b4ebSrica 	return (find_addr(rh_list_head, prefix_len, addr));
165*f875b4ebSrica }
166*f875b4ebSrica 
167*f875b4ebSrica static void
168*f875b4ebSrica add_zone(const char *name, int linenum)
169*f875b4ebSrica {
170*f875b4ebSrica 	add_name(&zc_list_head, name, linenum);
171*f875b4ebSrica }
172*f875b4ebSrica 
173*f875b4ebSrica static struct tsol_name_list *
174*f875b4ebSrica find_zone(const char *name)
175*f875b4ebSrica {
176*f875b4ebSrica 	return (find_name(zc_list_head, name));
177*f875b4ebSrica }
178*f875b4ebSrica 
179*f875b4ebSrica int
180*f875b4ebSrica main(int argc, char **argv)
181*f875b4ebSrica {
182*f875b4ebSrica 	const char *tnrhdb_file = TNRHDB_PATH;
183*f875b4ebSrica 	const char *tnrhtp_file = TNRHTP_PATH;
184*f875b4ebSrica 	const char *tnzonecfg_file = TNZONECFG_PATH;
185*f875b4ebSrica 	int chr;
186*f875b4ebSrica 
187*f875b4ebSrica 	/* set the locale for only the messages system (all else is clean) */
188*f875b4ebSrica 	(void) setlocale(LC_ALL, "");
189*f875b4ebSrica #ifndef TEXT_DOMAIN		/* Should be defined by cc -D */
190*f875b4ebSrica #define	TEXT_DOMAIN	"SYS_TEST"	/* Use this only if it wasn't */
191*f875b4ebSrica #endif
192*f875b4ebSrica 	(void) textdomain(TEXT_DOMAIN);
193*f875b4ebSrica 
194*f875b4ebSrica 	while ((chr = getopt(argc, argv, "h:t:z:")) != EOF) {
195*f875b4ebSrica 		switch (chr) {
196*f875b4ebSrica 		case 'h':
197*f875b4ebSrica 			tnrhdb_file = optarg;
198*f875b4ebSrica 			break;
199*f875b4ebSrica 		case 't':
200*f875b4ebSrica 			tnrhtp_file = optarg;
201*f875b4ebSrica 			break;
202*f875b4ebSrica 		case 'z':
203*f875b4ebSrica 			tnzonecfg_file = optarg;
204*f875b4ebSrica 			break;
205*f875b4ebSrica 		default:
206*f875b4ebSrica 			usage();
207*f875b4ebSrica 		}
208*f875b4ebSrica 	}
209*f875b4ebSrica 
210*f875b4ebSrica 	check_tnrhtp(tnrhtp_file);
211*f875b4ebSrica 	check_tnrhdb(tnrhdb_file);
212*f875b4ebSrica 	check_tnzonecfg(tnzonecfg_file);
213*f875b4ebSrica 
214*f875b4ebSrica 	return (exitval);
215*f875b4ebSrica }
216*f875b4ebSrica 
217*f875b4ebSrica static void
218*f875b4ebSrica usage(void)
219*f875b4ebSrica {
220*f875b4ebSrica 	(void) fprintf(stderr, gettext(
221*f875b4ebSrica 	    "usage: tnchkdb [-h path] [-t path] [-z path]\n"));
222*f875b4ebSrica 	exit(2);
223*f875b4ebSrica }
224*f875b4ebSrica 
225*f875b4ebSrica static void
226*f875b4ebSrica print_error(int linenum, int err, const char *errstr)
227*f875b4ebSrica {
228*f875b4ebSrica 	(void) fprintf(stderr, gettext("line %1$d: %2$s: %.32s\n"), linenum,
229*f875b4ebSrica 	    tsol_strerror(err, errno), errstr);
230*f875b4ebSrica }
231*f875b4ebSrica 
232*f875b4ebSrica static void
233*f875b4ebSrica cipso_representable(const bslabel_t *lab, int linenum, const char *template,
234*f875b4ebSrica     const char *name)
235*f875b4ebSrica {
236*f875b4ebSrica 	const _blevel_impl_t *blab = (const _blevel_impl_t *)lab;
237*f875b4ebSrica 	int lclass;
238*f875b4ebSrica 	uint32_t c8;
239*f875b4ebSrica 
240*f875b4ebSrica 	if (!bltype(lab, SUN_SL_ID)) {
241*f875b4ebSrica 		(void) fprintf(stderr, gettext("tnchkdb: "
242*f875b4ebSrica 		    "%1$s type %2$d is invalid for cipso labels: "
243*f875b4ebSrica 		    "line %3$d entry %4$s\n"), name, GETBLTYPE(lab), linenum,
244*f875b4ebSrica 		    template);
245*f875b4ebSrica 		exitval = 1;
246*f875b4ebSrica 	}
247*f875b4ebSrica 	lclass = LCLASS(blab);
248*f875b4ebSrica 	if (lclass & 0xff00) {
249*f875b4ebSrica 		(void) fprintf(stderr, gettext("tnchkdb: "
250*f875b4ebSrica 		    "%1$s classification %2$x is invalid for cipso labels: "
251*f875b4ebSrica 		    "line %3$d entry %4$s\n"), name, lclass, linenum,
252*f875b4ebSrica 		    template);
253*f875b4ebSrica 		exitval = 1;
254*f875b4ebSrica 	}
255*f875b4ebSrica 	c8 = blab->compartments.c8;
256*f875b4ebSrica #ifdef  _BIG_ENDIAN
257*f875b4ebSrica 	if (c8 & 0x0000ffff) {
258*f875b4ebSrica #else
259*f875b4ebSrica 	if (c8 & 0xffff0000) {
260*f875b4ebSrica #endif
261*f875b4ebSrica 		(void) fprintf(stderr, gettext("tnchkdb: %1$s "
262*f875b4ebSrica 		    "compartments 241-256 must be zero for cipso labels: "
263*f875b4ebSrica 		    "line %2$d entry %3$s\n"), name, linenum, template);
264*f875b4ebSrica 		exitval = 1;
265*f875b4ebSrica 	}
266*f875b4ebSrica }
267*f875b4ebSrica 
268*f875b4ebSrica static void
269*f875b4ebSrica check_tnrhtp(const char *file)
270*f875b4ebSrica {
271*f875b4ebSrica 	tsol_tpent_t *tpentp;
272*f875b4ebSrica 	tsol_tpstr_t tpstr;
273*f875b4ebSrica 	int err;
274*f875b4ebSrica 	char *errstr;
275*f875b4ebSrica 	FILE *fp;
276*f875b4ebSrica 	blevel_t *l1, *l2;
277*f875b4ebSrica 	char line[2048], *cp;
278*f875b4ebSrica 	int linenum = 0;
279*f875b4ebSrica 	struct tsol_name_list *tnl;
280*f875b4ebSrica 	char buf[NSS_BUFLEN_TSOL_TP];
281*f875b4ebSrica 	uint32_t initial_doi = 0;
282*f875b4ebSrica 	boolean_t multiple_doi_found = B_FALSE;
283*f875b4ebSrica 	boolean_t doi_zero_found = B_FALSE;
284*f875b4ebSrica 
285*f875b4ebSrica 	(void) printf(gettext("checking %s ...\n"), file);
286*f875b4ebSrica 
287*f875b4ebSrica 	if ((fp = fopen(file, "r")) == NULL) {
288*f875b4ebSrica 		err = errno;
289*f875b4ebSrica 		(void) fprintf(stderr,
290*f875b4ebSrica 		    gettext("tnchkdb: cannot open %1$s: %2$s\n"), file,
291*f875b4ebSrica 		    strerror(err));
292*f875b4ebSrica 		exitval = 2;
293*f875b4ebSrica 		tnrhtp_bad = B_TRUE;
294*f875b4ebSrica 		return;
295*f875b4ebSrica 	}
296*f875b4ebSrica 
297*f875b4ebSrica 	while (fgets(line, sizeof (line), fp) != NULL) {
298*f875b4ebSrica 		linenum++;
299*f875b4ebSrica 		if (line[0] == '#')
300*f875b4ebSrica 			continue;
301*f875b4ebSrica 		if ((cp = strchr(line, '\n')) != NULL)
302*f875b4ebSrica 			*cp = '\0';
303*f875b4ebSrica 		(void) str_to_tpstr(line, strlen(line), &tpstr, buf,
304*f875b4ebSrica 		    sizeof (buf));
305*f875b4ebSrica 		tpentp = tpstr_to_ent(&tpstr, &err, &errstr);
306*f875b4ebSrica 		if (tpentp == NULL) {
307*f875b4ebSrica 			if (err == LTSNET_EMPTY)
308*f875b4ebSrica 				continue;
309*f875b4ebSrica 			print_error(linenum, err, errstr);
310*f875b4ebSrica 			exitval = 1;
311*f875b4ebSrica 			/*
312*f875b4ebSrica 			 * Flag is set *only* for parsing errors, which result
313*f875b4ebSrica 			 * in omitting the entry from tsol_name_list.
314*f875b4ebSrica 			 */
315*f875b4ebSrica 			tnrhtp_bad = B_TRUE;
316*f875b4ebSrica 			continue;
317*f875b4ebSrica 		}
318*f875b4ebSrica 
319*f875b4ebSrica 		switch (tpentp->host_type) {
320*f875b4ebSrica 		case UNLABELED:
321*f875b4ebSrica 			/*
322*f875b4ebSrica 			 * check doi
323*f875b4ebSrica 			 */
324*f875b4ebSrica 			if (initial_doi == 0)
325*f875b4ebSrica 				initial_doi = tpentp->tp_cipso_doi_unl;
326*f875b4ebSrica 			if (tpentp->tp_cipso_doi_unl != initial_doi)
327*f875b4ebSrica 				multiple_doi_found = B_TRUE;
328*f875b4ebSrica 			if (tpentp->tp_cipso_doi_unl == 0)
329*f875b4ebSrica 				doi_zero_found = B_TRUE;
330*f875b4ebSrica 
331*f875b4ebSrica 			cipso_representable(&tpentp->tp_def_label, linenum,
332*f875b4ebSrica 			    tpentp->name, TP_DEFLABEL);
333*f875b4ebSrica 
334*f875b4ebSrica 			/*
335*f875b4ebSrica 			 * check max_sl dominates min_sl
336*f875b4ebSrica 			 */
337*f875b4ebSrica 			l1 = &tpentp->tp_gw_sl_range.lower_bound;
338*f875b4ebSrica 			l2 = &tpentp->tp_gw_sl_range.upper_bound;
339*f875b4ebSrica 			if (!bldominates(l2, l1)) {
340*f875b4ebSrica 				(void) fprintf(stderr,
341*f875b4ebSrica 				    gettext("tnchkdb: max_sl does not "
342*f875b4ebSrica 				    "dominate min_sl: line %$1d entry %2$s\n"),
343*f875b4ebSrica 				    linenum, tpentp->name);
344*f875b4ebSrica 				exitval = 1;
345*f875b4ebSrica 			}
346*f875b4ebSrica 
347*f875b4ebSrica 			cipso_representable(l1, linenum, tpentp->name,
348*f875b4ebSrica 			    TP_MINLABEL);
349*f875b4ebSrica 			l1 = (blevel_t *)&tpentp->tp_gw_sl_set[0];
350*f875b4ebSrica 			l2 = (blevel_t *)&tpentp->tp_gw_sl_set[NSLS_MAX];
351*f875b4ebSrica 			for (; l1 < l2; l1++) {
352*f875b4ebSrica 				if (bisinvalid(l1))
353*f875b4ebSrica 					break;
354*f875b4ebSrica 				cipso_representable(l1, linenum, tpentp->name,
355*f875b4ebSrica 				    TP_SET);
356*f875b4ebSrica 			}
357*f875b4ebSrica 			break;
358*f875b4ebSrica 
359*f875b4ebSrica 		case SUN_CIPSO:
360*f875b4ebSrica 			/*
361*f875b4ebSrica 			 * check max_sl dominates min_sl
362*f875b4ebSrica 			 */
363*f875b4ebSrica 			l1 = &tpentp->tp_sl_range_cipso.lower_bound;
364*f875b4ebSrica 			l2 = &tpentp->tp_sl_range_cipso.upper_bound;
365*f875b4ebSrica 			if (!bldominates(l2, l1)) {
366*f875b4ebSrica 				(void) fprintf(stderr,
367*f875b4ebSrica 				    gettext("tnchkdb: max_sl does not "
368*f875b4ebSrica 				    "dominate min_sl: line %$1d entry %2$s\n"),
369*f875b4ebSrica 				    linenum, tpentp->name);
370*f875b4ebSrica 				exitval = 1;
371*f875b4ebSrica 			}
372*f875b4ebSrica 
373*f875b4ebSrica 			cipso_representable(l1, linenum, tpentp->name,
374*f875b4ebSrica 			    TP_MINLABEL);
375*f875b4ebSrica 
376*f875b4ebSrica 			l1 = (blevel_t *)&tpentp->tp_sl_set_cipso[0];
377*f875b4ebSrica 			l2 = (blevel_t *)&tpentp->tp_sl_set_cipso[NSLS_MAX];
378*f875b4ebSrica 			for (; l1 < l2; l1++) {
379*f875b4ebSrica 				if (bisinvalid(l1))
380*f875b4ebSrica 					break;
381*f875b4ebSrica 				cipso_representable(l1, linenum, tpentp->name,
382*f875b4ebSrica 				    TP_SET);
383*f875b4ebSrica 			}
384*f875b4ebSrica 
385*f875b4ebSrica 			/*
386*f875b4ebSrica 			 * check doi
387*f875b4ebSrica 			 */
388*f875b4ebSrica 			if (initial_doi == 0)
389*f875b4ebSrica 				initial_doi = tpentp->tp_cipso_doi_cipso;
390*f875b4ebSrica 			if (tpentp->tp_cipso_doi_cipso != initial_doi)
391*f875b4ebSrica 				multiple_doi_found = B_TRUE;
392*f875b4ebSrica 			if (tpentp->tp_cipso_doi_cipso == 0)
393*f875b4ebSrica 				doi_zero_found = B_TRUE;
394*f875b4ebSrica 			break;
395*f875b4ebSrica 
396*f875b4ebSrica 		default:
397*f875b4ebSrica 			(void) fprintf(stderr, gettext("tnchkdb: unknown host "
398*f875b4ebSrica 			    "type %$1d: line %2$d entry %3$s\n"),
399*f875b4ebSrica 			    tpentp->host_type, linenum, tpentp->name);
400*f875b4ebSrica 			exitval = 1;
401*f875b4ebSrica 		} /* switch */
402*f875b4ebSrica 
403*f875b4ebSrica 		/*
404*f875b4ebSrica 		 * check if a duplicated entry
405*f875b4ebSrica 		 */
406*f875b4ebSrica 		if ((tnl = find_template(tpentp->name)) != NULL) {
407*f875b4ebSrica 			(void) fprintf(stderr, gettext("tnchkdb: duplicated "
408*f875b4ebSrica 			    "entry: %1$s at lines %2$d and %3$d\n"),
409*f875b4ebSrica 			    tpentp->name, tnl->linenum, linenum);
410*f875b4ebSrica 			exitval = 1;
411*f875b4ebSrica 		} else {
412*f875b4ebSrica 			add_template(tpentp->name, linenum);
413*f875b4ebSrica 		}
414*f875b4ebSrica 		tsol_freetpent(tpentp);
415*f875b4ebSrica 	}
416*f875b4ebSrica 	if (multiple_doi_found == B_TRUE) {
417*f875b4ebSrica 		(void) fprintf(stderr,
418*f875b4ebSrica 		    gettext("tnchkdb: Warning: tnrhtp entries do not all "
419*f875b4ebSrica 		    "contain the same DOI value\n"));
420*f875b4ebSrica 	}
421*f875b4ebSrica 	if (doi_zero_found == B_TRUE) {
422*f875b4ebSrica 		(void) fprintf(stderr,
423*f875b4ebSrica 		    gettext("tnchkdb: Warning: DOI=0 found in some "
424*f875b4ebSrica 		    "tnrhtp entries\n"));
425*f875b4ebSrica 	}
426*f875b4ebSrica 	(void) fclose(fp);
427*f875b4ebSrica }
428*f875b4ebSrica 
429*f875b4ebSrica static void
430*f875b4ebSrica check_tnrhdb(const char *file)
431*f875b4ebSrica {
432*f875b4ebSrica 	tsol_rhent_t *rhentp;
433*f875b4ebSrica 	tsol_rhstr_t rhstr;
434*f875b4ebSrica 	int err;
435*f875b4ebSrica 	char *errstr;
436*f875b4ebSrica 	FILE *fp;
437*f875b4ebSrica 	char line[2048], *cp;
438*f875b4ebSrica 	int linenum;
439*f875b4ebSrica 	in6_addr_t addr;
440*f875b4ebSrica 	struct tsol_addr_list *tal;
441*f875b4ebSrica 	char buf[NSS_BUFLEN_TSOL_RH];
442*f875b4ebSrica 
443*f875b4ebSrica 	(void) printf(gettext("checking %s ...\n"), file);
444*f875b4ebSrica 
445*f875b4ebSrica 	if ((fp = fopen(file, "r")) == NULL) {
446*f875b4ebSrica 		err = errno;
447*f875b4ebSrica 		(void) fprintf(stderr,
448*f875b4ebSrica 		    gettext("tnchkdb: failed to open %s: %s\n"), file,
449*f875b4ebSrica 		    strerror(err));
450*f875b4ebSrica 		exitval = 2;
451*f875b4ebSrica 		return;
452*f875b4ebSrica 	}
453*f875b4ebSrica 
454*f875b4ebSrica 	/*
455*f875b4ebSrica 	 * check that all templates used in tnrhdb file are defined by tnrhtp
456*f875b4ebSrica 	 */
457*f875b4ebSrica 	linenum = 0;
458*f875b4ebSrica 	while (fgets(line, sizeof (line), fp) != NULL) {
459*f875b4ebSrica 		linenum++;
460*f875b4ebSrica 		if (line[0] == '#')
461*f875b4ebSrica 			continue;
462*f875b4ebSrica 		if ((cp = strchr(line, '\n')) != NULL)
463*f875b4ebSrica 			*cp = '\0';
464*f875b4ebSrica 		(void) str_to_rhstr(line, strlen(line), &rhstr, buf,
465*f875b4ebSrica 		    sizeof (buf));
466*f875b4ebSrica 		rhentp = rhstr_to_ent(&rhstr, &err, &errstr);
467*f875b4ebSrica 		if (rhentp == NULL) {
468*f875b4ebSrica 			if (err == LTSNET_EMPTY)
469*f875b4ebSrica 				continue;
470*f875b4ebSrica 			print_error(linenum, err, errstr);
471*f875b4ebSrica 			exitval = 1;
472*f875b4ebSrica 			continue;
473*f875b4ebSrica 		}
474*f875b4ebSrica 
475*f875b4ebSrica 		if (rhentp->rh_address.ta_family == AF_INET) {
476*f875b4ebSrica 			IN6_INADDR_TO_V4MAPPED(&rhentp->rh_address.ta_addr_v4,
477*f875b4ebSrica 			    &addr);
478*f875b4ebSrica 		} else {
479*f875b4ebSrica 			addr = rhentp->rh_address.ta_addr_v6;
480*f875b4ebSrica 		}
481*f875b4ebSrica 		if ((tal = find_host(rhentp->rh_prefix, addr)) != NULL) {
482*f875b4ebSrica 			(void) fprintf(stderr,
483*f875b4ebSrica 			    gettext("tnchkdb: duplicate entry: lines %1$d and "
484*f875b4ebSrica 			    "%2$d\n"), tal->linenum, linenum);
485*f875b4ebSrica 			exitval = 1;
486*f875b4ebSrica 		} else {
487*f875b4ebSrica 			add_host(rhentp->rh_prefix, addr, linenum);
488*f875b4ebSrica 		}
489*f875b4ebSrica 
490*f875b4ebSrica 		if (!tnrhtp_bad && find_template(rhentp->rh_template) == NULL) {
491*f875b4ebSrica 			(void) fprintf(stderr,
492*f875b4ebSrica 			    gettext("tnchkdb: unknown template name: %1$s at "
493*f875b4ebSrica 			    "line %2$d\n"), rhentp->rh_template, linenum);
494*f875b4ebSrica 			exitval = 1;
495*f875b4ebSrica 		}
496*f875b4ebSrica 
497*f875b4ebSrica 		tsol_freerhent(rhentp);
498*f875b4ebSrica 	}
499*f875b4ebSrica 	(void) fclose(fp);
500*f875b4ebSrica }
501*f875b4ebSrica 
502*f875b4ebSrica static void
503*f875b4ebSrica check_mlp_conflicts(tsol_mlp_t *mlps, boolean_t isglobal, const char *name,
504*f875b4ebSrica     int linenum)
505*f875b4ebSrica {
506*f875b4ebSrica 	tsol_mlp_t *mlpptr, *mlp2;
507*f875b4ebSrica 	mlp_info_list_t *mil;
508*f875b4ebSrica 
509*f875b4ebSrica 	for (mlpptr = mlps; !TSOL_MLP_END(mlpptr); mlpptr++) {
510*f875b4ebSrica 		if (mlpptr->mlp_port_upper == 0)
511*f875b4ebSrica 			mlpptr->mlp_port_upper = mlpptr->mlp_port;
512*f875b4ebSrica 
513*f875b4ebSrica 		/* First, validate against self for duplicates */
514*f875b4ebSrica 		for (mlp2 = mlps; mlp2 < mlpptr; mlp2++) {
515*f875b4ebSrica 			if (mlp2->mlp_ipp == mlpptr->mlp_ipp &&
516*f875b4ebSrica 			    !(mlp2->mlp_port_upper < mlpptr->mlp_port ||
517*f875b4ebSrica 			    mlp2->mlp_port > mlpptr->mlp_port_upper))
518*f875b4ebSrica 				break;
519*f875b4ebSrica 		}
520*f875b4ebSrica 
521*f875b4ebSrica 		if (mlp2 < mlpptr) {
522*f875b4ebSrica 			(void) fprintf(stderr, gettext("tnchkdb: self-overlap "
523*f875b4ebSrica 			    "of %1$s MLP protocol %2$d port %3$d-%4$d with "
524*f875b4ebSrica 			    "%5$d-%6$d: zone %7$s line %8$d\n"),
525*f875b4ebSrica 			    gettext(isglobal ? "global" : "zone-specific"),
526*f875b4ebSrica 			    mlpptr->mlp_ipp, mlpptr->mlp_port,
527*f875b4ebSrica 			    mlpptr->mlp_port_upper, mlp2->mlp_port,
528*f875b4ebSrica 			    mlp2->mlp_port_upper, name, linenum);
529*f875b4ebSrica 			exitval = 1;
530*f875b4ebSrica 		}
531*f875b4ebSrica 
532*f875b4ebSrica 		if (isglobal) {
533*f875b4ebSrica 			/* Next, validate against list for duplicates */
534*f875b4ebSrica 			for (mil = global_mlps; mil != NULL; mil = mil->next) {
535*f875b4ebSrica 				if (strcmp(mil->name, name) == 0)
536*f875b4ebSrica 					continue;
537*f875b4ebSrica 				if (mil->mlp.mlp_ipp == mlpptr->mlp_ipp &&
538*f875b4ebSrica 				    !(mil->mlp.mlp_port_upper <
539*f875b4ebSrica 				    mlpptr->mlp_port ||
540*f875b4ebSrica 				    mil->mlp.mlp_port >
541*f875b4ebSrica 				    mlpptr->mlp_port_upper))
542*f875b4ebSrica 					break;
543*f875b4ebSrica 			}
544*f875b4ebSrica 
545*f875b4ebSrica 			if (mil != NULL) {
546*f875b4ebSrica 				(void) fprintf(stderr, gettext("tnchkdb: "
547*f875b4ebSrica 				    "overlap of global MLP protocol %2$d port "
548*f875b4ebSrica 				    "%3$d-%4$d with zone %$5s %6$d-%7$d: zone "
549*f875b4ebSrica 				    "%8$s lines %9$d and %10$d\n"),
550*f875b4ebSrica 				    mlpptr->mlp_ipp, mlpptr->mlp_port,
551*f875b4ebSrica 				    mlpptr->mlp_port_upper, mil->name,
552*f875b4ebSrica 				    mil->mlp.mlp_port, mil->mlp.mlp_port_upper,
553*f875b4ebSrica 				    name, mil->linenum, linenum);
554*f875b4ebSrica 				exitval = 1;
555*f875b4ebSrica 			}
556*f875b4ebSrica 
557*f875b4ebSrica 			/* Now throw into list */
558*f875b4ebSrica 			if ((mil = malloc(sizeof (*mil))) == NULL) {
559*f875b4ebSrica 				(void) fprintf(stderr, gettext("tnchkdb: "
560*f875b4ebSrica 				    "malloc error: %s\n"), strerror(errno));
561*f875b4ebSrica 				exit(2);
562*f875b4ebSrica 			}
563*f875b4ebSrica 			(void) strlcpy(mil->name, name, sizeof (mil->name));
564*f875b4ebSrica 			mil->linenum = linenum;
565*f875b4ebSrica 			mil->mlp = *mlpptr;
566*f875b4ebSrica 			mil->next = global_mlps;
567*f875b4ebSrica 			global_mlps = mil;
568*f875b4ebSrica 		}
569*f875b4ebSrica 	}
570*f875b4ebSrica }
571*f875b4ebSrica 
572*f875b4ebSrica static void
573*f875b4ebSrica check_tnzonecfg(const char *file)
574*f875b4ebSrica {
575*f875b4ebSrica 	tsol_zcent_t *zc;
576*f875b4ebSrica 	int err;
577*f875b4ebSrica 	char *errstr;
578*f875b4ebSrica 	FILE *fp;
579*f875b4ebSrica 	char line[2048], *cp;
580*f875b4ebSrica 	int linenum;
581*f875b4ebSrica 	boolean_t saw_global;
582*f875b4ebSrica 	struct tsol_name_list *tnl;
583*f875b4ebSrica 
584*f875b4ebSrica 	(void) printf(gettext("checking %s ...\n"), file);
585*f875b4ebSrica 
586*f875b4ebSrica 	if ((fp = fopen(file, "r")) == NULL) {
587*f875b4ebSrica 		err = errno;
588*f875b4ebSrica 		(void) fprintf(stderr,
589*f875b4ebSrica 		    gettext("tnchkdb: failed to open %s: %s\n"), file,
590*f875b4ebSrica 		    strerror(err));
591*f875b4ebSrica 		exitval = 2;
592*f875b4ebSrica 		return;
593*f875b4ebSrica 	}
594*f875b4ebSrica 
595*f875b4ebSrica 	saw_global = B_FALSE;
596*f875b4ebSrica 	linenum = 0;
597*f875b4ebSrica 	while (fgets(line, sizeof (line), fp) != NULL) {
598*f875b4ebSrica 		if ((cp = strchr(line, '\n')) != NULL)
599*f875b4ebSrica 			*cp = '\0';
600*f875b4ebSrica 
601*f875b4ebSrica 		linenum++;
602*f875b4ebSrica 		if ((zc = tsol_sgetzcent(line, &err, &errstr)) == NULL) {
603*f875b4ebSrica 			if (err == LTSNET_EMPTY)
604*f875b4ebSrica 				continue;
605*f875b4ebSrica 			print_error(linenum, err, errstr);
606*f875b4ebSrica 			exitval = 1;
607*f875b4ebSrica 			continue;
608*f875b4ebSrica 		}
609*f875b4ebSrica 
610*f875b4ebSrica 		cipso_representable(&zc->zc_label, linenum, zc->zc_name,
611*f875b4ebSrica 		    "label");
612*f875b4ebSrica 
613*f875b4ebSrica 		if (strcmp(zc->zc_name, "global") == 0)
614*f875b4ebSrica 			saw_global = B_TRUE;
615*f875b4ebSrica 
616*f875b4ebSrica 		if ((tnl = find_zone(zc->zc_name)) != NULL) {
617*f875b4ebSrica 			(void) fprintf(stderr,
618*f875b4ebSrica 			    gettext("tnchkdb: duplicate zones: %1$s at lines "
619*f875b4ebSrica 			    "%2$d and %3$d\n"), zc->zc_name, tnl->linenum,
620*f875b4ebSrica 			    linenum);
621*f875b4ebSrica 			exitval = 1;
622*f875b4ebSrica 		} else {
623*f875b4ebSrica 			add_zone(zc->zc_name, linenum);
624*f875b4ebSrica 		}
625*f875b4ebSrica 
626*f875b4ebSrica 		if (zc->zc_private_mlp != NULL)
627*f875b4ebSrica 			check_mlp_conflicts(zc->zc_private_mlp, B_FALSE,
628*f875b4ebSrica 			    zc->zc_name, linenum);
629*f875b4ebSrica 		if (zc->zc_shared_mlp != NULL)
630*f875b4ebSrica 			check_mlp_conflicts(zc->zc_shared_mlp, B_TRUE,
631*f875b4ebSrica 			    zc->zc_name, linenum);
632*f875b4ebSrica 
633*f875b4ebSrica 		tsol_freezcent(zc);
634*f875b4ebSrica 	}
635*f875b4ebSrica 	(void) fclose(fp);
636*f875b4ebSrica 
637*f875b4ebSrica 	if (!saw_global) {
638*f875b4ebSrica 		(void) fprintf(stderr, gettext("tnchkdb: missing required "
639*f875b4ebSrica 		    "entry for global zone in %s\n"), file);
640*f875b4ebSrica 		exitval = 1;
641*f875b4ebSrica 	}
642*f875b4ebSrica }
643