コード例 #1
0
/**
 * Merge zones.
 *
 */
void
zone_merge(zone_type* z1, zone_type* z2)
{
    const char* str;
    adapter_type* adtmp = NULL;

    if (!z1 || !z2) {
        return;
    }
    /* policy name */
    if (ods_strcmp(z2->policy_name, z1->policy_name) != 0) {
        if (z2->policy_name) {
            str = strdup(z2->policy_name);
            if (!str) {
                ods_log_error("[%s] failed to merge policy %s name to zone "
                    "%s", zone_str, z2->policy_name, z1->name);
            } else {
                free((void*)z1->policy_name);
                z1->policy_name = str;
                z1->zl_status = ZONE_ZL_UPDATED;
            }
        } else {
            free((void*)z1->policy_name);
            z1->policy_name = NULL;
            z1->zl_status = ZONE_ZL_UPDATED;
        }
    }
    /* signconf filename */
    if (ods_strcmp(z2->signconf_filename, z1->signconf_filename) != 0) {
        if (z2->signconf_filename) {
            str = strdup(z2->signconf_filename);
            if (!str) {
                ods_log_error("[%s] failed to merge signconf filename %s to "
                    "zone %s", zone_str, z2->policy_name, z1->name);
            } else {
                free((void*)z1->signconf_filename);
                z1->signconf_filename = str;
                z1->zl_status = ZONE_ZL_UPDATED;
            }
        } else {
            free((void*)z1->signconf_filename);
            z1->signconf_filename = NULL;
            z1->zl_status = ZONE_ZL_UPDATED;
        }
    }
    /* adapters */
    if (adapter_compare(z2->adinbound, z1->adinbound) != 0) {
        adtmp = z2->adinbound;
        z2->adinbound = z1->adinbound;
        z1->adinbound = adtmp;
        adtmp = NULL;
    }
    if (adapter_compare(z2->adoutbound, z1->adoutbound) != 0) {
        adtmp = z2->adoutbound;
        z2->adoutbound = z1->adoutbound;
        z1->adoutbound = adtmp;
        adtmp = NULL;
    }
    return;
}
コード例 #2
0
ファイル: file.c プロジェクト: eest/opendnssec
/**
 * Convert file mode to readable string.
 *
 */
const char*
ods_file_mode2str(const char* mode)
{
    if (!mode) {
        return "no mode";
    }

    if (ods_strcmp(mode, "a") == 0) {
        return "appending";
    } else if (ods_strcmp(mode, "r") == 0) {
        return "reading";
    } else if (ods_strcmp(mode, "w") == 0) {
        return "writing";
	}
    return "unknown mode";
}
コード例 #3
0
ファイル: ods-enforcer.c プロジェクト: bbczeuz/opendnssec
/**
 * Main. start interface tool.
 *
 */
int
main(int argc, char* argv[])
{
    char* cmd = NULL;
    int ret = 0;
    allocator_type* clialloc = allocator_create(malloc, free);
    if (!clialloc) {
        fprintf(stderr,"error, malloc failed for client\n");
        exit(1);
    }

	/*	argv[0] is always the executable name so 
		argc is always 1 or higher */
	ods_log_assert(argc >= 1);
	
	/*	concat arguments an add 1 extra char for 
		adding '\n' char later on, but only when argc > 1 */
    cmd = ods_str_join(clialloc,argc-1,&argv[1],' ');

    if (argc > 1 && !cmd) {
        fprintf(stderr, "memory allocation failed\n");
        exit(1);
    }

    /* main stuff */
    if (!cmd) {
        ret = interface_start(cmd);
    } else {
        if (ods_strcmp(cmd, "-h") == 0 || ods_strcmp(cmd, "--help") == 0) {
            usage(stdout);
            ret = 1;
        } else {
            strcat(cmd,"\n");
            ret = interface_start(cmd);
        }
    }

    /* done */
    allocator_deallocate(clialloc, (void*) cmd);
    allocator_cleanup(clialloc);
    return ret;
}
コード例 #4
0
/**
 * Read and match a string from backup file.
 *
 */
int
backup_read_check_str(FILE* in, const char* str)
{
    char *p = backup_read_token(in);
    if (!p) {
        ods_log_debug("[%s] cannot read check string \'%s\'", backup_str, str);
        return 0;
    }
    if (ods_strcmp(p, str) != 0) {
        ods_log_debug("[%s] \'%s\' does not match \'%s\'", backup_str, p, str);
        return 0;
    }
    return 1;
}
コード例 #5
0
ファイル: keys.c プロジェクト: opendnssec/opendnssec
/**
 * Lookup a key in the key list by locator.
 *
 */
