예제 #1
0
/** parse a string into temporary storage */
int
zonec_parse_string(region_type* region, domain_table_type* domains,
	zone_type* zone, char* str, domain_type** parsed, int* num_rrs)
{
	int errors;
	zonec_setup_string_parser(region, domains);
	parser->current_zone = zone;
	parser->errors = 0;
	totalrrs = 0;
	startzonec = time(NULL)+100000; /* disable */
	parser_push_stringbuf(str);
	yyparse();
	parser_pop_stringbuf();
	errors = parser->errors;
	*num_rrs = totalrrs;
	if(*num_rrs == 0)
		*parsed = NULL;
	else	*parsed = parser->prev_dname;
	/* remove origin if it was not used during the parse */
	if(parser->origin != error_domain)
		domain_table_deldomain(parser->db, parser->origin);
	region_free_all(parser->rr_region);
	zonec_desetup_string_parser();
	parser_flush();
	return errors;
}
예제 #2
0
static void
set_previous_owner(struct state_pretty_rr *state, const dname_type *dname)
{
	region_free_all(state->previous_owner_region);
	state->previous_owner = dname_copy(state->previous_owner_region, dname);
	state->previous_owner_origin = dname_origin(
		state->previous_owner_region, state->previous_owner);
}
예제 #3
0
void
region_destroy(region_type *region)
{
	void (*deallocator)(void *);
	if (!region)
		return;

	deallocator = region->deallocator;

	region_free_all(region);
	deallocator(region->cleanups);
	deallocator(region->initial_data);
	if(region->recycle_bin)
		deallocator(region->recycle_bin);
	if(region->large_list) {
		struct large_elem* p = region->large_list, *np;
		while(p) {
			np = p->next;
			deallocator(p);
			p = np;
		}
	}
	deallocator(region);
}
예제 #4
0
/*
 * Reads the specified zone into the memory
 * nsd_options can be NULL if no config file is passed.
 */
