示例#1
0
/**
 * Print ixfr.
 *
 */
ods_status
adapi_printixfr(FILE* fd, zone_type* zone)
{
    rrset_type* rrset = NULL;
    ods_status status = ODS_STATUS_OK;
    if (!fd || !zone || !zone->db || !zone->ixfr) {
        ods_log_error("[%s] unable to print ixfr: file descriptor, zone or "
            "name database missing", adapi_str);
        return ODS_STATUS_ASSERT_ERR;
    }
    if (!zone->db->is_initialized) {
        /* no ixfr yet */
        return ODS_STATUS_OK;
    }
    rrset = zone_lookup_rrset(zone, zone->apex, LDNS_RR_TYPE_SOA);
    ods_log_assert(rrset);
    rrset_print(fd, rrset, 1, &status);
    if (status != ODS_STATUS_OK) {
        return status;
    }
    pthread_mutex_lock(&zone->ixfr->ixfr_lock);
    if (ixfr_print(fd, zone->ixfr)) {
        zone->adoutbound->error = 1;
    }
    pthread_mutex_unlock(&zone->ixfr->ixfr_lock);
    rrset_print(fd, rrset, 1, &status);
    return status;
}
示例#2
0
/**
 * Update serial.
 *
 */
ods_status
zone_update_serial(zone_type* zone)
{
    ods_status status = ODS_STATUS_OK;
    rrset_type* rrset = NULL;
    rr_type* soa = NULL;
    ldns_rr* rr = NULL;
    ldns_rdf* soa_rdata = NULL;

    ods_log_assert(zone);
    ods_log_assert(zone->apex);
    ods_log_assert(zone->name);
    ods_log_assert(zone->db);
    ods_log_assert(zone->signconf);

    if (zone->db->serial_updated) {
        /* already done, unmark and return ok */
        ods_log_debug("[%s] zone %s soa serial already up to date",
            zone_str, zone->name);
        zone->db->serial_updated = 0;
        return ODS_STATUS_OK;
    }
    rrset = zone_lookup_rrset(zone, zone->apex, LDNS_RR_TYPE_SOA);
    ods_log_assert(rrset);
    ods_log_assert(rrset->rrs);
    ods_log_assert(rrset->rrs[0].rr);
    rr = ldns_rr_clone(rrset->rrs[0].rr);
    if (!rr) {
        ods_log_error("[%s] unable to update zone %s soa serial: failed to "
            "clone soa rr", zone_str, zone->name);
        return ODS_STATUS_ERR;
    }
    status = namedb_update_serial(zone->db, zone->signconf->soa_serial,
        zone->db->inbserial);
    if (status != ODS_STATUS_OK) {
        ods_log_error("[%s] unable to update zone %s soa serial: %s",
            zone_str, zone->name, ods_status2str(status));
        ldns_rr_free(rr);
        return status;
    }
    ods_log_verbose("[%s] zone %s set soa serial to %u", zone_str,
        zone->name, zone->db->intserial);
    soa_rdata = ldns_rr_set_rdf(rr,
        ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32,
        zone->db->intserial), SE_SOA_RDATA_SERIAL);
    if (soa_rdata) {
        ldns_rdf_deep_free(soa_rdata);
        soa_rdata = NULL;
    } else {
        ods_log_error("[%s] unable to update zone %s soa serial: failed to "
            "replace soa serial rdata", zone_str, zone->name);
        ldns_rr_free(rr);
        return ODS_STATUS_ERR;
    }
    soa = rrset_add_rr(rrset, rr);
    ods_log_assert(soa);
    rrset_diff(rrset, 0, 0);
    zone->db->serial_updated = 0;
    return ODS_STATUS_OK;
}
示例#3
0
/**
 * Publish the NSEC3 parameters as indicated by the signer configuration.
 *
 */
