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