14746Srica /*
24746Srica * CDDL HEADER START
34746Srica *
44746Srica * The contents of this file are subject to the terms of the
54746Srica * Common Development and Distribution License (the "License").
64746Srica * You may not use this file except in compliance with the License.
74746Srica *
84746Srica * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
94746Srica * or http://www.opensolaris.org/os/licensing.
104746Srica * See the License for the specific language governing permissions
114746Srica * and limitations under the License.
124746Srica *
134746Srica * When distributing Covered Code, include this CDDL HEADER in each
144746Srica * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
154746Srica * If applicable, add the following below this CDDL HEADER, with the
164746Srica * fields enclosed by brackets "[]" replaced with your own identifying
174746Srica * information: Portions Copyright [yyyy] [name of copyright owner]
184746Srica *
194746Srica * CDDL HEADER END
204746Srica */
214746Srica
224746Srica /*
23*9530STon.Nguyen@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
244746Srica * Use is subject to license terms.
254746Srica */
264746Srica
274746Srica /*
284746Srica * tnchkdb.c - Trusted network database checking utility
294746Srica */
304746Srica #include <stdio.h>
314746Srica #include <stdlib.h>
324746Srica #include <errno.h>
334746Srica #include <locale.h>
344746Srica #include <malloc.h>
354746Srica #include <string.h>
364746Srica #include <libtsnet.h>
374746Srica #include <netinet/in.h>
384746Srica #include <nss_dbdefs.h>
394746Srica
404746Srica static void usage(void);
414746Srica static void check_tnrhtp(const char *);
424746Srica static void check_tnrhdb(const char *);
434746Srica static void check_tnzonecfg(const char *);
444746Srica
454746Srica static boolean_t tnrhtp_bad;
464746Srica static int exitval;
474746Srica
484746Srica struct tsol_name_list {
494746Srica struct tsol_name_list *next;
504746Srica int linenum;
514746Srica char name[TNTNAMSIZ];
524746Srica };
534746Srica
544746Srica struct tsol_addr_list {
554746Srica struct tsol_addr_list *next;
564746Srica int linenum;
574746Srica int prefix_len;
584746Srica in6_addr_t addr;
594746Srica };
604746Srica
614746Srica static struct tsol_name_list *tp_list_head;
624746Srica static struct tsol_addr_list *rh_list_head;
634746Srica static struct tsol_name_list *zc_list_head;
644746Srica
654746Srica typedef struct mlp_info_list_s {
664746Srica struct mlp_info_list_s *next;
674746Srica int linenum;
684746Srica tsol_mlp_t mlp;
694746Srica char name[TNTNAMSIZ];
704746Srica } mlp_info_list_t;
714746Srica
724746Srica static mlp_info_list_t *global_mlps;
734746Srica
744746Srica static void
add_name(struct tsol_name_list ** head,const char * name,int linenum)754746Srica add_name(struct tsol_name_list **head, const char *name, int linenum)
764746Srica {
774746Srica int err;
784746Srica struct tsol_name_list *entry;
794746Srica
804746Srica entry = malloc(sizeof (struct tsol_name_list));
814746Srica if (entry == NULL) {
824746Srica err = errno;
834746Srica
844746Srica (void) fprintf(stderr,
854746Srica gettext("tnchkdb: allocating name list: %s\n"),
864746Srica strerror(err));
874746Srica exit(1);
884746Srica }
894746Srica (void) strlcpy(entry->name, name, sizeof (entry->name));
904746Srica entry->next = *head;
914746Srica entry->linenum = linenum;
924746Srica *head = entry;
934746Srica }
944746Srica
954746Srica static struct tsol_name_list *
find_name(struct tsol_name_list * head,const char * name)964746Srica find_name(struct tsol_name_list *head, const char *name)
974746Srica {
984746Srica struct tsol_name_list *entry;
994746Srica
1004746Srica for (entry = head; entry != NULL; entry = entry->next)
1014746Srica if (strcmp(entry->name, name) == 0)
1024746Srica break;
1034746Srica return (entry);
1044746Srica }
1054746Srica
1064746Srica static void
add_addr(struct tsol_addr_list ** head,int prefix_len,in6_addr_t addr,int linenum)1074746Srica add_addr(struct tsol_addr_list **head, int prefix_len, in6_addr_t addr,
1084746Srica int linenum)
1094746Srica {
1104746Srica int err;
1114746Srica struct tsol_addr_list *entry;
1124746Srica
1134746Srica entry = malloc(sizeof (struct tsol_addr_list));
1144746Srica if (entry == NULL) {
1154746Srica err = errno;
1164746Srica
1174746Srica (void) fprintf(stderr,
1184746Srica gettext("tnchkdb: allocating addr list: %s\n"),
1194746Srica strerror(err));
1204746Srica exit(2);
1214746Srica }
1224746Srica entry->prefix_len = prefix_len;
1234746Srica entry->addr = addr;
1244746Srica entry->next = *head;
1254746Srica entry->linenum = linenum;
1264746Srica *head = entry;
1274746Srica }
1284746Srica
1294746Srica static struct tsol_addr_list *
find_addr(struct tsol_addr_list * head,int prefix_len,in6_addr_t addr)1304746Srica find_addr(struct tsol_addr_list *head, int prefix_len, in6_addr_t addr)
1314746Srica {
1324746Srica struct tsol_addr_list *entry;
1334746Srica
1344746Srica for (entry = head; entry != NULL; entry = entry->next)
1354746Srica if (entry->prefix_len == prefix_len &&
1364746Srica IN6_ARE_ADDR_EQUAL(&entry->addr, &addr))
1374746Srica break;
1384746Srica return (entry);
1394746Srica }
1404746Srica
1414746Srica static void
add_template(const char * name,int linenum)1424746Srica add_template(const char *name, int linenum)
1434746Srica {
1444746Srica add_name(&tp_list_head, name, linenum);
1454746Srica }
1464746Srica
1474746Srica static struct tsol_name_list *
find_template(const char * name)1484746Srica find_template(const char *name)
1494746Srica {
1504746Srica return (find_name(tp_list_head, name));
1514746Srica }
1524746Srica
1534746Srica static void
add_host(int prefix_len,in6_addr_t addr,int linenum)1544746Srica add_host(int prefix_len, in6_addr_t addr, int linenum)
1554746Srica {
1564746Srica add_addr(&rh_list_head, prefix_len, addr, linenum);
1574746Srica }
1584746Srica
1594746Srica static struct tsol_addr_list *
find_host(int prefix_len,in6_addr_t addr)1604746Srica find_host(int prefix_len, in6_addr_t addr)
1614746Srica {
1624746Srica return (find_addr(rh_list_head, prefix_len, addr));
1634746Srica }
1644746Srica
1654746Srica static void
add_zone(const char * name,int linenum)1664746Srica add_zone(const char *name, int linenum)
1674746Srica {
1684746Srica add_name(&zc_list_head, name, linenum);
1694746Srica }
1704746Srica
1714746Srica static struct tsol_name_list *
find_zone(const char * name)1724746Srica find_zone(const char *name)
1734746Srica {
1744746Srica return (find_name(zc_list_head, name));
1754746Srica }
1764746Srica
1774746Srica int
main(int argc,char ** argv)1784746Srica main(int argc, char **argv)
1794746Srica {
1804746Srica const char *tnrhdb_file = TNRHDB_PATH;
1814746Srica const char *tnrhtp_file = TNRHTP_PATH;
1824746Srica const char *tnzonecfg_file = TNZONECFG_PATH;
1834746Srica int chr;
1844746Srica
1854746Srica /* set the locale for only the messages system (all else is clean) */
1864746Srica (void) setlocale(LC_ALL, "");
1874746Srica #ifndef TEXT_DOMAIN /* Should be defined by cc -D */
1884746Srica #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it wasn't */
1894746Srica #endif
1904746Srica (void) textdomain(TEXT_DOMAIN);
1914746Srica
1924746Srica while ((chr = getopt(argc, argv, "h:t:z:")) != EOF) {
1934746Srica switch (chr) {
1944746Srica case 'h':
1954746Srica tnrhdb_file = optarg;
1964746Srica break;
1974746Srica case 't':
1984746Srica tnrhtp_file = optarg;
1994746Srica break;
2004746Srica case 'z':
2014746Srica tnzonecfg_file = optarg;
2024746Srica break;
2034746Srica default:
2044746Srica usage();
2054746Srica }
2064746Srica }
2074746Srica
2084746Srica check_tnrhtp(tnrhtp_file);
2094746Srica check_tnrhdb(tnrhdb_file);
2104746Srica check_tnzonecfg(tnzonecfg_file);
2114746Srica
2124746Srica return (exitval);
2134746Srica }
2144746Srica
2154746Srica static void
usage(void)2164746Srica usage(void)
2174746Srica {
2184746Srica (void) fprintf(stderr, gettext(
2194746Srica "usage: tnchkdb [-h path] [-t path] [-z path]\n"));
2204746Srica exit(2);
2214746Srica }
2224746Srica
2234746Srica static void
print_error(int linenum,int err,const char * errstr)2244746Srica print_error(int linenum, int err, const char *errstr)
2254746Srica {
2264746Srica (void) fprintf(stderr, gettext("line %1$d: %2$s: %.32s\n"), linenum,
2274746Srica tsol_strerror(err, errno), errstr);
2284746Srica }
2294746Srica
2304746Srica static void
cipso_representable(const bslabel_t * lab,int linenum,const char * template,const char * name)2314746Srica cipso_representable(const bslabel_t *lab, int linenum, const char *template,
2324746Srica const char *name)
2334746Srica {
2344746Srica const _blevel_impl_t *blab = (const _blevel_impl_t *)lab;
2354746Srica int lclass;
2364746Srica uint32_t c8;
2374746Srica
2384746Srica if (!bltype(lab, SUN_SL_ID)) {
2394746Srica (void) fprintf(stderr, gettext("tnchkdb: "
2404746Srica "%1$s type %2$d is invalid for cipso labels: "
2414746Srica "line %3$d entry %4$s\n"), name, GETBLTYPE(lab), linenum,
2424746Srica template);
2434746Srica exitval = 1;
2444746Srica }
2454746Srica lclass = LCLASS(blab);
2464746Srica if (lclass & 0xff00) {
2474746Srica (void) fprintf(stderr, gettext("tnchkdb: "
2484746Srica "%1$s classification %2$x is invalid for cipso labels: "
2494746Srica "line %3$d entry %4$s\n"), name, lclass, linenum,
2504746Srica template);
2514746Srica exitval = 1;
2524746Srica }
2534746Srica c8 = blab->compartments.c8;
2544746Srica #ifdef _BIG_ENDIAN
2554746Srica if (c8 & 0x0000ffff) {
2564746Srica #else
2574746Srica if (c8 & 0xffff0000) {
2584746Srica #endif
2594746Srica (void) fprintf(stderr, gettext("tnchkdb: %1$s "
2604746Srica "compartments 241-256 must be zero for cipso labels: "
2614746Srica "line %2$d entry %3$s\n"), name, linenum, template);
2624746Srica exitval = 1;
2634746Srica }
2644746Srica }
2654746Srica
2664746Srica static void
2674746Srica check_tnrhtp(const char *file)
2684746Srica {
2694746Srica tsol_tpent_t *tpentp;
2704746Srica tsol_tpstr_t tpstr;
2714746Srica int err;
2724746Srica char *errstr;
2734746Srica FILE *fp;
2744746Srica blevel_t *l1, *l2;
2754746Srica char line[2048], *cp;
2764746Srica int linenum = 0;
2774746Srica struct tsol_name_list *tnl;
2784746Srica char buf[NSS_BUFLEN_TSOL_TP];
2794746Srica uint32_t initial_doi = 0;
2804746Srica boolean_t multiple_doi_found = B_FALSE;
2814746Srica boolean_t doi_zero_found = B_FALSE;
2824746Srica
2834746Srica (void) printf(gettext("checking %s ...\n"), file);
2844746Srica
2854746Srica if ((fp = fopen(file, "r")) == NULL) {
2864746Srica err = errno;
2874746Srica (void) fprintf(stderr,
2884910Ston gettext("tnchkdb: failed to open %1$s: %2$s\n"), file,
2894746Srica strerror(err));
2904746Srica exitval = 2;
2914746Srica tnrhtp_bad = B_TRUE;
2924746Srica return;
2934746Srica }
2944746Srica
2954746Srica while (fgets(line, sizeof (line), fp) != NULL) {
2964746Srica linenum++;
2974746Srica if (line[0] == '#')
2984746Srica continue;
2994746Srica if ((cp = strchr(line, '\n')) != NULL)
3004746Srica *cp = '\0';
3014746Srica (void) str_to_tpstr(line, strlen(line), &tpstr, buf,
3024746Srica sizeof (buf));
3034746Srica tpentp = tpstr_to_ent(&tpstr, &err, &errstr);
3044746Srica if (tpentp == NULL) {
3054746Srica if (err == LTSNET_EMPTY)
3064746Srica continue;
3074746Srica print_error(linenum, err, errstr);
3084746Srica exitval = 1;
3094746Srica /*
3104746Srica * Flag is set *only* for parsing errors, which result
3114746Srica * in omitting the entry from tsol_name_list.
3124746Srica */
3134746Srica tnrhtp_bad = B_TRUE;
3144746Srica continue;
3154746Srica }
3164746Srica
3174746Srica switch (tpentp->host_type) {
3184746Srica case UNLABELED:
3194746Srica /*
3204746Srica * check doi
3214746Srica */
3224746Srica if (initial_doi == 0)
3234746Srica initial_doi = tpentp->tp_cipso_doi_unl;
3244746Srica if (tpentp->tp_cipso_doi_unl != initial_doi)
3254746Srica multiple_doi_found = B_TRUE;
3264746Srica if (tpentp->tp_cipso_doi_unl == 0)
3274746Srica doi_zero_found = B_TRUE;
3284746Srica
3294746Srica cipso_representable(&tpentp->tp_def_label, linenum,
3304746Srica tpentp->name, TP_DEFLABEL);
3314746Srica
3324746Srica /*
3334746Srica * check max_sl dominates min_sl
3344746Srica */
3354746Srica l1 = &tpentp->tp_gw_sl_range.lower_bound;
3364746Srica l2 = &tpentp->tp_gw_sl_range.upper_bound;
3374746Srica if (!bldominates(l2, l1)) {
3384746Srica (void) fprintf(stderr,
3394746Srica gettext("tnchkdb: max_sl does not "
340*9530STon.Nguyen@Sun.COM "dominate min_sl: line %1$d entry %2$s\n"),
3414746Srica linenum, tpentp->name);
3424746Srica exitval = 1;
3434746Srica }
3444746Srica
3454746Srica cipso_representable(l1, linenum, tpentp->name,
3464746Srica TP_MINLABEL);
3474746Srica l1 = (blevel_t *)&tpentp->tp_gw_sl_set[0];
3484746Srica l2 = (blevel_t *)&tpentp->tp_gw_sl_set[NSLS_MAX];
3494746Srica for (; l1 < l2; l1++) {
3504746Srica if (bisinvalid(l1))
3514746Srica break;
3524746Srica cipso_representable(l1, linenum, tpentp->name,
3534746Srica TP_SET);
3544746Srica }
3554746Srica break;
3564746Srica
3574746Srica case SUN_CIPSO:
3584746Srica /*
3594746Srica * check max_sl dominates min_sl
3604746Srica */
3614746Srica l1 = &tpentp->tp_sl_range_cipso.lower_bound;
3624746Srica l2 = &tpentp->tp_sl_range_cipso.upper_bound;
3634746Srica if (!bldominates(l2, l1)) {
3644746Srica (void) fprintf(stderr,
3654746Srica gettext("tnchkdb: max_sl does not "
366*9530STon.Nguyen@Sun.COM "dominate min_sl: line %1$d entry %2$s\n"),
3674746Srica linenum, tpentp->name);
3684746Srica exitval = 1;
3694746Srica }
3704746Srica
3714746Srica cipso_representable(l1, linenum, tpentp->name,
3724746Srica TP_MINLABEL);
3734746Srica
3744746Srica l1 = (blevel_t *)&tpentp->tp_sl_set_cipso[0];
3754746Srica l2 = (blevel_t *)&tpentp->tp_sl_set_cipso[NSLS_MAX];
3764746Srica for (; l1 < l2; l1++) {
3774746Srica if (bisinvalid(l1))
3784746Srica break;
3794746Srica cipso_representable(l1, linenum, tpentp->name,
3804746Srica TP_SET);
3814746Srica }
3824746Srica
3834746Srica /*
3844746Srica * check doi
3854746Srica */
3864746Srica if (initial_doi == 0)
3874746Srica initial_doi = tpentp->tp_cipso_doi_cipso;
3884746Srica if (tpentp->tp_cipso_doi_cipso != initial_doi)
3894746Srica multiple_doi_found = B_TRUE;
3904746Srica if (tpentp->tp_cipso_doi_cipso == 0)
3914746Srica doi_zero_found = B_TRUE;
3924746Srica break;
3934746Srica
3944746Srica default:
3954746Srica (void) fprintf(stderr, gettext("tnchkdb: unknown host "
396*9530STon.Nguyen@Sun.COM "type %1$d: line %2$d entry %3$s\n"),
3974746Srica tpentp->host_type, linenum, tpentp->name);
3984746Srica exitval = 1;
3994746Srica } /* switch */
4004746Srica
4014746Srica /*
4024746Srica * check if a duplicated entry
4034746Srica */
4044746Srica if ((tnl = find_template(tpentp->name)) != NULL) {
4054746Srica (void) fprintf(stderr, gettext("tnchkdb: duplicated "
4064746Srica "entry: %1$s at lines %2$d and %3$d\n"),
4074746Srica tpentp->name, tnl->linenum, linenum);
4084746Srica exitval = 1;
4094746Srica } else {
4104746Srica add_template(tpentp->name, linenum);
4114746Srica }
4124746Srica tsol_freetpent(tpentp);
4134746Srica }
4144746Srica if (multiple_doi_found == B_TRUE) {
4154746Srica (void) fprintf(stderr,
4164746Srica gettext("tnchkdb: Warning: tnrhtp entries do not all "
4174746Srica "contain the same DOI value\n"));
4184746Srica }
4194746Srica if (doi_zero_found == B_TRUE) {
4204746Srica (void) fprintf(stderr,
4214746Srica gettext("tnchkdb: Warning: DOI=0 found in some "
4224746Srica "tnrhtp entries\n"));
4234746Srica }
4244746Srica (void) fclose(fp);
4254746Srica }
4264746Srica
4274746Srica static void
4284746Srica check_tnrhdb(const char *file)
4294746Srica {
4304746Srica tsol_rhent_t *rhentp;
4314746Srica tsol_rhstr_t rhstr;
4324746Srica int err;
4334746Srica char *errstr;
4344746Srica FILE *fp;
4354746Srica char line[2048], *cp;
4364746Srica int linenum;
4374746Srica in6_addr_t addr;
4384746Srica struct tsol_addr_list *tal;
4394746Srica char buf[NSS_BUFLEN_TSOL_RH];
4404746Srica
4414746Srica (void) printf(gettext("checking %s ...\n"), file);
4424746Srica
4434746Srica if ((fp = fopen(file, "r")) == NULL) {
4444746Srica err = errno;
4454746Srica (void) fprintf(stderr,
4464746Srica gettext("tnchkdb: failed to open %s: %s\n"), file,
4474746Srica strerror(err));
4484746Srica exitval = 2;
4494746Srica return;
4504746Srica }
4514746Srica
4524746Srica /*
4534746Srica * check that all templates used in tnrhdb file are defined by tnrhtp
4544746Srica */
4554746Srica linenum = 0;
4564746Srica while (fgets(line, sizeof (line), fp) != NULL) {
4574746Srica linenum++;
4584746Srica if (line[0] == '#')
4594746Srica continue;
4604746Srica if ((cp = strchr(line, '\n')) != NULL)
4614746Srica *cp = '\0';
4624746Srica (void) str_to_rhstr(line, strlen(line), &rhstr, buf,
4634746Srica sizeof (buf));
4644746Srica rhentp = rhstr_to_ent(&rhstr, &err, &errstr);
4654746Srica if (rhentp == NULL) {
4664746Srica if (err == LTSNET_EMPTY)
4674746Srica continue;
4684746Srica print_error(linenum, err, errstr);
4694746Srica exitval = 1;
4704746Srica continue;
4714746Srica }
4724746Srica
4734746Srica if (rhentp->rh_address.ta_family == AF_INET) {
4744746Srica IN6_INADDR_TO_V4MAPPED(&rhentp->rh_address.ta_addr_v4,
4754746Srica &addr);
4764746Srica } else {
4774746Srica addr = rhentp->rh_address.ta_addr_v6;
4784746Srica }
4794746Srica if ((tal = find_host(rhentp->rh_prefix, addr)) != NULL) {
4804746Srica (void) fprintf(stderr,
4814746Srica gettext("tnchkdb: duplicate entry: lines %1$d and "
4824746Srica "%2$d\n"), tal->linenum, linenum);
4834746Srica exitval = 1;
4844746Srica } else {
4854746Srica add_host(rhentp->rh_prefix, addr, linenum);
4864746Srica }
4874746Srica
4884746Srica if (!tnrhtp_bad && find_template(rhentp->rh_template) == NULL) {
4894746Srica (void) fprintf(stderr,
4904746Srica gettext("tnchkdb: unknown template name: %1$s at "
4914746Srica "line %2$d\n"), rhentp->rh_template, linenum);
4924746Srica exitval = 1;
4934746Srica }
4944746Srica
4954746Srica tsol_freerhent(rhentp);
4964746Srica }
4974746Srica (void) fclose(fp);
4984746Srica }
4994746Srica
5004746Srica static void
5014746Srica check_mlp_conflicts(tsol_mlp_t *mlps, boolean_t isglobal, const char *name,
5024746Srica int linenum)
5034746Srica {
5044746Srica tsol_mlp_t *mlpptr, *mlp2;
5054746Srica mlp_info_list_t *mil;
5064746Srica
5074746Srica for (mlpptr = mlps; !TSOL_MLP_END(mlpptr); mlpptr++) {
5084746Srica if (mlpptr->mlp_port_upper == 0)
5094746Srica mlpptr->mlp_port_upper = mlpptr->mlp_port;
5104746Srica
5114746Srica /* First, validate against self for duplicates */
5124746Srica for (mlp2 = mlps; mlp2 < mlpptr; mlp2++) {
5134746Srica if (mlp2->mlp_ipp == mlpptr->mlp_ipp &&
5144746Srica !(mlp2->mlp_port_upper < mlpptr->mlp_port ||
5154746Srica mlp2->mlp_port > mlpptr->mlp_port_upper))
5164746Srica break;
5174746Srica }
5184746Srica
5194746Srica if (mlp2 < mlpptr) {
5204746Srica (void) fprintf(stderr, gettext("tnchkdb: self-overlap "
5214746Srica "of %1$s MLP protocol %2$d port %3$d-%4$d with "
5224746Srica "%5$d-%6$d: zone %7$s line %8$d\n"),
5234746Srica gettext(isglobal ? "global" : "zone-specific"),
5244746Srica mlpptr->mlp_ipp, mlpptr->mlp_port,
5254746Srica mlpptr->mlp_port_upper, mlp2->mlp_port,
5264746Srica mlp2->mlp_port_upper, name, linenum);
5274746Srica exitval = 1;
5284746Srica }
5294746Srica
5304746Srica if (isglobal) {
5314746Srica /* Next, validate against list for duplicates */
5324746Srica for (mil = global_mlps; mil != NULL; mil = mil->next) {
5334746Srica if (strcmp(mil->name, name) == 0)
5344746Srica continue;
5354746Srica if (mil->mlp.mlp_ipp == mlpptr->mlp_ipp &&
5364746Srica !(mil->mlp.mlp_port_upper <
5374746Srica mlpptr->mlp_port ||
5384746Srica mil->mlp.mlp_port >
5394746Srica mlpptr->mlp_port_upper))
5404746Srica break;
5414746Srica }
5424746Srica
5434746Srica if (mil != NULL) {
5444746Srica (void) fprintf(stderr, gettext("tnchkdb: "
545*9530STon.Nguyen@Sun.COM "overlap of global MLP protocol %1$d port "
546*9530STon.Nguyen@Sun.COM "%2$d-%3$d with zone %4$s %5$d-%6$d: zone "
547*9530STon.Nguyen@Sun.COM "%7$s lines %8$d and %9$d\n"),
5484746Srica mlpptr->mlp_ipp, mlpptr->mlp_port,
5494746Srica mlpptr->mlp_port_upper, mil->name,
5504746Srica mil->mlp.mlp_port, mil->mlp.mlp_port_upper,
5514746Srica name, mil->linenum, linenum);
5524746Srica exitval = 1;
5534746Srica }
5544746Srica
5554746Srica /* Now throw into list */
5564746Srica if ((mil = malloc(sizeof (*mil))) == NULL) {
5574746Srica (void) fprintf(stderr, gettext("tnchkdb: "
5584746Srica "malloc error: %s\n"), strerror(errno));
5594746Srica exit(2);
5604746Srica }
5614746Srica (void) strlcpy(mil->name, name, sizeof (mil->name));
5624746Srica mil->linenum = linenum;
5634746Srica mil->mlp = *mlpptr;
5644746Srica mil->next = global_mlps;
5654746Srica global_mlps = mil;
5664746Srica }
5674746Srica }
5684746Srica }
5694746Srica
5704746Srica static void
5714746Srica check_tnzonecfg(const char *file)
5724746Srica {
5734746Srica tsol_zcent_t *zc;
5744746Srica int err;
5754746Srica char *errstr;
5764746Srica FILE *fp;
5774746Srica char line[2048], *cp;
5784746Srica int linenum;
5794746Srica boolean_t saw_global;
5804746Srica struct tsol_name_list *tnl;
5814746Srica
5824746Srica (void) printf(gettext("checking %s ...\n"), file);
5834746Srica
5844746Srica if ((fp = fopen(file, "r")) == NULL) {
5854746Srica err = errno;
5864746Srica (void) fprintf(stderr,
5874746Srica gettext("tnchkdb: failed to open %s: %s\n"), file,
5884746Srica strerror(err));
5894746Srica exitval = 2;
5904746Srica return;
5914746Srica }
5924746Srica
5934746Srica saw_global = B_FALSE;
5944746Srica linenum = 0;
5954746Srica while (fgets(line, sizeof (line), fp) != NULL) {
5964746Srica if ((cp = strchr(line, '\n')) != NULL)
5974746Srica *cp = '\0';
5984746Srica
5994746Srica linenum++;
6004746Srica if ((zc = tsol_sgetzcent(line, &err, &errstr)) == NULL) {
6014746Srica if (err == LTSNET_EMPTY)
6024746Srica continue;
6034746Srica print_error(linenum, err, errstr);
6044746Srica exitval = 1;
6054746Srica continue;
6064746Srica }
6074746Srica
6084746Srica cipso_representable(&zc->zc_label, linenum, zc->zc_name,
6094746Srica "label");
6104746Srica
6114746Srica if (strcmp(zc->zc_name, "global") == 0)
6124746Srica saw_global = B_TRUE;
6134746Srica
6144746Srica if ((tnl = find_zone(zc->zc_name)) != NULL) {
6154746Srica (void) fprintf(stderr,
6164746Srica gettext("tnchkdb: duplicate zones: %1$s at lines "
6174746Srica "%2$d and %3$d\n"), zc->zc_name, tnl->linenum,
6184746Srica linenum);
6194746Srica exitval = 1;
6204746Srica } else {
6214746Srica add_zone(zc->zc_name, linenum);
6224746Srica }
6234746Srica
6244746Srica if (zc->zc_private_mlp != NULL)
6254746Srica check_mlp_conflicts(zc->zc_private_mlp, B_FALSE,
6264746Srica zc->zc_name, linenum);
6274746Srica if (zc->zc_shared_mlp != NULL)
6284746Srica check_mlp_conflicts(zc->zc_shared_mlp, B_TRUE,
6294746Srica zc->zc_name, linenum);
6304746Srica
6314746Srica tsol_freezcent(zc);
6324746Srica }
6334746Srica (void) fclose(fp);
6344746Srica
6354746Srica if (!saw_global) {
6364746Srica (void) fprintf(stderr, gettext("tnchkdb: missing required "
6374746Srica "entry for global zone in %s\n"), file);
6384746Srica exitval = 1;
6394746Srica }
6404746Srica }
641