ods_status
zone_publish_nsec3param(zone_type* zone)
{
    rrset_type* rrset = NULL;
    rr_type* n3prr = NULL;
    ldns_rr* rr = NULL;
    ods_status status = ODS_STATUS_OK;

    if (!zone || !zone->name || !zone->db || !zone->signconf) {
        return ODS_STATUS_ASSERT_ERR;
    }
    if (!zone->signconf->nsec3params) {
        /* NSEC */
        ods_log_assert(zone->signconf->nsec_type == LDNS_RR_TYPE_NSEC);
        return ODS_STATUS_OK;
    }

    if (!zone->signconf->nsec3params->rr) {
        rr = ldns_rr_new_frm_type(LDNS_RR_TYPE_NSEC3PARAMS);
        if (!rr) {
            ods_log_error("[%s] unable to publish nsec3params for zone %s: "
                "error creating rr (%s)", zone_str, zone->name,
                ods_status2str(status));
            return ODS_STATUS_MALLOC_ERR;
        }
        ldns_rr_set_class(rr, zone->klass);
        ldns_rr_set_ttl(rr, 0);
        ldns_rr_set_owner(rr, ldns_rdf_clone(zone->apex));
        ldns_nsec3_add_param_rdfs(rr,
            zone->signconf->nsec3params->algorithm, 0,
            zone->signconf->nsec3params->iterations,
            zone->signconf->nsec3params->salt_len,
            zone->signconf->nsec3params->salt_data);
        /**
         * Always set bit 7 of the flags to zero,
         * according to rfc5155 section 11
         */
        ldns_set_bit(ldns_rdf_data(ldns_rr_rdf(rr, 1)), 7, 0);
        zone->signconf->nsec3params->rr = rr;
    }
    ods_log_assert(zone->signconf->nsec3params->rr);
    status = zone_add_rr(zone, zone->signconf->nsec3params->rr, 0);
    if (status == ODS_STATUS_UNCHANGED) {
        /* rr already exists, adjust pointer */
        rrset = zone_lookup_rrset(zone, zone->apex, LDNS_RR_TYPE_NSEC3PARAMS);
        ods_log_assert(rrset);
        n3prr = rrset_lookup_rr(rrset, zone->signconf->nsec3params->rr);
        ods_log_assert(n3prr);
        if (n3prr->rr != zone->signconf->nsec3params->rr) {
            ldns_rr_free(zone->signconf->nsec3params->rr);
        }
        zone->signconf->nsec3params->rr = n3prr->rr;
        status = ODS_STATUS_OK;
    } else if (status != ODS_STATUS_OK) {
        ods_log_error("[%s] unable to publish nsec3params for zone %s: "
            "error adding nsec3params (%s)", zone_str,
            zone->name, ods_status2str(status));
    }
    return status;
}
/**
 * Query response.
 *
 */
static query_state
query_response(query_type* q, ldns_rr_type qtype)
{
    rrset_type* rrset = NULL;
    response_type r;
    if (!q || !q->zone) {
        return QUERY_DISCARDED;
    }
    r.rrset_count = 0;
    lock_basic_lock(&q->zone->zone_lock);
    rrset = zone_lookup_rrset(q->zone, q->zone->apex, qtype);
    if (rrset) {
        if (!response_add_rrset(&r, rrset, LDNS_SECTION_ANSWER)) {
            lock_basic_unlock(&q->zone->zone_lock);
            return query_servfail(q);
        }
        /* NS RRset goes into Authority Section */
        rrset = zone_lookup_rrset(q->zone, q->zone->apex, LDNS_RR_TYPE_NS);
        if (rrset) {
            if (!response_add_rrset(&r, rrset, LDNS_SECTION_AUTHORITY)) {
                lock_basic_unlock(&q->zone->zone_lock);
                return query_servfail(q);
            }
        }
    } else if (qtype != LDNS_RR_TYPE_SOA) {
        rrset = zone_lookup_rrset(q->zone, q->zone->apex, LDNS_RR_TYPE_SOA);
        if (rrset) {
            if (!response_add_rrset(&r, rrset, LDNS_SECTION_AUTHORITY)) {
                lock_basic_unlock(&q->zone->zone_lock);
                return query_servfail(q);
            }
        }
    } else {
        lock_basic_unlock(&q->zone->zone_lock);
        return query_servfail(q);
    }
    lock_basic_unlock(&q->zone->zone_lock);

    response_encode(q, &r);
    /* compression */
    return QUERY_PROCESSED;
}
示例#5
0
/**
 * Print axfr.
 *
 */
ods_status
adapi_printaxfr(FILE* fd, zone_type* zone)
{
    rrset_type* rrset = NULL;
    ods_status status = ODS_STATUS_OK;
    if (!fd || !zone || !zone->db) {
        ods_log_error("[%s] unable to print axfr: file descriptor, zone or "
            "name database missing", adapi_str);
        return ODS_STATUS_ASSERT_ERR;
    }
    namedb_export(fd, zone->db, &status);
    if (status == ODS_STATUS_OK) {
        rrset = zone_lookup_rrset(zone, zone->apex, LDNS_RR_TYPE_SOA);
        ods_log_assert(rrset);
        rrset_print(fd, rrset, 1, &status);
    }
    return status;
}
示例#6
0
/**
 * Unlink NSEC3PARAM RR.
 *
 */
