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 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 * 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 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 * 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 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 * 148f875b4ebSrica find_template(const char *name) 149f875b4ebSrica { 150f875b4ebSrica return (find_name(tp_list_head, name)); 151f875b4ebSrica } 152f875b4ebSrica 153f875b4ebSrica static void 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 * 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 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 * 172f875b4ebSrica find_zone(const char *name) 173f875b4ebSrica { 174f875b4ebSrica return (find_name(zc_list_head, name)); 175f875b4ebSrica } 176f875b4ebSrica 177f875b4ebSrica int 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 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 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 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