unsigned int
zonec_read(const char* name, const char* zonefile, zone_type* zone)
{
	const dname_type *dname;

	totalrrs = 0;
	startzonec = time(NULL);
	parser->errors = 0;

	dname = dname_parse(parser->rr_region, name);
	if (!dname) {
		zc_error("incorrect zone name '%s'", name);
		return 1;
	}

#ifndef ROOT_SERVER
	/* Is it a root zone? Are we a root server then? Idiot proof. */
	if (dname->label_count == 1) {
		zc_error("not configured as a root server");
		return 1;
	}
#endif

	/* Open the zone file */
	if (!zone_open(zonefile, 3600, CLASS_IN, dname)) {
		zc_error("cannot open '%s': %s", zonefile, strerror(errno));
		return 1;
	}
	parser->current_zone = zone;

	/* Parse and process all RRs.  */
	yyparse();

	/* remove origin if it was unused */
	if(parser->origin != error_domain)
		domain_table_deldomain(parser->db, parser->origin);
	/* rr_region has been emptied by now */
	dname = dname_parse(parser->rr_region, name);

	/* check if zone file contained a correct SOA record */
	if (!parser->current_zone) {
		zc_error("zone configured as '%s' has no content.", name);
	} else if(!parser->current_zone->soa_rrset ||
		parser->current_zone->soa_rrset->rr_count == 0) {
		zc_error("zone configured as '%s' has no SOA record.", name);
	} else if(dname_compare(domain_dname(
		parser->current_zone->soa_rrset->rrs[0].owner), dname) != 0) {
		zc_error("zone configured as '%s', but SOA has owner '%s'.",
			name, domain_to_string(
			parser->current_zone->soa_rrset->rrs[0].owner));
	}
	region_free_all(parser->rr_region);

	parser_flush();
	fclose(yyin);
	if(!zone_is_slave(zone->opts))
		check_dname(zone);

	parser->filename = NULL;
	return parser->errors;
}
예제 #5
0
struct namedb *
namedb_open (const char *filename, nsd_options_t* opt, size_t num_children)
{
    namedb_type *db;

    /*
     * Temporary region used while loading domain names from the
     * database.  The region is freed after each time a dname is
     * read from the database.
     */
    region_type *dname_region;

    /*
     * Temporary region used to store array of domains and zones
     * while loading the database.  The region is freed before
     * returning.
     */
    region_type *temp_region;

    uint32_t dname_count;
    domain_type **domains;	/* Indexed by domain number.  */

    uint32_t zone_count;
    zone_type **zones;	/* Indexed by zone number.  */

    uint32_t i;
    uint32_t rrset_count = 0;
    uint32_t rr_count = 0;

    rrset_type *rrset;

    DEBUG(DEBUG_DBACCESS, 2,
          (LOG_INFO, "sizeof(namedb_type) = %lu\n", (unsigned long) sizeof(namedb_type)));
    DEBUG(DEBUG_DBACCESS, 2,
          (LOG_INFO, "sizeof(zone_type) = %lu\n", (unsigned long) sizeof(zone_type)));
    DEBUG(DEBUG_DBACCESS, 2,
          (LOG_INFO, "sizeof(domain_type) = %lu\n", (unsigned long) sizeof(domain_type)));
    DEBUG(DEBUG_DBACCESS, 2,
          (LOG_INFO, "sizeof(rrset_type) = %lu\n", (unsigned long) sizeof(rrset_type)));
    DEBUG(DEBUG_DBACCESS, 2,
          (LOG_INFO, "sizeof(rr_type) = %lu\n", (unsigned long) sizeof(rr_type)));
    DEBUG(DEBUG_DBACCESS, 2,
          (LOG_INFO, "sizeof(rdata_atom_type) = %lu\n", (unsigned long) sizeof(rdata_atom_type)));
    DEBUG(DEBUG_DBACCESS, 2,
          (LOG_INFO, "sizeof(rbnode_t) = %lu\n", (unsigned long) sizeof(rbnode_t)));

    if ((db = namedb_create()) == NULL) {
        log_msg(LOG_ERR,
                "insufficient memory to create database");
        return NULL;
    }
    db->filename = region_strdup(db->region, filename);

    if (gettimeofday(&(db->diff_timestamp), NULL) != 0) {
        log_msg(LOG_ERR, "unable to load %s: cannot initialize"
                "timestamp", db->filename);
        namedb_destroy(db);
        return NULL;
    }

    /* Open it... */
    db->fd = fopen(db->filename, "r");
    if (db->fd == NULL) {
        log_msg(LOG_ERR, "unable to load %s: %s",
                db->filename, strerror(errno));
        namedb_destroy(db);
        return NULL;
    }

    if (!read_magic(db)) {
        log_msg(LOG_ERR, "corrupted database (read magic): %s", db->filename);
        log_msg(LOG_ERR, "cannot load database, incompatible version "
                "number. Please rebuild database and "
                "start again.");
        namedb_close(db);
        return NULL;
    }

    if (!read_size(db, &zone_count)) {
        log_msg(LOG_ERR, "corrupted database (read size): %s", db->filename);
        namedb_close(db);
        return NULL;
    }

    DEBUG(DEBUG_DBACCESS, 1,
          (LOG_INFO, "Retrieving %lu zones\n", (unsigned long) zone_count));

    temp_region = region_create(xalloc, free);
    dname_region = region_create(xalloc, free);

    db->zone_count = zone_count;
    zones = (zone_type **) region_alloc(temp_region,
                                        zone_count * sizeof(zone_type *));
    for (i = 0; i < zone_count; ++i) {
        const dname_type *dname = read_dname(db->fd, dname_region);
        if (!dname) {
            log_msg(LOG_ERR, "corrupted database (read dname): %s", db->filename);
            region_destroy(dname_region);
            region_destroy(temp_region);
            namedb_close(db);
            return NULL;
        }
        zones[i] = (zone_type *) region_alloc(db->region,
                                              sizeof(zone_type));
        zones[i]->next = db->zones;
        db->zones = zones[i];
        zones[i]->apex = domain_table_insert(db->domains, dname);
        zones[i]->soa_rrset = NULL;
        zones[i]->soa_nx_rrset = NULL;
        zones[i]->ns_rrset = NULL;
#ifdef NSEC3
        zones[i]->nsec3_soa_rr = NULL;
        zones[i]->nsec3_last = NULL;
#endif
        zones[i]->opts = zone_options_find(opt, domain_dname(zones[i]->apex));
        zones[i]->number = i + 1;
        zones[i]->is_secure = 0;
        zones[i]->updated = 1;
        zones[i]->is_ok = 0;
        zones[i]->dirty = region_alloc(db->region, sizeof(uint8_t)*num_children);
        memset(zones[i]->dirty, 0, sizeof(uint8_t)*num_children);
        if(!zones[i]->opts) {
            log_msg(LOG_ERR, "cannot load database. Zone %s in db "
                    "%s, but not in config file (might "
                    "happen if you edited the config "
                    "file). Please rebuild database and "
                    "start again.",
                    dname_to_string(dname, NULL), db->filename);
            region_destroy(dname_region);
            region_destroy(temp_region);
            namedb_close(db);
            return NULL;
        }
#ifdef NSEC3
#ifndef FULL_PREHASH
        zones[i]->nsec3_domains = NULL;
        if (0 != zone_nsec3_domains_create(db, zones[i])) {
            log_msg(LOG_ERR,
                    "insufficient memory for NSEC3 tree, "
                    "unable to read database");
            region_destroy(dname_region);
            region_destroy(temp_region);
            namedb_close(db);
            return NULL;
        }
#endif /* !FULL_PREHASH */
#endif /* NSEC3 */
        region_free_all(dname_region);
    }

    if (!read_size(db, &dname_count)) {
        log_msg(LOG_ERR, "corrupted database (read size): %s", db->filename);
        region_destroy(dname_region);
        region_destroy(temp_region);
        namedb_close(db);
        return NULL;
    }

    DEBUG(DEBUG_DBACCESS, 1,
          (LOG_INFO, "Retrieving %lu domain names\n", (unsigned long) dname_count));

    domains = (domain_type **) region_alloc(
                  temp_region, dname_count * sizeof(domain_type *));
    for (i = 0; i < dname_count; ++i) {
        const dname_type *dname = read_dname(db->fd, dname_region);
        if (!dname) {
            log_msg(LOG_ERR, "corrupted database (read dname): %s", db->filename);
            region_destroy(dname_region);
            region_destroy(temp_region);
            namedb_close(db);
            return NULL;
        }
        domains[i] = domain_table_insert(db->domains, dname);
        region_free_all(dname_region);
    }

    region_destroy(dname_region);

#ifndef NDEBUG
    fprintf(stderr, "database region after loading domain names: ");
    region_dump_stats(db->region, stderr);
    fprintf(stderr, "\n");
#endif

    while ((rrset = read_rrset(db, dname_count, domains, zone_count, zones))) {
        ++rrset_count;
        rr_count += rrset->rr_count;
    }

    DEBUG(DEBUG_DBACCESS, 1,
          (LOG_INFO, "Retrieved %lu RRs in %lu RRsets\n",
           (unsigned long) rr_count, (unsigned long) rrset_count));

    region_destroy(temp_region);

    if ((db->crc_pos = ftello(db->fd)) == -1) {
        log_msg(LOG_ERR, "ftello %s failed: %s",
                db->filename, strerror(errno));
        namedb_close(db);
        return NULL;
    }
    if (!read_size(db, &db->crc)) {
        log_msg(LOG_ERR, "corrupted database (read size): %s", db->filename);
        namedb_close(db);
        return NULL;
    }
    if (!read_magic(db)) {
        log_msg(LOG_ERR, "corrupted database (read magic): %s", db->filename);
        log_msg(LOG_ERR, "cannot load database, incompatible version "
                "number. Please rebuild database and "
                "start again.");
        namedb_close(db);
        return NULL;
    }

    fclose(db->fd);
    db->fd = NULL;

#ifndef NDEBUG
    fprintf(stderr, "database region after loading database: ");
    region_dump_stats(db->region, stderr);
    fprintf(stderr, "\n");
#endif

    return db;
}