void
zone_rollback_nsec3param(zone_type* zone)
{
    rrset_type* rrset = NULL;
    rr_type* n3prr = NULL;

    if (!zone || !zone->signconf || !zone->signconf->nsec3params) {
        return;
    }
    rrset = zone_lookup_rrset(zone, zone->apex, LDNS_RR_TYPE_NSEC3PARAMS);
    if (rrset && zone->signconf->nsec3params->rr) {
        n3prr = rrset_lookup_rr(rrset, zone->signconf->nsec3params->rr);
        if (n3prr && !n3prr->exists &&
            n3prr->rr == zone->signconf->nsec3params->rr) {
            zone->signconf->nsec3params->rr = NULL;
        }
    }
    return;
}
示例#7
0
文件: addns.c 项目: icaas/opendnssec
/**
 * Send notifies.
 *
 */
static void
dnsout_send_notify(void* zone)
{
    zone_type* z = (zone_type*) zone;
    rrset_type* rrset = NULL;
    ldns_rr* soa = NULL;
    if (!z || !z->notify) {
        ods_log_error("[%s] unable to send notify for zone %s: no notify "
                      "handler", adapter_str, z->name);
        return;
    }
    ods_log_assert(z->adoutbound);
    ods_log_assert(z->adoutbound->config);
    ods_log_assert(z->adoutbound->type == ADAPTER_DNS);
    ods_log_assert(z->db);
    ods_log_assert(z->name);
    ods_log_debug("[%s] enable notify for zone %s serial %u", adapter_str,
                  z->name, z->db->intserial);
    rrset = zone_lookup_rrset(z, z->apex, LDNS_RR_TYPE_SOA);
    ods_log_assert(rrset);
    soa = ldns_rr_clone(rrset->rrs[0].rr);
    notify_enable(z->notify, soa);
    return;
}
示例#8
0
/**
 * Unlink DNSKEY RRs.
 *
 */
void
zone_rollback_dnskeys(zone_type* zone)
{
    uint16_t i = 0;
    rrset_type* rrset = NULL;
    rr_type* dnskey = NULL;
    if (!zone || !zone->signconf || !zone->signconf->keys) {
        return;
    }
    rrset = zone_lookup_rrset(zone, zone->apex, LDNS_RR_TYPE_DNSKEY);
    /* unlink dnskey rrs */
    for (i=0; i < zone->signconf->keys->count; i++) {
        if (rrset && zone->signconf->keys->keys[i].dnskey) {
            dnskey = rrset_lookup_rr(rrset,
                zone->signconf->keys->keys[i].dnskey);
            if (dnskey && !dnskey->exists &&
                dnskey->rr == zone->signconf->keys->keys[i].dnskey) {
                zone->signconf->keys->keys[i].dnskey = NULL;
            }
        }
    }
    /* done */
    return;
}
/**
 * Read namedb from backup file.
 *
 */
