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