key_type*
keylist_lookup_by_locator(keylist_type* kl, const char* locator)
{
    uint16_t i = 0;
    if (!kl || !locator || kl->count <= 0) {
        return NULL;
    }
    for (i=0; i < kl->count; i++) {
        if (&kl->keys[i] && kl->keys[i].locator) {
            if (ods_strcmp(kl->keys[i].locator, locator) == 0) {
                return &kl->keys[i];
            }
        }
    }
    return NULL;
}
コード例 #6
0
ファイル: ods-enforcer.c プロジェクト: bbczeuz/opendnssec
/**
 * Interface.
 *
 */
static int
interface_run(FILE* fp, int sockfd, char* cmd)
{
    int maxfdp1 = 0;
    int stdineof = 0;
    int i = 0;
    int n = 0;
    int ret = 0;
    int cmd_written = 0;
    int cmd_response = 0;
    fd_set rset;
    char buf[ODS_SE_MAXLINE];
    int written;

    stdineof = 0;
    FD_ZERO(&rset);
    for(;;) {
        /* prepare */
        if (stdineof == 0) {
            FD_SET(fileno(fp), &rset);
        }
        FD_SET(sockfd, &rset);
        maxfdp1 = max(fileno(fp), sockfd) + 1;

        if (!cmd || cmd_written) {
            /* interactive mode */
            ret = select(maxfdp1, &rset, NULL, NULL, NULL);
            if (ret < 0) {
                if (errno != EINTR && errno != EWOULDBLOCK) {
                    ods_log_warning("[%s] interface select error: %s",
                        cli_str, strerror(errno));
                }
                continue;
            }
        } else if (cmd) {
            /* passive mode */
            ods_writen(sockfd, cmd, strlen(cmd));
            cmd_written = 1;
            stdineof = 1;
            /* Clear the interactive mode / stdin fd from the set */
            FD_CLR(fileno(fp), &rset);
            continue;
        }

        if (cmd && cmd_written && cmd_response) {
            /* normal termination */
            return 0;
        }

        if (FD_ISSET(sockfd, &rset)) {
            /* clear buffer */
            for (i=0; i < ODS_SE_MAXLINE; i++) {
                buf[i] = 0;
            }
            buf[ODS_SE_MAXLINE-1] = '\0';

            /* socket is readable */
            if ((n = read(sockfd, buf, ODS_SE_MAXLINE)) <= 0) {
                if (n < 0) {
                    /* error occurred */
                    fprintf(stderr, "error: %s\n", strerror(errno));
                    return 1;
                } else {
                    /* n==0 */
                    if (stdineof == 1) {
                        /* normal termination */
                        return 0;
                    } else {
                        /* weird termination */
                        fprintf(stderr, "enforcer engine terminated "
                                "prematurely\n");
                        return 1;
                    }
                }
            }

            if (cmd) {
                if (n < SE_CLI_CMDLEN) {
                    /* not enough data received */
                    fprintf(stderr, "not enough response data received "
                            "from daemon.\n");
                    return 1;
                }
                
                /* n >= SE_CLI_CMDLEN : and so it is safe to do buffer 
                    manipulations below. */
                if (strncmp(buf+n-SE_CLI_CMDLEN,"\ncmd> ",SE_CLI_CMDLEN) == 0) {
                
                    /* we have the full response */
                    n -= SE_CLI_CMDLEN;
                    buf[n] = '\0';
                    cmd_response = 1;
                }
            }

            /* n > 0 : when we get to this line... */
            for (written=0; written < n; written += ret) {
                /* write what we got to stdout */
                ret = (int) write(fileno(stdout), &buf[written], n-written);
                /* error and shutdown handling */
                if (ret == 0) {
                    fprintf(stderr, "no write\n");
                    break;
                }
                if (ret < 0) {
                    if (errno == EINTR || errno == EWOULDBLOCK) {
                        ret = 0;
                        continue; /* try again... */
                    }
                    fprintf(stderr, "\n\nwrite error: %s\n", strerror(errno));
                    break;
                }
                /* ret > 0 : when we get here... */
                if (written+ret > n) {
                    fprintf(stderr, "\n\nwrite error: more bytes (%d) written than required (%d)\n", written+ret, n);
                    break;
                }
                /* written+ret < n : means partial write, requires us to loop... */
            }
            if (ods_strcmp(buf, ODS_SE_STOP_RESPONSE) == 0 ) {
                /* we do no further reading, flush */
                write(fileno(stdout), "\n", 1);
                return 0;
            } else if (cmd_response) return 0;
        }

        if (FD_ISSET(fileno(fp), &rset)) {
            /* input is readable */

            if (cmd && cmd_written) {
                /* passive mode */
                stdineof = 1;
                ret = shutdown(sockfd, SHUT_WR);
                if (ret != 0) {
                    fprintf(stderr, "shutdown failed: %s\n",
                        strerror(errno));
                    return 1;
                }
                FD_CLR(fileno(fp), &rset);
                continue;
            }

            /* clear buffer */
            for (i=0; i< ODS_SE_MAXLINE; i++) {
                buf[i] = 0;
            }

            /* interactive mode */
            if ((n = read(fileno(fp), buf, ODS_SE_MAXLINE)) == 0) {
                stdineof = 1;
                ret = shutdown(sockfd, SHUT_WR);
                if (ret != 0) {
                    fprintf(stderr, "shutdown failed: %s\n",
                        strerror(errno));
                    return 1;
                }
                FD_CLR(fileno(fp), &rset);
                continue;
            }
            if (strncmp(buf, "exit", 4) == 0 ||
                strncmp(buf, "quit", 4) == 0) {
                return 0;
            }
            ods_str_trim(buf);
            n = strlen(buf);
            ods_writen(sockfd, buf, n);
        }
    }
}
コード例 #7
0
ファイル: ods-enforcer.c プロジェクト: bbczeuz/opendnssec
/**
 * Start interface
 *
 */