ods_status
backup_read_namedb(FILE* in, void* zone)
{
    zone_type* z = (zone_type*) zone;
    denial_type* denial = NULL;
    rrset_type* rrset = NULL;
    ods_status result = ODS_STATUS_OK;
    ldns_rr_type type_covered;
    ldns_rr* rr = NULL;
    ldns_rdf* prev = NULL;
    ldns_rdf* orig = NULL;
    ldns_rdf* dname = NULL;
    ldns_status status = LDNS_STATUS_OK;
    char line[SE_ADFILE_MAXLINE];
    char* str = NULL;
    char* locator = NULL;
    uint32_t flags = 0;
    unsigned int l = 0;

    ods_log_assert(in);
    ods_log_assert(z);

    /* $ORIGIN <zone name> */
    dname = adapi_get_origin(z);
    if (!dname) {
        ods_log_error("[%s] error getting default value for $ORIGIN",
                      backup_str);
        return ODS_STATUS_ERR;
    }
    orig = ldns_rdf_clone(dname);
    if (!orig) {
        ods_log_error("[%s] error setting default value for $ORIGIN",
                      backup_str);
        return ODS_STATUS_ERR;
    }
    /* read RRs */
    ods_log_debug("[%s] read RRs %s", backup_str, z->name);
    while ((rr = backup_read_rr(in, z, line, &orig, &prev, &status, &l))
            != NULL) {
        /* check status */
        if (status != LDNS_STATUS_OK) {
            ods_log_error("[%s] error reading RR #%i (%s): %s",
                          backup_str, l, ldns_get_errorstr_by_id(status), line);
            result = ODS_STATUS_ERR;
            goto backup_namedb_done;
        }
        /* add to the database */
        result = adapi_add_rr(z, rr, 1);
        if (result == ODS_STATUS_UNCHANGED) {
            ods_log_debug("[%s] skipping RR #%i (duplicate): %s",
                          backup_str, l, line);
            ldns_rr_free(rr);
            rr = NULL;
            result = ODS_STATUS_OK;
            continue;
        } else if (result != ODS_STATUS_OK) {
            ods_log_error("[%s] error adding RR #%i: %s",
                          backup_str, l, line);
            ldns_rr_free(rr);
            rr = NULL;
            goto backup_namedb_done;
        }
    }
    if (result == ODS_STATUS_OK && status != LDNS_STATUS_OK) {
        ods_log_error("[%s] error reading RR #%i (%s): %s",
                      backup_str, l, ldns_get_errorstr_by_id(status), line);
        result = ODS_STATUS_ERR;
        goto backup_namedb_done;
    }
    namedb_diff(z->db, 0, 0);

    /* read NSEC(3)s */
    ods_log_debug("[%s] read NSEC(3)s %s", backup_str, z->name);
    l = 0;
    while ((rr = backup_read_rr(in, z, line, &orig, &prev, &status, &l))
            != NULL) {
        /* check status */
        if (status != LDNS_STATUS_OK) {
            ods_log_error("[%s] error reading NSEC(3) #%i (%s): %s",
                          backup_str, l, ldns_get_errorstr_by_id(status), line);
            result = ODS_STATUS_ERR;
            goto backup_namedb_done;
        }
        if (ldns_rr_get_type(rr) != LDNS_RR_TYPE_NSEC &&
                ldns_rr_get_type(rr) != LDNS_RR_TYPE_NSEC3) {
            ods_log_error("[%s] error NSEC(3) #%i is not NSEC(3): %s",
                          backup_str, l, line);
            ldns_rr_free(rr);
            rr = NULL;
            result = ODS_STATUS_ERR;
            goto backup_namedb_done;
        }
        /* add to the denial chain */
        denial = namedb_lookup_denial(z->db, ldns_rr_owner(rr));
        if (!denial) {
            ods_log_error("[%s] error adding NSEC(3) #%i: %s",
                          backup_str, l, line);
            ldns_rr_free(rr);
            rr = NULL;
            result = ODS_STATUS_ERR;
            goto backup_namedb_done;
        }
        denial_add_rr(denial, rr);
    }
    if (result == ODS_STATUS_OK && status != LDNS_STATUS_OK) {
        ods_log_error("[%s] error reading NSEC(3) #%i (%s): %s",
                      backup_str, l, ldns_get_errorstr_by_id(status), line);
        result = ODS_STATUS_ERR;
        goto backup_namedb_done;
    }

    /* read RRSIGs */
    ods_log_debug("[%s] read RRSIGs %s", backup_str, z->name);
    l = 0;
    while ((rr = backup_read_rr(in, z, line, &orig, &prev, &status, &l))
            != NULL) {
        /* check status */
        if (status != LDNS_STATUS_OK) {
            ods_log_error("[%s] error reading RRSIG #%i (%s): %s",
                          backup_str, l, ldns_get_errorstr_by_id(status), line);
            result = ODS_STATUS_ERR;
            goto backup_namedb_done;
        }
        if (ldns_rr_get_type(rr) != LDNS_RR_TYPE_RRSIG) {
            ods_log_error("[%s] error RRSIG #%i is not RRSIG: %s",
                          backup_str, l, line);
            ldns_rr_free(rr);
            rr = NULL;
            result = ODS_STATUS_ERR;
            goto backup_namedb_done;
        }
        /* read locator and flags */
        str = strstr(line, "flags");
        if (str) {
            flags = (uint32_t) atoi(str+6);
        }
        str = strstr(line, "locator");
        if (str) {
            locator = replace_space_with_nul(str+8);
        }
        /* add signatures */
        type_covered = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr));
        if (type_covered == LDNS_RR_TYPE_NSEC ||
                type_covered == LDNS_RR_TYPE_NSEC3) {
            denial = namedb_lookup_denial(z->db, ldns_rr_owner(rr));
            if (!denial) {
                ods_log_error("[%s] error restoring RRSIG #%i (%s): %s",
                              backup_str, l, ldns_get_errorstr_by_id(status), line);
                ldns_rr_free(rr);
                rr = NULL;
                result = ODS_STATUS_ERR;
                goto backup_namedb_done;
            }
            rrset = denial->rrset;
        } else {
            rrset = zone_lookup_rrset(z, ldns_rr_owner(rr), type_covered);
        }
        if (!rrset || !rrset_add_rrsig(rrset, rr, locator, flags)) {
            ods_log_error("[%s] error restoring RRSIG #%i (%s): %s",
                          backup_str, l, ldns_get_errorstr_by_id(status), line);
            ldns_rr_free(rr);
            rr = NULL;
            result = ODS_STATUS_ERR;
            goto backup_namedb_done;
        } else {
            rrset->needs_signing = 0;
        }
    }
    if (result == ODS_STATUS_OK && status != LDNS_STATUS_OK) {
        ods_log_error("[%s] error reading RRSIG #%i (%s): %s",
                      backup_str, l, ldns_get_errorstr_by_id(status), line);
        result = ODS_STATUS_ERR;
    }

