1 /* 2 * zonec.c -- zone compiler. 3 * 4 * Copyright (c) 2001-2006, NLnet Labs. All rights reserved. 5 * 6 * See LICENSE for the license. 7 * 8 */ 9 10 #include "config.h" 11 12 #include <assert.h> 13 #include <fcntl.h> 14 #include <ctype.h> 15 #include <errno.h> 16 #include <limits.h> 17 #include <stdio.h> 18 #include <string.h> 19 #ifdef HAVE_STRINGS_H 20 #include <strings.h> 21 #endif 22 #include <unistd.h> 23 #include <stdlib.h> 24 #include <time.h> 25 #ifdef HAVE_SYS_STAT_H 26 #include <sys/stat.h> 27 #endif 28 29 #include <netinet/in.h> 30 31 #ifdef HAVE_NETDB_H 32 #include <netdb.h> 33 #endif 34 35 #include "zonec.h" 36 37 #include "dname.h" 38 #include "dns.h" 39 #include "namedb.h" 40 #include "rdata.h" 41 #include "region-allocator.h" 42 #include "util.h" 43 #include "zparser.h" 44 #include "options.h" 45 #include "nsec3.h" 46 47 #define ILNP_MAXDIGITS 4 48 #define ILNP_NUMGROUPS 4 49 50 const dname_type *error_dname; 51 domain_type *error_domain; 52 53 static time_t startzonec = 0; 54 static long int totalrrs = 0; 55 56 extern uint8_t nsecbits[NSEC_WINDOW_COUNT][NSEC_WINDOW_BITS_SIZE]; 57 extern uint16_t nsec_highest_rcode; 58 59 60 /* 61 * Allocate SIZE+sizeof(uint16_t) bytes and store SIZE in the first 62 * element. Return a pointer to the allocation. 63 */ 64 static uint16_t * 65 alloc_rdata(region_type *region, size_t size) 66 { 67 uint16_t *result = region_alloc(region, sizeof(uint16_t) + size); 68 *result = size; 69 return result; 70 } 71 72 uint16_t * 73 alloc_rdata_init(region_type *region, const void *data, size_t size) 74 { 75 uint16_t *result = region_alloc(region, sizeof(uint16_t) + size); 76 *result = size; 77 memcpy(result + 1, data, size); 78 return result; 79 } 80 81 /* 82 * These are parser function for generic zone file stuff. 83 */ 84 uint16_t * 85 zparser_conv_hex(region_type *region, const char *hex, size_t len) 86 { 87 /* convert a hex value to wireformat */ 88 uint16_t *r = NULL; 89 uint8_t *t; 90 int i; 91 92 if (len % 2 != 0) { 93 zc_error_prev_line("number of hex digits must be a multiple of 2"); 94 } else if (len > MAX_RDLENGTH * 2) { 95 zc_error_prev_line("hex data exceeds maximum rdata length (%d)", 96 MAX_RDLENGTH); 97 } else { 98 /* the length part */ 99 r = alloc_rdata(region, len/2); 100 t = (uint8_t *)(r + 1); 101 102 /* Now process octet by octet... */ 103 while (*hex) { 104 *t = 0; 105 for (i = 16; i >= 1; i -= 15) { 106 if (isxdigit((unsigned char)*hex)) { 107 *t += hexdigit_to_int(*hex) * i; 108 } else { 109 zc_error_prev_line( 110 "illegal hex character '%c'", 111 (int) *hex); 112 return NULL; 113 } 114 ++hex; 115 } 116 ++t; 117 } 118 } 119 return r; 120 } 121 122 /* convert hex, precede by a 1-byte length */ 123 uint16_t * 124 zparser_conv_hex_length(region_type *region, const char *hex, size_t len) 125 { 126 uint16_t *r = NULL; 127 uint8_t *t; 128 int i; 129 if (len % 2 != 0) { 130 zc_error_prev_line("number of hex digits must be a multiple of 2"); 131 } else if (len > 255 * 2) { 132 zc_error_prev_line("hex data exceeds 255 bytes"); 133 } else { 134 uint8_t *l; 135 136 /* the length part */ 137 r = alloc_rdata(region, len/2+1); 138 t = (uint8_t *)(r + 1); 139 140 l = t++; 141 *l = '\0'; 142 143 /* Now process octet by octet... */ 144 while (*hex) { 145 *t = 0; 146 for (i = 16; i >= 1; i -= 15) { 147 if (isxdigit((unsigned char)*hex)) { 148 *t += hexdigit_to_int(*hex) * i; 149 } else { 150 zc_error_prev_line( 151 "illegal hex character '%c'", 152 (int) *hex); 153 return NULL; 154 } 155 ++hex; 156 } 157 ++t; 158 ++*l; 159 } 160 } 161 return r; 162 } 163 164 uint16_t * 165 zparser_conv_time(region_type *region, const char *time) 166 { 167 /* convert a time YYHM to wireformat */ 168 uint16_t *r = NULL; 169 struct tm tm; 170 171 /* Try to scan the time... */ 172 if (!strptime(time, "%Y%m%d%H%M%S", &tm)) { 173 zc_error_prev_line("date and time is expected"); 174 } else { 175 uint32_t l = htonl(mktime_from_utc(&tm)); 176 r = alloc_rdata_init(region, &l, sizeof(l)); 177 } 178 return r; 179 } 180 181 uint16_t * 182 zparser_conv_services(region_type *region, const char *protostr, 183 char *servicestr) 184 { 185 /* 186 * Convert a protocol and a list of service port numbers 187 * (separated by spaces) in the rdata to wireformat 188 */ 189 uint16_t *r = NULL; 190 uint8_t *p; 191 uint8_t bitmap[65536/8]; 192 char sep[] = " "; 193 char *word; 194 int max_port = -8; 195 /* convert a protocol in the rdata to wireformat */ 196 struct protoent *proto; 197 198 memset(bitmap, 0, sizeof(bitmap)); 199 200 proto = getprotobyname(protostr); 201 if (!proto) { 202 proto = getprotobynumber(atoi(protostr)); 203 } 204 if (!proto) { 205 zc_error_prev_line("unknown protocol '%s'", protostr); 206 return NULL; 207 } 208 209 for (word = strtok(servicestr, sep); word; word = strtok(NULL, sep)) { 210 struct servent *service; 211 int port; 212 213 service = getservbyname(word, proto->p_name); 214 if (service) { 215 /* Note: ntohs not ntohl! Strange but true. */ 216 port = ntohs((uint16_t) service->s_port); 217 } else { 218 char *end; 219 port = strtol(word, &end, 10); 220 if (*end != '\0') { 221 zc_error_prev_line("unknown service '%s' for protocol '%s'", 222 word, protostr); 223 continue; 224 } 225 } 226 227 if (port < 0 || port > 65535) { 228 zc_error_prev_line("bad port number %d", port); 229 } else { 230 set_bit(bitmap, port); 231 if (port > max_port) 232 max_port = port; 233 } 234 } 235 236 r = alloc_rdata(region, sizeof(uint8_t) + max_port / 8 + 1); 237 p = (uint8_t *) (r + 1); 238 *p = proto->p_proto; 239 memcpy(p + 1, bitmap, *r-1); 240 241 return r; 242 } 243 244 uint16_t * 245 zparser_conv_serial(region_type *region, const char *serialstr) 246 { 247 uint16_t *r = NULL; 248 uint32_t serial; 249 const char *t; 250 251 serial = strtoserial(serialstr, &t); 252 if (*t != '\0') { 253 zc_error_prev_line("serial is expected"); 254 } else { 255 serial = htonl(serial); 256 r = alloc_rdata_init(region, &serial, sizeof(serial)); 257 } 258 return r; 259 } 260 261 uint16_t * 262 zparser_conv_period(region_type *region, const char *periodstr) 263 { 264 /* convert a time period (think TTL's) to wireformat) */ 265 uint16_t *r = NULL; 266 uint32_t period; 267 const char *end; 268 269 /* Allocate required space... */ 270 period = strtottl(periodstr, &end); 271 if (*end != '\0') { 272 zc_error_prev_line("time period is expected"); 273 } else { 274 period = htonl(period); 275 r = alloc_rdata_init(region, &period, sizeof(period)); 276 } 277 return r; 278 } 279 280 uint16_t * 281 zparser_conv_short(region_type *region, const char *text) 282 { 283 uint16_t *r = NULL; 284 uint16_t value; 285 char *end; 286 287 value = htons((uint16_t) strtol(text, &end, 10)); 288 if (*end != '\0') { 289 zc_error_prev_line("integer value is expected"); 290 } else { 291 r = alloc_rdata_init(region, &value, sizeof(value)); 292 } 293 return r; 294 } 295 296 uint16_t * 297 zparser_conv_byte(region_type *region, const char *text) 298 { 299 uint16_t *r = NULL; 300 uint8_t value; 301 char *end; 302 303 value = (uint8_t) strtol(text, &end, 10); 304 if (*end != '\0') { 305 zc_error_prev_line("integer value is expected"); 306 } else { 307 r = alloc_rdata_init(region, &value, sizeof(value)); 308 } 309 return r; 310 } 311 312 uint16_t * 313 zparser_conv_algorithm(region_type *region, const char *text) 314 { 315 const lookup_table_type *alg; 316 uint8_t id; 317 318 alg = lookup_by_name(dns_algorithms, text); 319 if (alg) { 320 id = (uint8_t) alg->id; 321 } else { 322 char *end; 323 id = (uint8_t) strtol(text, &end, 10); 324 if (*end != '\0') { 325 zc_error_prev_line("algorithm is expected"); 326 return NULL; 327 } 328 } 329 330 return alloc_rdata_init(region, &id, sizeof(id)); 331 } 332 333 uint16_t * 334 zparser_conv_certificate_type(region_type *region, const char *text) 335 { 336 /* convert an algorithm string to integer */ 337 const lookup_table_type *type; 338 uint16_t id; 339 340 type = lookup_by_name(dns_certificate_types, text); 341 if (type) { 342 id = htons((uint16_t) type->id); 343 } else { 344 char *end; 345 id = htons((uint16_t) strtol(text, &end, 10)); 346 if (*end != '\0') { 347 zc_error_prev_line("certificate type is expected"); 348 return NULL; 349 } 350 } 351 352 return alloc_rdata_init(region, &id, sizeof(id)); 353 } 354 355 uint16_t * 356 zparser_conv_a(region_type *region, const char *text) 357 { 358 in_addr_t address; 359 uint16_t *r = NULL; 360 361 if (inet_pton(AF_INET, text, &address) != 1) { 362 zc_error_prev_line("invalid IPv4 address '%s'", text); 363 } else { 364 r = alloc_rdata_init(region, &address, sizeof(address)); 365 } 366 return r; 367 } 368 369 uint16_t * 370 zparser_conv_aaaa(region_type *region, const char *text) 371 { 372 uint8_t address[IP6ADDRLEN]; 373 uint16_t *r = NULL; 374 375 if (inet_pton(AF_INET6, text, address) != 1) { 376 zc_error_prev_line("invalid IPv6 address '%s'", text); 377 } else { 378 r = alloc_rdata_init(region, address, sizeof(address)); 379 } 380 return r; 381 } 382 383 384 uint16_t * 385 zparser_conv_ilnp64(region_type *region, const char *text) 386 { 387 uint16_t *r = NULL; 388 int ngroups, num; 389 unsigned long hex; 390 const char *ch; 391 char digits[ILNP_MAXDIGITS+1]; 392 unsigned int ui[ILNP_NUMGROUPS]; 393 uint16_t a[ILNP_NUMGROUPS]; 394 395 ngroups = 1; /* Always at least one group */ 396 num = 0; 397 for (ch = text; *ch != '\0'; ch++) { 398 if (*ch == ':') { 399 if (num <= 0) { 400 zc_error_prev_line("ilnp64: empty group of " 401 "digits is not allowed"); 402 return NULL; 403 } 404 digits[num] = '\0'; 405 hex = (unsigned long) strtol(digits, NULL, 16); 406 num = 0; 407 ui[ngroups - 1] = hex; 408 if (ngroups >= ILNP_NUMGROUPS) { 409 zc_error_prev_line("ilnp64: more than %d groups " 410 "of digits", ILNP_NUMGROUPS); 411 return NULL; 412 } 413 ngroups++; 414 } else { 415 /* Our grammar is stricter than the one accepted by 416 * strtol. */ 417 if (!isxdigit((unsigned char)*ch)) { 418 zc_error_prev_line("ilnp64: invalid " 419 "(non-hexadecimal) character %c", *ch); 420 return NULL; 421 } 422 if (num >= ILNP_MAXDIGITS) { 423 zc_error_prev_line("ilnp64: more than %d digits " 424 "in a group", ILNP_MAXDIGITS); 425 return NULL; 426 } 427 digits[num++] = *ch; 428 } 429 } 430 if (num <= 0) { 431 zc_error_prev_line("ilnp64: empty group of digits is not " 432 "allowed"); 433 return NULL; 434 } 435 digits[num] = '\0'; 436 hex = (unsigned long) strtol(digits, NULL, 16); 437 ui[ngroups - 1] = hex; 438 if (ngroups < 4) { 439 zc_error_prev_line("ilnp64: less than %d groups of digits", 440 ILNP_NUMGROUPS); 441 return NULL; 442 } 443 444 a[0] = htons(ui[0]); 445 a[1] = htons(ui[1]); 446 a[2] = htons(ui[2]); 447 a[3] = htons(ui[3]); 448 r = alloc_rdata_init(region, a, sizeof(a)); 449 return r; 450 } 451 452 static uint16_t * 453 zparser_conv_eui48(region_type *region, const char *text) 454 { 455 uint8_t nums[6]; 456 uint16_t *r = NULL; 457 unsigned int a, b, c, d, e, f; 458 int l; 459 460 if (sscanf(text, "%2x-%2x-%2x-%2x-%2x-%2x%n", 461 &a, &b, &c, &d, &e, &f, &l) != 6 || 462 l != (int)strlen(text)){ 463 zc_error_prev_line("eui48: invalid rr"); 464 return NULL; 465 } 466 nums[0] = (uint8_t)a; 467 nums[1] = (uint8_t)b; 468 nums[2] = (uint8_t)c; 469 nums[3] = (uint8_t)d; 470 nums[4] = (uint8_t)e; 471 nums[5] = (uint8_t)f; 472 r = alloc_rdata_init(region, nums, sizeof(nums)); 473 return r; 474 } 475 476 static uint16_t * 477 zparser_conv_eui64(region_type *region, const char *text) 478 { 479 uint8_t nums[8]; 480 uint16_t *r = NULL; 481 unsigned int a, b, c, d, e, f, g, h; 482 int l; 483 if (sscanf(text, "%2x-%2x-%2x-%2x-%2x-%2x-%2x-%2x%n", 484 &a, &b, &c, &d, &e, &f, &g, &h, &l) != 8 || 485 l != (int)strlen(text)) { 486 zc_error_prev_line("eui64: invalid rr"); 487 return NULL; 488 } 489 nums[0] = (uint8_t)a; 490 nums[1] = (uint8_t)b; 491 nums[2] = (uint8_t)c; 492 nums[3] = (uint8_t)d; 493 nums[4] = (uint8_t)e; 494 nums[5] = (uint8_t)f; 495 nums[6] = (uint8_t)g; 496 nums[7] = (uint8_t)h; 497 r = alloc_rdata_init(region, nums, sizeof(nums)); 498 return r; 499 } 500 501 uint16_t * 502 zparser_conv_eui(region_type *region, const char *text, size_t len) 503 { 504 uint16_t *r = NULL; 505 int nnum, num; 506 const char* ch; 507 508 nnum = len/8; 509 num = 1; 510 for (ch = text; *ch != '\0'; ch++) { 511 if (*ch == '-') { 512 num++; 513 } else if (!isxdigit((unsigned char)*ch)) { 514 zc_error_prev_line("eui%u: invalid (non-hexadecimal) " 515 "character %c", (unsigned) len, *ch); 516 return NULL; 517 } 518 } 519 if (num != nnum) { 520 zc_error_prev_line("eui%u: wrong number of hex numbers", 521 (unsigned) len); 522 return NULL; 523 } 524 525 switch (len) { 526 case 48: 527 r = zparser_conv_eui48(region, text); 528 break; 529 case 64: 530 r = zparser_conv_eui64(region, text); 531 break; 532 default: 533 zc_error_prev_line("eui%u: invalid length", 534 (unsigned) len); 535 return NULL; 536 break; 537 } 538 return r; 539 } 540 541 uint16_t * 542 zparser_conv_text(region_type *region, const char *text, size_t len) 543 { 544 uint16_t *r = NULL; 545 uint8_t *p; 546 547 if (len > 255) { 548 zc_error_prev_line("text string is longer than 255 characters," 549 " try splitting it into multiple parts"); 550 len = 255; 551 } 552 r = alloc_rdata(region, len + 1); 553 p = (uint8_t *) (r + 1); 554 *p = len; 555 memcpy(p + 1, text, len); 556 return r; 557 } 558 559 /* for CAA Value [RFC 6844] */ 560 uint16_t * 561 zparser_conv_long_text(region_type *region, const char *text, size_t len) 562 { 563 uint16_t *r = NULL; 564 if (len > MAX_RDLENGTH) { 565 zc_error_prev_line("text string is longer than max rdlen"); 566 return NULL; 567 } 568 r = alloc_rdata_init(region, text, len); 569 return r; 570 } 571 572 /* for CAA Tag [RFC 6844] */ 573 uint16_t * 574 zparser_conv_tag(region_type *region, const char *text, size_t len) 575 { 576 uint16_t *r = NULL; 577 uint8_t *p; 578 const char* ptr; 579 580 if (len < 1) { 581 zc_error_prev_line("invalid tag: zero length"); 582 return NULL; 583 } 584 if (len > 15) { 585 zc_error_prev_line("invalid tag %s: longer than 15 characters (%u)", 586 text, (unsigned) len); 587 return NULL; 588 } 589 for (ptr = text; *ptr; ptr++) { 590 if (!isdigit((unsigned char)*ptr) && !islower((unsigned char)*ptr)) { 591 zc_error_prev_line("invalid tag %s: contains invalid char %c", 592 text, *ptr); 593 return NULL; 594 } 595 } 596 r = alloc_rdata(region, len + 1); 597 p = (uint8_t *) (r + 1); 598 *p = len; 599 memmove(p + 1, text, len); 600 return r; 601 } 602 603 uint16_t * 604 zparser_conv_dns_name(region_type *region, const uint8_t* name, size_t len) 605 { 606 uint16_t* r = NULL; 607 uint8_t* p = NULL; 608 r = alloc_rdata(region, len); 609 p = (uint8_t *) (r + 1); 610 memcpy(p, name, len); 611 612 return r; 613 } 614 615 uint16_t * 616 zparser_conv_b32(region_type *region, const char *b32) 617 { 618 uint8_t buffer[B64BUFSIZE]; 619 uint16_t *r = NULL; 620 int i; 621 622 if(strcmp(b32, "-") == 0) { 623 return alloc_rdata_init(region, "", 1); 624 } 625 i = b32_pton(b32, buffer+1, B64BUFSIZE-1); 626 if (i == -1 || i > 255) { 627 zc_error_prev_line("invalid base32 data"); 628 } else { 629 buffer[0] = i; /* store length byte */ 630 r = alloc_rdata_init(region, buffer, i+1); 631 } 632 return r; 633 } 634 635 uint16_t * 636 zparser_conv_b64(region_type *region, const char *b64) 637 { 638 uint8_t buffer[B64BUFSIZE]; 639 uint16_t *r = NULL; 640 int i; 641 642 i = __b64_pton(b64, buffer, B64BUFSIZE); 643 if (i == -1) { 644 zc_error_prev_line("invalid base64 data"); 645 } else { 646 r = alloc_rdata_init(region, buffer, i); 647 } 648 return r; 649 } 650 651 uint16_t * 652 zparser_conv_rrtype(region_type *region, const char *text) 653 { 654 uint16_t *r = NULL; 655 uint16_t type = rrtype_from_string(text); 656 657 if (type == 0) { 658 zc_error_prev_line("unrecognized RR type '%s'", text); 659 } else { 660 type = htons(type); 661 r = alloc_rdata_init(region, &type, sizeof(type)); 662 } 663 return r; 664 } 665 666 uint16_t * 667 zparser_conv_nxt(region_type *region, uint8_t nxtbits[]) 668 { 669 /* nxtbits[] consists of 16 bytes with some zero's in it 670 * copy every byte with zero to r and write the length in 671 * the first byte 672 */ 673 uint16_t i; 674 uint16_t last = 0; 675 676 for (i = 0; i < 16; i++) { 677 if (nxtbits[i] != 0) 678 last = i + 1; 679 } 680 681 return alloc_rdata_init(region, nxtbits, last); 682 } 683 684 685 /* we potentially have 256 windows, each one is numbered. empty ones 686 * should be discarded 687 */ 688 uint16_t * 689 zparser_conv_nsec(region_type *region, 690 uint8_t nsecbits[NSEC_WINDOW_COUNT][NSEC_WINDOW_BITS_SIZE]) 691 { 692 /* nsecbits contains up to 64K of bits which represent the 693 * types available for a name. Walk the bits according to 694 * nsec++ draft from jakob 695 */ 696 uint16_t *r; 697 uint8_t *ptr; 698 size_t i,j; 699 uint16_t window_count = 0; 700 uint16_t total_size = 0; 701 uint16_t window_max = 0; 702 703 /* The used windows. */ 704 int used[NSEC_WINDOW_COUNT]; 705 /* The last byte used in each the window. */ 706 int size[NSEC_WINDOW_COUNT]; 707 708 window_max = 1 + (nsec_highest_rcode / 256); 709 710 /* used[i] is the i-th window included in the nsec 711 * size[used[0]] is the size of window 0 712 */ 713 714 /* walk through the 256 windows */ 715 for (i = 0; i < window_max; ++i) { 716 int empty_window = 1; 717 /* check each of the 32 bytes */ 718 for (j = 0; j < NSEC_WINDOW_BITS_SIZE; ++j) { 719 if (nsecbits[i][j] != 0) { 720 size[i] = j + 1; 721 empty_window = 0; 722 } 723 } 724 if (!empty_window) { 725 used[window_count] = i; 726 window_count++; 727 } 728 } 729 730 for (i = 0; i < window_count; ++i) { 731 total_size += sizeof(uint16_t) + size[used[i]]; 732 } 733 734 r = alloc_rdata(region, total_size); 735 ptr = (uint8_t *) (r + 1); 736 737 /* now walk used and copy it */ 738 for (i = 0; i < window_count; ++i) { 739 ptr[0] = used[i]; 740 ptr[1] = size[used[i]]; 741 memcpy(ptr + 2, &nsecbits[used[i]], size[used[i]]); 742 ptr += size[used[i]] + 2; 743 } 744 745 return r; 746 } 747 748 /* Parse an int terminated in the specified range. */ 749 static int 750 parse_int(const char *str, 751 char **end, 752 int *result, 753 const char *name, 754 int min, 755 int max) 756 { 757 *result = (int) strtol(str, end, 10); 758 if (*result < min || *result > max) { 759 zc_error_prev_line("%s must be within the range [%d .. %d]", 760 name, 761 min, 762 max); 763 return 0; 764 } else { 765 return 1; 766 } 767 } 768 769 /* RFC1876 conversion routines */ 770 static unsigned int poweroften[10] = {1, 10, 100, 1000, 10000, 100000, 771 1000000,10000000,100000000,1000000000}; 772 773 /* 774 * Converts ascii size/precision X * 10**Y(cm) to 0xXY. 775 * Sets the given pointer to the last used character. 776 * 777 */ 778 static uint8_t 779 precsize_aton (char *cp, char **endptr) 780 { 781 unsigned int mval = 0, cmval = 0; 782 uint8_t retval = 0; 783 int exponent; 784 int mantissa; 785 786 while (isdigit((unsigned char)*cp)) 787 mval = mval * 10 + hexdigit_to_int(*cp++); 788 789 if (*cp == '.') { /* centimeters */ 790 cp++; 791 if (isdigit((unsigned char)*cp)) { 792 cmval = hexdigit_to_int(*cp++) * 10; 793 if (isdigit((unsigned char)*cp)) { 794 cmval += hexdigit_to_int(*cp++); 795 } 796 } 797 } 798 799 if(mval >= poweroften[7]) { 800 /* integer overflow possible for *100 */ 801 mantissa = mval / poweroften[7]; 802 exponent = 9; /* max */ 803 } 804 else { 805 cmval = (mval * 100) + cmval; 806 807 for (exponent = 0; exponent < 9; exponent++) 808 if (cmval < poweroften[exponent+1]) 809 break; 810 811 mantissa = cmval / poweroften[exponent]; 812 } 813 if (mantissa > 9) 814 mantissa = 9; 815 816 retval = (mantissa << 4) | exponent; 817 818 if (*cp == 'm') cp++; 819 820 *endptr = cp; 821 822 return (retval); 823 } 824 825 /* 826 * Parses a specific part of rdata. 827 * 828 * Returns: 829 * 830 * number of elements parsed 831 * zero on error 832 * 833 */ 834 uint16_t * 835 zparser_conv_loc(region_type *region, char *str) 836 { 837 uint16_t *r; 838 uint32_t *p; 839 int i; 840 int deg, min, secs; /* Secs is stored times 1000. */ 841 uint32_t lat = 0, lon = 0, alt = 0; 842 /* encoded defaults: version=0 sz=1m hp=10000m vp=10m */ 843 uint8_t vszhpvp[4] = {0, 0x12, 0x16, 0x13}; 844 char *start; 845 double d; 846 847 for(;;) { 848 deg = min = secs = 0; 849 850 /* Degrees */ 851 if (*str == '\0') { 852 zc_error_prev_line("unexpected end of LOC data"); 853 return NULL; 854 } 855 856 if (!parse_int(str, &str, °, "degrees", 0, 180)) 857 return NULL; 858 if (!isspace((unsigned char)*str)) { 859 zc_error_prev_line("space expected after degrees"); 860 return NULL; 861 } 862 ++str; 863 864 /* Minutes? */ 865 if (isdigit((unsigned char)*str)) { 866 if (!parse_int(str, &str, &min, "minutes", 0, 60)) 867 return NULL; 868 if (!isspace((unsigned char)*str)) { 869 zc_error_prev_line("space expected after minutes"); 870 return NULL; 871 } 872 ++str; 873 } 874 875 /* Seconds? */ 876 if (isdigit((unsigned char)*str)) { 877 start = str; 878 if (!parse_int(str, &str, &i, "seconds", 0, 60)) { 879 return NULL; 880 } 881 882 if (*str == '.' && !parse_int(str + 1, &str, &i, "seconds fraction", 0, 999)) { 883 return NULL; 884 } 885 886 if (!isspace((unsigned char)*str)) { 887 zc_error_prev_line("space expected after seconds"); 888 return NULL; 889 } 890 /* No need for precision specifiers, it's a double */ 891 if (sscanf(start, "%lf", &d) != 1) { 892 zc_error_prev_line("error parsing seconds"); 893 } 894 895 if (d < 0.0 || d > 60.0) { 896 zc_error_prev_line("seconds not in range 0.0 .. 60.0"); 897 } 898 899 secs = (int) (d * 1000.0 + 0.5); 900 ++str; 901 } 902 903 switch(*str) { 904 case 'N': 905 case 'n': 906 lat = ((uint32_t)1<<31) + (deg * 3600000 + min * 60000 + secs); 907 break; 908 case 'E': 909 case 'e': 910 lon = ((uint32_t)1<<31) + (deg * 3600000 + min * 60000 + secs); 911 break; 912 case 'S': 913 case 's': 914 lat = ((uint32_t)1<<31) - (deg * 3600000 + min * 60000 + secs); 915 break; 916 case 'W': 917 case 'w': 918 lon = ((uint32_t)1<<31) - (deg * 3600000 + min * 60000 + secs); 919 break; 920 default: 921 zc_error_prev_line("invalid latitude/longtitude: '%c'", *str); 922 return NULL; 923 } 924 ++str; 925 926 if (lat != 0 && lon != 0) 927 break; 928 929 if (!isspace((unsigned char)*str)) { 930 zc_error_prev_line("space expected after latitude/longitude"); 931 return NULL; 932 } 933 ++str; 934 } 935 936 /* Altitude */ 937 if (*str == '\0') { 938 zc_error_prev_line("unexpected end of LOC data"); 939 return NULL; 940 } 941 942 if (!isspace((unsigned char)*str)) { 943 zc_error_prev_line("space expected before altitude"); 944 return NULL; 945 } 946 ++str; 947 948 start = str; 949 950 /* Sign */ 951 if (*str == '+' || *str == '-') { 952 ++str; 953 } 954 955 /* Meters of altitude... */ 956 if(strtol(str, &str, 10) == LONG_MAX) { 957 zc_error_prev_line("altitude too large, number overflow"); 958 return NULL; 959 } 960 switch(*str) { 961 case ' ': 962 case '\0': 963 case 'm': 964 break; 965 case '.': 966 if (!parse_int(str + 1, &str, &i, "altitude fraction", 0, 99)) { 967 return NULL; 968 } 969 if (!isspace((unsigned char)*str) && *str != '\0' && *str != 'm') { 970 zc_error_prev_line("altitude fraction must be a number"); 971 return NULL; 972 } 973 break; 974 default: 975 zc_error_prev_line("altitude must be expressed in meters"); 976 return NULL; 977 } 978 if (!isspace((unsigned char)*str) && *str != '\0') 979 ++str; 980 981 if (sscanf(start, "%lf", &d) != 1) { 982 zc_error_prev_line("error parsing altitude"); 983 } 984 985 alt = (uint32_t) (10000000.0 + d * 100 + 0.5); 986 987 if (!isspace((unsigned char)*str) && *str != '\0') { 988 zc_error_prev_line("unexpected character after altitude"); 989 return NULL; 990 } 991 992 /* Now parse size, horizontal precision and vertical precision if any */ 993 for(i = 1; isspace((unsigned char)*str) && i <= 3; i++) { 994 vszhpvp[i] = precsize_aton(str + 1, &str); 995 996 if (!isspace((unsigned char)*str) && *str != '\0') { 997 zc_error_prev_line("invalid size or precision"); 998 return NULL; 999 } 1000 } 1001 1002 /* Allocate required space... */ 1003 r = alloc_rdata(region, 16); 1004 p = (uint32_t *) (r + 1); 1005 1006 memmove(p, vszhpvp, 4); 1007 write_uint32(p + 1, lat); 1008 write_uint32(p + 2, lon); 1009 write_uint32(p + 3, alt); 1010 1011 return r; 1012 } 1013 1014 /* 1015 * Convert an APL RR RDATA element. 1016 */ 1017 uint16_t * 1018 zparser_conv_apl_rdata(region_type *region, char *str) 1019 { 1020 int negated = 0; 1021 uint16_t address_family; 1022 uint8_t prefix; 1023 uint8_t maximum_prefix; 1024 uint8_t length; 1025 uint8_t address[IP6ADDRLEN]; 1026 char *colon = strchr(str, ':'); 1027 char *slash = strchr(str, '/'); 1028 int af; 1029 int rc; 1030 uint16_t rdlength; 1031 uint16_t *r; 1032 uint8_t *t; 1033 char *end; 1034 long p; 1035 1036 if (!colon) { 1037 zc_error("address family separator is missing"); 1038 return NULL; 1039 } 1040 if (!slash) { 1041 zc_error("prefix separator is missing"); 1042 return NULL; 1043 } 1044 1045 *colon = '\0'; 1046 *slash = '\0'; 1047 1048 if (*str == '!') { 1049 negated = 1; 1050 ++str; 1051 } 1052 1053 if (strcmp(str, "1") == 0) { 1054 address_family = htons(1); 1055 af = AF_INET; 1056 length = sizeof(in_addr_t); 1057 maximum_prefix = length * 8; 1058 } else if (strcmp(str, "2") == 0) { 1059 address_family = htons(2); 1060 af = AF_INET6; 1061 length = IP6ADDRLEN; 1062 maximum_prefix = length * 8; 1063 } else { 1064 zc_error("invalid address family '%s'", str); 1065 return NULL; 1066 } 1067 1068 rc = inet_pton(af, colon + 1, address); 1069 if (rc == 0) { 1070 zc_error("invalid address '%s'", colon + 1); 1071 return NULL; 1072 } else if (rc == -1) { 1073 zc_error("inet_pton failed: %s", strerror(errno)); 1074 return NULL; 1075 } 1076 1077 /* Strip trailing zero octets. */ 1078 while (length > 0 && address[length - 1] == 0) 1079 --length; 1080 1081 1082 p = strtol(slash + 1, &end, 10); 1083 if (p < 0 || p > maximum_prefix) { 1084 zc_error("prefix not in the range 0 .. %d", maximum_prefix); 1085 return NULL; 1086 } else if (*end != '\0') { 1087 zc_error("invalid prefix '%s'", slash + 1); 1088 return NULL; 1089 } 1090 prefix = (uint8_t) p; 1091 1092 rdlength = (sizeof(address_family) + sizeof(prefix) + sizeof(length) 1093 + length); 1094 r = alloc_rdata(region, rdlength); 1095 t = (uint8_t *) (r + 1); 1096 1097 memcpy(t, &address_family, sizeof(address_family)); 1098 t += sizeof(address_family); 1099 memcpy(t, &prefix, sizeof(prefix)); 1100 t += sizeof(prefix); 1101 memcpy(t, &length, sizeof(length)); 1102 if (negated) { 1103 *t |= APL_NEGATION_MASK; 1104 } 1105 t += sizeof(length); 1106 memcpy(t, address, length); 1107 1108 return r; 1109 } 1110 1111 /* 1112 * Below some function that also convert but not to wireformat 1113 * but to "normal" (int,long,char) types 1114 */ 1115 1116 uint32_t 1117 zparser_ttl2int(const char *ttlstr, int* error) 1118 { 1119 /* convert a ttl value to a integer 1120 * return the ttl in a int 1121 * -1 on error 1122 */ 1123 1124 uint32_t ttl; 1125 const char *t; 1126 1127 ttl = strtottl(ttlstr, &t); 1128 if (*t != 0) { 1129 zc_error_prev_line("invalid TTL value: %s",ttlstr); 1130 *error = 1; 1131 } 1132 1133 return ttl; 1134 } 1135 1136 1137 void 1138 zadd_rdata_wireformat(uint16_t *data) 1139 { 1140 if (parser->current_rr.rdata_count >= MAXRDATALEN) { 1141 zc_error_prev_line("too many rdata elements"); 1142 } else { 1143 parser->current_rr.rdatas[parser->current_rr.rdata_count].data 1144 = data; 1145 ++parser->current_rr.rdata_count; 1146 } 1147 } 1148 1149 /** 1150 * Used for TXT RR's to grow with undefined number of strings. 1151 */ 1152 void 1153 zadd_rdata_txt_wireformat(uint16_t *data, int first) 1154 { 1155 rdata_atom_type *rd; 1156 if (parser->current_rr.rdata_count >= MAXRDATALEN) { 1157 zc_error_prev_line("too many rdata txt elements"); 1158 return; 1159 } 1160 1161 /* First STR in str_seq, allocate 65K in first unused rdata 1162 * else find last used rdata */ 1163 if (first) { 1164 rd = &parser->current_rr.rdatas[parser->current_rr.rdata_count]; 1165 if ((rd->data = (uint16_t *) region_alloc(parser->rr_region, 1166 sizeof(uint16_t) + 65535 * sizeof(uint8_t))) == NULL) { 1167 zc_error_prev_line("Could not allocate memory for TXT RR"); 1168 return; 1169 } 1170 parser->current_rr.rdata_count++; 1171 rd->data[0] = 0; 1172 } 1173 else 1174 rd = &parser->current_rr.rdatas[parser->current_rr.rdata_count-1]; 1175 1176 if ((size_t)rd->data[0] + (size_t)data[0] > 65535) { 1177 zc_error_prev_line("too large rdata element"); 1178 return; 1179 } 1180 1181 memcpy((uint8_t *)rd->data + 2 + rd->data[0], data + 1, data[0]); 1182 rd->data[0] += data[0]; 1183 } 1184 1185 /** 1186 * Clean up after last call of zadd_rdata_txt_wireformat 1187 */ 1188 void 1189 zadd_rdata_txt_clean_wireformat() 1190 { 1191 uint16_t *tmp_data; 1192 rdata_atom_type *rd = &parser->current_rr.rdatas[parser->current_rr.rdata_count-1]; 1193 if(!rd || !rd->data) 1194 return; /* previous syntax failure */ 1195 if ((tmp_data = (uint16_t *) region_alloc(parser->region, 1196 ((size_t)rd->data[0]) + ((size_t)2))) != NULL) { 1197 memcpy(tmp_data, rd->data, rd->data[0] + 2); 1198 /* rd->data of u16+65535 freed when rr_region is freed */ 1199 rd->data = tmp_data; 1200 } 1201 else { 1202 /* We could not get memory in non-volatile region */ 1203 zc_error_prev_line("could not allocate memory for rdata"); 1204 return; 1205 } 1206 } 1207 1208 void 1209 zadd_rdata_domain(domain_type *domain) 1210 { 1211 if (parser->current_rr.rdata_count >= MAXRDATALEN) { 1212 zc_error_prev_line("too many rdata elements"); 1213 } else { 1214 parser->current_rr.rdatas[parser->current_rr.rdata_count].domain 1215 = domain; 1216 domain->usage ++; /* new reference to domain */ 1217 ++parser->current_rr.rdata_count; 1218 } 1219 } 1220 1221 void 1222 parse_unknown_rdata(uint16_t type, uint16_t *wireformat) 1223 { 1224 buffer_type packet; 1225 uint16_t size; 1226 ssize_t rdata_count; 1227 ssize_t i; 1228 rdata_atom_type *rdatas; 1229 1230 if (wireformat) { 1231 size = *wireformat; 1232 } else { 1233 return; 1234 } 1235 1236 buffer_create_from(&packet, wireformat + 1, *wireformat); 1237 rdata_count = rdata_wireformat_to_rdata_atoms(parser->region, 1238 parser->db->domains, 1239 type, 1240 size, 1241 &packet, 1242 &rdatas); 1243 if (rdata_count == -1) { 1244 zc_error_prev_line("bad unknown RDATA"); 1245 return; 1246 } 1247 1248 for (i = 0; i < rdata_count; ++i) { 1249 if (rdata_atom_is_domain(type, i)) { 1250 zadd_rdata_domain(rdatas[i].domain); 1251 } else { 1252 zadd_rdata_wireformat(rdatas[i].data); 1253 } 1254 } 1255 } 1256 1257 1258 /* 1259 * Compares two rdata arrays. 1260 * 1261 * Returns: 1262 * 1263 * zero if they are equal 1264 * non-zero if not 1265 * 1266 */ 1267 static int 1268 zrdatacmp(uint16_t type, rr_type *a, rr_type *b) 1269 { 1270 int i = 0; 1271 1272 assert(a); 1273 assert(b); 1274 1275 /* One is shorter than another */ 1276 if (a->rdata_count != b->rdata_count) 1277 return 1; 1278 1279 /* Compare element by element */ 1280 for (i = 0; i < a->rdata_count; ++i) { 1281 if (rdata_atom_is_domain(type, i)) { 1282 if (rdata_atom_domain(a->rdatas[i]) 1283 != rdata_atom_domain(b->rdatas[i])) 1284 { 1285 return 1; 1286 } 1287 } else if(rdata_atom_is_literal_domain(type, i)) { 1288 if (rdata_atom_size(a->rdatas[i]) 1289 != rdata_atom_size(b->rdatas[i])) 1290 return 1; 1291 if (!dname_equal_nocase(rdata_atom_data(a->rdatas[i]), 1292 rdata_atom_data(b->rdatas[i]), 1293 rdata_atom_size(a->rdatas[i]))) 1294 return 1; 1295 } else { 1296 if (rdata_atom_size(a->rdatas[i]) 1297 != rdata_atom_size(b->rdatas[i])) 1298 { 1299 return 1; 1300 } 1301 if (memcmp(rdata_atom_data(a->rdatas[i]), 1302 rdata_atom_data(b->rdatas[i]), 1303 rdata_atom_size(a->rdatas[i])) != 0) 1304 { 1305 return 1; 1306 } 1307 } 1308 } 1309 1310 /* Otherwise they are equal */ 1311 return 0; 1312 } 1313 1314 /* 1315 * 1316 * Opens a zone file. 1317 * 1318 * Returns: 1319 * 1320 * - pointer to the parser structure 1321 * - NULL on error and errno set 1322 * 1323 */ 1324 static int 1325 zone_open(const char *filename, uint32_t ttl, uint16_t klass, 1326 const dname_type *origin) 1327 { 1328 /* Open the zone file... */ 1329 if (strcmp(filename, "-") == 0) { 1330 yyin = stdin; 1331 filename = "<stdin>"; 1332 } else if (!(yyin = fopen(filename, "r"))) { 1333 return 0; 1334 } 1335 1336 zparser_init(filename, ttl, klass, origin); 1337 1338 return 1; 1339 } 1340 1341 1342 void 1343 set_bitnsec(uint8_t bits[NSEC_WINDOW_COUNT][NSEC_WINDOW_BITS_SIZE], 1344 uint16_t index) 1345 { 1346 /* 1347 * The bits are counted from left to right, so bit #0 is the 1348 * left most bit. 1349 */ 1350 uint8_t window = index / 256; 1351 uint8_t bit = index % 256; 1352 1353 bits[window][bit / 8] |= (1 << (7 - bit % 8)); 1354 } 1355 1356 1357 static int 1358 has_soa(domain_type* domain) 1359 { 1360 rrset_type* p = NULL; 1361 if(!domain) return 0; 1362 for(p = domain->rrsets; p; p = p->next) 1363 if(rrset_rrtype(p) == TYPE_SOA) 1364 return 1; 1365 return 0; 1366 } 1367 1368 int 1369 process_rr(void) 1370 { 1371 zone_type *zone = parser->current_zone; 1372 rr_type *rr = &parser->current_rr; 1373 rrset_type *rrset; 1374 size_t max_rdlength; 1375 int i; 1376 rrtype_descriptor_type *descriptor 1377 = rrtype_descriptor_by_type(rr->type); 1378 1379 /* We only support IN class */ 1380 if (rr->klass != CLASS_IN) { 1381 if(zone_is_slave(zone->opts)) 1382 zc_warning_prev_line("only class IN is supported"); 1383 else 1384 zc_error_prev_line("only class IN is supported"); 1385 return 0; 1386 } 1387 1388 /* Make sure the maximum RDLENGTH does not exceed 65535 bytes. */ 1389 max_rdlength = rdata_maximum_wireformat_size( 1390 descriptor, rr->rdata_count, rr->rdatas); 1391 1392 if (max_rdlength > MAX_RDLENGTH) { 1393 zc_error_prev_line("maximum rdata length exceeds %d octets", MAX_RDLENGTH); 1394 return 0; 1395 } 1396 /* we have the zone already */ 1397 assert(zone); 1398 if (rr->type == TYPE_SOA) { 1399 if (rr->owner != zone->apex) { 1400 zc_error_prev_line( 1401 "SOA record with invalid domain name"); 1402 return 0; 1403 } 1404 if(has_soa(rr->owner)) { 1405 if(zone_is_slave(zone->opts)) 1406 zc_warning_prev_line("this SOA record was already encountered"); 1407 else 1408 zc_error_prev_line("this SOA record was already encountered"); 1409 return 0; 1410 } 1411 rr->owner->is_apex = 1; 1412 } 1413 1414 if (!domain_is_subdomain(rr->owner, zone->apex)) 1415 { 1416 if(zone_is_slave(zone->opts)) 1417 zc_warning_prev_line("out of zone data"); 1418 else 1419 zc_error_prev_line("out of zone data"); 1420 return 0; 1421 } 1422 1423 /* Do we have this type of rrset already? */ 1424 rrset = domain_find_rrset(rr->owner, zone, rr->type); 1425 if (!rrset) { 1426 rrset = (rrset_type *) region_alloc(parser->region, 1427 sizeof(rrset_type)); 1428 rrset->zone = zone; 1429 rrset->rr_count = 1; 1430 rrset->rrs = (rr_type *) region_alloc(parser->region, 1431 sizeof(rr_type)); 1432 rrset->rrs[0] = *rr; 1433 1434 /* Add it */ 1435 domain_add_rrset(rr->owner, rrset); 1436 } else { 1437 rr_type* o; 1438 if (rr->type != TYPE_RRSIG && rrset->rrs[0].ttl != rr->ttl) { 1439 zc_warning_prev_line( 1440 "%s TTL %u does not match the TTL %u of the %s RRset", 1441 domain_to_string(rr->owner), (unsigned)rr->ttl, 1442 (unsigned)rrset->rrs[0].ttl, 1443 rrtype_to_string(rr->type)); 1444 } 1445 1446 /* Search for possible duplicates... */ 1447 for (i = 0; i < rrset->rr_count; i++) { 1448 if (!zrdatacmp(rr->type, rr, &rrset->rrs[i])) { 1449 break; 1450 } 1451 } 1452 1453 /* Discard the duplicates... */ 1454 if (i < rrset->rr_count) { 1455 return 0; 1456 } 1457 if(rrset->rr_count == 65535) { 1458 zc_error_prev_line("too many RRs for domain RRset"); 1459 return 0; 1460 } 1461 1462 /* Add it... */ 1463 o = rrset->rrs; 1464 rrset->rrs = (rr_type *) region_alloc_array(parser->region, 1465 (rrset->rr_count + 1), sizeof(rr_type)); 1466 memcpy(rrset->rrs, o, (rrset->rr_count) * sizeof(rr_type)); 1467 region_recycle(parser->region, o, 1468 (rrset->rr_count) * sizeof(rr_type)); 1469 rrset->rrs[rrset->rr_count] = *rr; 1470 ++rrset->rr_count; 1471 } 1472 1473 if(rr->type == TYPE_DNAME && rrset->rr_count > 1) { 1474 if(zone_is_slave(zone->opts)) 1475 zc_warning_prev_line("multiple DNAMEs at the same name"); 1476 else 1477 zc_error_prev_line("multiple DNAMEs at the same name"); 1478 } 1479 if(rr->type == TYPE_CNAME && rrset->rr_count > 1) { 1480 if(zone_is_slave(zone->opts)) 1481 zc_warning_prev_line("multiple CNAMEs at the same name"); 1482 else 1483 zc_error_prev_line("multiple CNAMEs at the same name"); 1484 } 1485 if((rr->type == TYPE_DNAME && domain_find_rrset(rr->owner, zone, TYPE_CNAME)) 1486 ||(rr->type == TYPE_CNAME && domain_find_rrset(rr->owner, zone, TYPE_DNAME))) { 1487 if(zone_is_slave(zone->opts)) 1488 zc_warning_prev_line("DNAME and CNAME at the same name"); 1489 else 1490 zc_error_prev_line("DNAME and CNAME at the same name"); 1491 } 1492 if(domain_find_rrset(rr->owner, zone, TYPE_CNAME) && 1493 domain_find_non_cname_rrset(rr->owner, zone)) { 1494 if(zone_is_slave(zone->opts)) 1495 zc_warning_prev_line("CNAME and other data at the same name"); 1496 else 1497 zc_error_prev_line("CNAME and other data at the same name"); 1498 } 1499 1500 /* Check we have SOA */ 1501 if(rr->owner == zone->apex) 1502 apex_rrset_checks(parser->db, rrset, rr->owner); 1503 1504 if(parser->line % ZONEC_PCT_COUNT == 0 && time(NULL) > startzonec + ZONEC_PCT_TIME) { 1505 struct stat buf; 1506 startzonec = time(NULL); 1507 buf.st_size = 0; 1508 fstat(fileno(yyin), &buf); 1509 if(buf.st_size == 0) buf.st_size = 1; 1510 VERBOSITY(1, (LOG_INFO, "parse %s %d %%", 1511 parser->current_zone->opts->name, 1512 (int)((uint64_t)ftell(yyin)*(uint64_t)100/(uint64_t)buf.st_size))); 1513 } 1514 ++totalrrs; 1515 return 1; 1516 } 1517 1518 /* 1519 * Find rrset type for any zone 1520 */ 1521 static rrset_type* 1522 domain_find_rrset_any(domain_type *domain, uint16_t type) 1523 { 1524 rrset_type *result = domain->rrsets; 1525 while (result) { 1526 if (rrset_rrtype(result) == type) { 1527 return result; 1528 } 1529 result = result->next; 1530 } 1531 return NULL; 1532 } 1533 1534 /* 1535 * Check for DNAME type. Nothing is allowed below it 1536 */ 1537 static void 1538 check_dname(zone_type* zone) 1539 { 1540 domain_type* domain; 1541 for(domain = zone->apex; domain && domain_is_subdomain(domain, 1542 zone->apex); domain=domain_next(domain)) 1543 { 1544 if(domain->is_existing) { 1545 /* there may not be DNAMEs above it */ 1546 domain_type* parent = domain->parent; 1547 #ifdef NSEC3 1548 if(domain_has_only_NSEC3(domain, NULL)) 1549 continue; 1550 #endif 1551 while(parent) { 1552 if(domain_find_rrset_any(parent, TYPE_DNAME)) { 1553 zc_error("While checking node %s,", 1554 domain_to_string(domain)); 1555 zc_error("DNAME at %s has data below it. " 1556 "This is not allowed (rfc 2672).", 1557 domain_to_string(parent)); 1558 return; 1559 } 1560 parent = parent->parent; 1561 } 1562 } 1563 } 1564 } 1565 1566 /* 1567 * Reads the specified zone into the memory 1568 * nsd_options can be NULL if no config file is passed. 1569 */ 1570 unsigned int 1571 zonec_read(const char* name, const char* zonefile, zone_type* zone) 1572 { 1573 const dname_type *dname; 1574 1575 totalrrs = 0; 1576 startzonec = time(NULL); 1577 parser->errors = 0; 1578 1579 dname = dname_parse(parser->rr_region, name); 1580 if (!dname) { 1581 zc_error("incorrect zone name '%s'", name); 1582 return 1; 1583 } 1584 1585 #ifndef ROOT_SERVER 1586 /* Is it a root zone? Are we a root server then? Idiot proof. */ 1587 if (dname->label_count == 1) { 1588 zc_error("not configured as a root server"); 1589 return 1; 1590 } 1591 #endif 1592 1593 /* Open the zone file */ 1594 if (!zone_open(zonefile, 3600, CLASS_IN, dname)) { 1595 zc_error("cannot open '%s': %s", zonefile, strerror(errno)); 1596 return 1; 1597 } 1598 parser->current_zone = zone; 1599 1600 /* Parse and process all RRs. */ 1601 yyparse(); 1602 1603 /* remove origin if it was unused */ 1604 if(parser->origin != error_domain) 1605 domain_table_deldomain(parser->db, parser->origin); 1606 /* rr_region has been emptied by now */ 1607 dname = dname_parse(parser->rr_region, name); 1608 1609 /* check if zone file contained a correct SOA record */ 1610 if (!parser->current_zone) { 1611 zc_error("zone configured as '%s' has no content.", name); 1612 } else if(!parser->current_zone->soa_rrset || 1613 parser->current_zone->soa_rrset->rr_count == 0) { 1614 zc_error("zone configured as '%s' has no SOA record.", name); 1615 } else if(dname_compare(domain_dname( 1616 parser->current_zone->soa_rrset->rrs[0].owner), dname) != 0) { 1617 zc_error("zone configured as '%s', but SOA has owner '%s'.", 1618 name, domain_to_string( 1619 parser->current_zone->soa_rrset->rrs[0].owner)); 1620 } 1621 1622 fclose(yyin); 1623 if(!zone_is_slave(zone->opts)) 1624 check_dname(zone); 1625 1626 parser->filename = NULL; 1627 return parser->errors; 1628 } 1629 1630 1631 /* 1632 * setup parse 1633 */ 1634 void 1635 zonec_setup_parser(namedb_type* db) 1636 { 1637 region_type* rr_region = region_create(xalloc, free); 1638 parser = zparser_create(db->region, rr_region, db); 1639 assert(parser); 1640 /* Unique pointers used to mark errors. */ 1641 error_dname = (dname_type *) region_alloc(db->region, 1); 1642 error_domain = (domain_type *) region_alloc(db->region, 1); 1643 /* Open the network database */ 1644 setprotoent(1); 1645 setservent(1); 1646 } 1647 1648 /** desetup parse */ 1649 void 1650 zonec_desetup_parser(void) 1651 { 1652 if(parser) { 1653 endservent(); 1654 endprotoent(); 1655 region_destroy(parser->rr_region); 1656 /* removed when parser->region(=db->region) is destroyed: 1657 * region_recycle(parser->region, (void*)error_dname, 1); 1658 * region_recycle(parser->region, (void*)error_domain, 1); */ 1659 /* clear memory for exit, but this is not portable to 1660 * other versions of lex. yylex_destroy(); */ 1661 } 1662 } 1663 1664 static domain_table_type* orig_domains = NULL; 1665 static region_type* orig_region = NULL; 1666 static region_type* orig_dbregion = NULL; 1667 1668 /** setup for string parse */ 1669 void 1670 zonec_setup_string_parser(region_type* region, domain_table_type* domains) 1671 { 1672 assert(parser); /* global parser must be setup */ 1673 orig_domains = parser->db->domains; 1674 orig_region = parser->region; 1675 orig_dbregion = parser->db->region; 1676 parser->region = region; 1677 parser->db->region = region; 1678 parser->db->domains = domains; 1679 zparser_init("string", 3600, CLASS_IN, domain_dname(domains->root)); 1680 } 1681 1682 /** desetup string parse */ 1683 void 1684 zonec_desetup_string_parser(void) 1685 { 1686 parser->region = orig_region; 1687 parser->db->domains = orig_domains; 1688 parser->db->region = orig_dbregion; 1689 } 1690 1691 /** parse a string into temporary storage */ 1692 int 1693 zonec_parse_string(region_type* region, domain_table_type* domains, 1694 zone_type* zone, char* str, domain_type** parsed, int* num_rrs) 1695 { 1696 int errors; 1697 zonec_setup_string_parser(region, domains); 1698 parser->current_zone = zone; 1699 parser->errors = 0; 1700 totalrrs = 0; 1701 startzonec = time(NULL)+100000; /* disable */ 1702 parser_push_stringbuf(str); 1703 yyparse(); 1704 parser_pop_stringbuf(); 1705 errors = parser->errors; 1706 *num_rrs = totalrrs; 1707 if(*num_rrs == 0) 1708 *parsed = NULL; 1709 else *parsed = parser->prev_dname; 1710 /* remove origin if it was not used during the parse */ 1711 if(parser->origin != error_domain) 1712 domain_table_deldomain(parser->db, parser->origin); 1713 zonec_desetup_string_parser(); 1714 return errors; 1715 } 1716