static int
interface_start(char* cmd)
{
    int sockfd, ret, flags;
    struct sockaddr_un servaddr;
    const char* servsock_filename = OPENDNSSEC_ENFORCER_SOCKETFILE;

    ods_log_init(NULL, 0, 0);

    /* new socket */
    sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (sockfd <= 0) {
        fprintf(stderr, "Unable to connect to engine. "
            "socket() failed: %s\n", strerror(errno));
        return 1;
    }

    /* no suprises */
    bzero(&servaddr, sizeof(servaddr));
    servaddr.sun_family = AF_UNIX;
    strncpy(servaddr.sun_path, servsock_filename,
        sizeof(servaddr.sun_path) - 1);

    /* connect */
    ret = connect(sockfd, (const struct sockaddr*) &servaddr,
        sizeof(servaddr));
    if (ret != 0) {
        if (cmd && ods_strcmp(cmd, "start\n") == 0) {
            return system(ODS_EN_ENGINE);
        }

        if (cmd && ods_strcmp(cmd, "running\n") == 0) {
            fprintf(stderr, "Engine not running.\n");
        } else {
            fprintf(stderr, "Unable to connect to engine: "
                "connect() failed: %s\n", strerror(errno));
        }

        close(sockfd);
        return 1;
    }

    /* set socket to non-blocking */
    flags = fcntl(sockfd, F_GETFL, 0);
    if (flags < 0) {
        ods_log_error("[%s] unable to start interface, fcntl(F_GETFL) "
            "failed: %s", cli_str, strerror(errno));
        close(sockfd);
        return 1;
    }
    flags |= O_NONBLOCK;
    if (fcntl(sockfd, F_SETFL, flags) < 0) {
        ods_log_error("[%s] unable to start interface, fcntl(F_SETFL) "
            "failed: %s", cli_str, strerror(errno));
        close(sockfd);
        return 1;
    }

    /* some sort of interface */
    if (!cmd) {
        fprintf(stderr, "cmd> ");
    }

    /* run */
    ret = interface_run(stdin, sockfd, cmd);
    close(sockfd);
    return ret;
}
コード例 #8
0
/**
 * Recover zone from backup.
 *
 */