backup_namedb_done:
    if (orig) {
        ldns_rdf_deep_free(orig);
        orig = NULL;
    }
    if (prev) {
        ldns_rdf_deep_free(prev);
        prev = NULL;
    }
    return result;
}
示例#10
0
/**
 * Publish the keys as indicated by the signer configuration.
 *
 */
ods_status
zone_publish_dnskeys(zone_type* zone)
{
    hsm_ctx_t* ctx = NULL;
    uint32_t ttl = 0;
    uint16_t i = 0;
    ods_status status = ODS_STATUS_OK;
    rrset_type* rrset = NULL;
    rr_type* dnskey = NULL;

    if (!zone || !zone->db || !zone->signconf || !zone->signconf->keys) {
        return ODS_STATUS_ASSERT_ERR;
    }
    ods_log_assert(zone->name);

    /* hsm access */
    ctx = hsm_create_context();
    if (ctx == NULL) {
        ods_log_error("[%s] unable to publish keys for zone %s: "
            "error creating libhsm context", zone_str, zone->name);
        return ODS_STATUS_HSM_ERR;
    }
    /* dnskey ttl */
    ttl = zone->default_ttl;
    if (zone->signconf->dnskey_ttl) {
        ttl = (uint32_t) duration2time(zone->signconf->dnskey_ttl);
    }
    /* publish keys */
    for (i=0; i < zone->signconf->keys->count; i++) {
        if (!zone->signconf->keys->keys[i].publish) {
            continue;
        }
        if (!zone->signconf->keys->keys[i].dnskey) {
            /* get dnskey */
            status = lhsm_get_key(ctx, zone->apex,
                &zone->signconf->keys->keys[i]);
            if (status != ODS_STATUS_OK) {
                ods_log_error("[%s] unable to publish dnskeys for zone %s: "
                    "error creating dnskey", zone_str, zone->name);
                break;
            }
        }
        ods_log_assert(zone->signconf->keys->keys[i].dnskey);
        ldns_rr_set_ttl(zone->signconf->keys->keys[i].dnskey, ttl);
        ldns_rr_set_class(zone->signconf->keys->keys[i].dnskey, zone->klass);
        status = zone_add_rr(zone, zone->signconf->keys->keys[i].dnskey, 0);
        if (status == ODS_STATUS_UNCHANGED) {
            /* rr already exists, adjust pointer */
            rrset = zone_lookup_rrset(zone, zone->apex, LDNS_RR_TYPE_DNSKEY);
            ods_log_assert(rrset);
            dnskey = rrset_lookup_rr(rrset,
                zone->signconf->keys->keys[i].dnskey);
            ods_log_assert(dnskey);
            if (dnskey->rr != zone->signconf->keys->keys[i].dnskey) {
                ldns_rr_free(zone->signconf->keys->keys[i].dnskey);
            }
            zone->signconf->keys->keys[i].dnskey = dnskey->rr;
            status = ODS_STATUS_OK;
        } else if (status != ODS_STATUS_OK) {
            ods_log_error("[%s] unable to publish dnskeys for zone %s: "
                "error adding dnskey", zone_str, zone->name);
            break;
        }
    }
    /* done */
    hsm_destroy_context(ctx);
    return status;
}