ods_status
zone_recover2(zone_type* zone)
{
    char* filename = NULL;
    FILE* fd = NULL;
    const char* token = NULL;
    time_t when = 0;
    task_type* task = NULL;
    ods_status status = ODS_STATUS_OK;
    /* zone part */
    int klass = 0;
    uint32_t inbound = 0, internal = 0, outbound = 0;
    /* signconf part */
    time_t lastmod = 0;
    /* nsec3params part */
    const char* salt = NULL;

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

    filename = ods_build_path(zone->name, ".backup2", 0, 1);
    if (!filename) {
        return ODS_STATUS_MALLOC_ERR;
    }
    fd = ods_fopen(filename, NULL, "r");
    if (fd) {
        /* start recovery */
        if (!backup_read_check_str(fd, ODS_SE_FILE_MAGIC_V3)) {
            ods_log_error("[%s] corrupted backup file zone %s: read magic "
                "error", zone_str, zone->name);
            goto recover_error2;
        }
        if (!backup_read_check_str(fd, ";;Time:") |
            !backup_read_time_t(fd, &when)) {
            ods_log_error("[%s] corrupted backup file zone %s: read time "
                "error", zone_str, zone->name);
            goto recover_error2;
        }
        /* zone stuff */
        if (!backup_read_check_str(fd, ";;Zone:") |
            !backup_read_check_str(fd, "name") |
            !backup_read_check_str(fd, zone->name)) {
            ods_log_error("[%s] corrupted backup file zone %s: read name "
                "error", zone_str, zone->name);
            goto recover_error2;
        }
        if (!backup_read_check_str(fd, "class") |
            !backup_read_int(fd, &klass)) {
            ods_log_error("[%s] corrupted backup file zone %s: read class "
                "error", zone_str, zone->name);
            goto recover_error2;
        }
        if (!backup_read_check_str(fd, "inbound") |
            !backup_read_uint32_t(fd, &inbound) |
            !backup_read_check_str(fd, "internal") |
            !backup_read_uint32_t(fd, &internal) |
            !backup_read_check_str(fd, "outbound") |
            !backup_read_uint32_t(fd, &outbound)) {
            ods_log_error("[%s] corrupted backup file zone %s: read serial "
                "error", zone_str, zone->name);
            goto recover_error2;
        }
        zone->klass = (ldns_rr_class) klass;
        zone->db->inbserial = inbound;
        zone->db->intserial = internal;
        zone->db->outserial = outbound;
        /* signconf part */
        if (!backup_read_check_str(fd, ";;Signconf:") |
            !backup_read_check_str(fd, "lastmod") |
            !backup_read_time_t(fd, &lastmod) |
            !backup_read_check_str(fd, "maxzonettl") |
            !backup_read_check_str(fd, "0") |
            !backup_read_check_str(fd, "resign") |
            !backup_read_duration(fd, &zone->signconf->sig_resign_interval) |
            !backup_read_check_str(fd, "refresh") |
            !backup_read_duration(fd, &zone->signconf->sig_refresh_interval) |
            !backup_read_check_str(fd, "valid") |
            !backup_read_duration(fd, &zone->signconf->sig_validity_default) |
            !backup_read_check_str(fd, "denial") |
            !backup_read_duration(fd,&zone->signconf->sig_validity_denial) |
            !backup_read_check_str(fd, "jitter") |
            !backup_read_duration(fd, &zone->signconf->sig_jitter) |
            !backup_read_check_str(fd, "offset") |
            !backup_read_duration(fd, &zone->signconf->sig_inception_offset) |
            !backup_read_check_str(fd, "nsec") |
            !backup_read_rr_type(fd, &zone->signconf->nsec_type) |
            !backup_read_check_str(fd, "dnskeyttl") |
            !backup_read_duration(fd, &zone->signconf->dnskey_ttl) |
            !backup_read_check_str(fd, "soattl") |
            !backup_read_duration(fd, &zone->signconf->soa_ttl) |
            !backup_read_check_str(fd, "soamin") |
            !backup_read_duration(fd, &zone->signconf->soa_min) |
            !backup_read_check_str(fd, "serial") |
            !backup_read_str(fd, &zone->signconf->soa_serial)) {
            ods_log_error("[%s] corrupted backup file zone %s: read signconf "
                "error", zone_str, zone->name);
            goto recover_error2;
        }
        /* nsec3params part */
        if (zone->signconf->nsec_type == LDNS_RR_TYPE_NSEC3) {
            if (!backup_read_check_str(fd, ";;Nsec3parameters:") |
                !backup_read_check_str(fd, "salt") |
                !backup_read_str(fd, &salt) |
                !backup_read_check_str(fd, "algorithm") |
                !backup_read_uint32_t(fd, &zone->signconf->nsec3_algo) |
                !backup_read_check_str(fd, "optout") |
                !backup_read_int(fd, &zone->signconf->nsec3_optout) |
                !backup_read_check_str(fd, "iterations") |
                !backup_read_uint32_t(fd, &zone->signconf->nsec3_iterations)) {
                ods_log_error("[%s] corrupted backup file zone %s: read "
                    "nsec3parameters error", zone_str, zone->name);
                goto recover_error2;
            }
            zone->signconf->nsec3_salt = allocator_strdup(
                zone->signconf->allocator, salt);
            free((void*) salt);
            salt = NULL;
            zone->signconf->nsec3params = nsec3params_create(
                (void*) zone->signconf,
                (uint8_t) zone->signconf->nsec3_algo,
                (uint8_t) zone->signconf->nsec3_optout,
                (uint16_t) zone->signconf->nsec3_iterations,
                zone->signconf->nsec3_salt);
            if (!zone->signconf->nsec3params) {
                ods_log_error("[%s] corrupted backup file zone %s: unable to "
                    "create nsec3param", zone_str, zone->name);
                goto recover_error2;
            }
        }
        zone->signconf->last_modified = lastmod;
        zone->default_ttl = (uint32_t) duration2time(zone->signconf->soa_min);
        /* keys part */
        zone->signconf->keys = keylist_create((void*) zone->signconf);
        while (backup_read_str(fd, &token)) {
            if (ods_strcmp(token, ";;Key:") == 0) {
                if (!key_recover2(fd, zone->signconf->keys)) {
                    ods_log_error("[%s] corrupted backup file zone %s: read "
                        "key error", zone_str, zone->name);
                    goto recover_error2;
                }
            } else if (ods_strcmp(token, ";;") == 0) {
                /* keylist done */
                free((void*) token);
                token = NULL;
                break;
            } else {
                /* keylist corrupted */
                goto recover_error2;
            }
            free((void*) token);
            token = NULL;
        }
        /* publish dnskeys */
        status = zone_publish_dnskeys(zone);
        if (status != ODS_STATUS_OK) {
            ods_log_error("[%s] corrupted backup file zone %s: unable to "
                "publish dnskeys (%s)", zone_str, zone->name,
                ods_status2str(status));
            goto recover_error2;
        }
        /* publish nsec3param */
        status = zone_publish_nsec3param(zone);
        if (status != ODS_STATUS_OK) {
            ods_log_error("[%s] corrupted backup file zone %s: unable to "
                "publish nsec3param (%s)", zone_str, zone->name,
                ods_status2str(status));
            goto recover_error2;
        }
        /* publish other records */
        status = backup_read_namedb(fd, zone);
        if (status != ODS_STATUS_OK) {
            ods_log_error("[%s] corrupted backup file zone %s: unable to "
                "read resource records (%s)", zone_str, zone->name,
                ods_status2str(status));
            goto recover_error2;
        }
        /* task */
        task = task_create(TASK_SIGN, when, (void*) zone);
        if (!task) {
            ods_log_error("[%s] failed to restore zone %s: unable to "
                "create task", zone_str, zone->name);
            goto recover_error2;
        }
        zone->task = (void*) task;
        free((void*)filename);
        ods_fclose(fd);
        /* journal */
        zone->db->is_initialized = 1;

        filename = ods_build_path(zone->name, ".ixfr", 0, 1);
        if (filename) {
            fd = ods_fopen(filename, NULL, "r");
        }
        if (fd) {
            status = backup_read_ixfr(fd, zone);
            if (status != ODS_STATUS_OK) {
                ods_log_warning("[%s] corrupted journal file zone %s, "
                    "skipping (%s)", zone_str, zone->name,
                    ods_status2str(status));
                ixfr_cleanup(zone->ixfr);
                zone->ixfr = ixfr_create((void*)zone);
            }
        }
        lock_basic_lock(&zone->ixfr->ixfr_lock);
        ixfr_purge(zone->ixfr);
        lock_basic_unlock(&zone->ixfr->ixfr_lock);

        /* all ok */
        free((void*)filename);
        ods_fclose(fd);
        if (zone->stats) {
            lock_basic_lock(&zone->stats->stats_lock);
            stats_clear(zone->stats);
            lock_basic_unlock(&zone->stats->stats_lock);
        }
        return ODS_STATUS_OK;
    }
    return ODS_STATUS_UNCHANGED;

recover_error2:
    free((void*)filename);
    ods_fclose(fd);
    /* signconf cleanup */
    free((void*)salt);
    salt = NULL;
    signconf_cleanup(zone->signconf);
    zone->signconf = signconf_create();
    ods_log_assert(zone->signconf);
    /* namedb cleanup */
    namedb_cleanup(zone->db);
    zone->db = namedb_create((void*)zone);
    ods_log_assert(zone->db);
    /* stats reset */
    if (zone->stats) {
       lock_basic_lock(&zone->stats->stats_lock);
       stats_clear(zone->stats);
       lock_basic_unlock(&zone->stats->stats_lock);
    }
    return ODS_STATUS_ERR;
}