static void config_free(struct config *conf) { void *value; config_reset(conf); while (dict_poproot(&conf->conf, &value)) free(value); while (dict_poproot(&conf->sources, NULL)) ; free(conf); }
static int table_static_update(struct table *table) { struct table *t; void *p = NULL; /* no config ? ok */ if (table->t_config[0] == '\0') goto ok; t = table_create("static", table->t_name, "update", table->t_config); if (!table_config(t)) goto err; /* replace former table, frees t */ while (dict_poproot(&table->t_dict, NULL, (void **)&p)) free(p); dict_merge(&table->t_dict, &t->t_dict); table_destroy(t); ok: log_info("info: Table \"%s\" successfully updated", table->t_name); return 1; err: table_destroy(t); log_info("info: Failed to update table \"%s\"", table->t_name); return 0; }
void m_clear_params(struct dict *d) { char *value; while (dict_poproot(d, (void **)&value)) free(value); }
static int table_sqlite_fetch(int service, char *dst, size_t sz) { const char *k; int s; if (service != K_SOURCE) return (-1); if (stmt_fetch_source == NULL) return (-1); if (source_ncall < source_refresh && time(NULL) - source_update < source_expire) goto fetch; source_iter = NULL; while (dict_poproot(&sources, NULL)) ; while ((s = sqlite3_step(stmt_fetch_source)) == SQLITE_ROW) dict_set(&sources, sqlite3_column_text(stmt_fetch_source, 0), NULL); if (s != SQLITE_DONE) log_warnx("warn: table-sqlite: sqlite3_step: %s", sqlite3_errmsg(db)); sqlite3_reset(stmt_fetch_source); source_update = time(NULL); source_ncall = 0; fetch: source_ncall += 1; if (! dict_iter(&sources, &source_iter, &k, (void **)NULL)) { source_iter = NULL; if (! dict_iter(&sources, &source_iter, &k, (void **)NULL)) return (0); } if (strlcpy(dst, k, sz) >= sz) return (-1); return (1); }
static int table_passwd_update(void) { FILE *fp; char *buf, *lbuf = NULL; size_t len; char *line; struct passwd pw; struct dict *npasswd; /* Parse configuration */ fp = fopen(config, "r"); if (fp == NULL) return (0); npasswd = calloc(1, sizeof *passwd); if (npasswd == NULL) goto err; dict_init(npasswd); while ((buf = fgetln(fp, &len))) { if (buf[len - 1] == '\n') buf[len - 1] = '\0'; else { /* EOF without EOL, copy and add the NUL */ if ((lbuf = malloc(len + 1)) == NULL) err(1, NULL); memcpy(lbuf, buf, len); lbuf[len] = '\0'; buf = lbuf; } if (! parse_passwd_entry(&pw, buf)) { log_warnx("warn: table-passwd: invalid entry"); goto err; } if ((line = strdup(buf)) == NULL) err(1, NULL); dict_set(npasswd, pw.pw_name, line); } free(lbuf); fclose(fp); /* swap passwd table and release old one*/ if (passwd) while (dict_poproot(passwd, (void**)&buf)) free(buf); passwd = npasswd; return (1); err: if (fp) fclose(fp); free(lbuf); /* release passwd table */ if (npasswd) { while (dict_poproot(npasswd, (void**)&buf)) free(buf); free(npasswd); } return (0); }
static int table_postgres_fetch(int service, char *dst, size_t sz) { char *stmt; PGresult *res; const char *k, *errfld; int i; if (config->db == NULL && config_connect(config) == 0) return (-1); retry: if (service != K_SOURCE) return (-1); stmt = config->stmt_fetch_source; if (stmt == NULL) return (-1); if (config->source_ncall < config->source_refresh && time(NULL) - config->source_update < config->source_expire) goto fetch; res = PQexecPrepared(config->db, stmt, 0, NULL, NULL, NULL, 0); if (PQresultStatus(res) != PGRES_TUPLES_OK) { errfld = PQresultErrorField(res, PG_DIAG_SQLSTATE); if (errfld[0] == '0' && errfld[1] == '8') { log_warnx("warn: table-postgres: trying to reconnect after error: %s", PQerrorMessage(config->db)); PQclear(res); if (config_connect(config)) goto retry; return (-1); } log_warnx("warn: table-postgres: PQexecPrepared: %s", PQerrorMessage(config->db)); PQclear(res); return (-1); } config->source_iter = NULL; while (dict_poproot(&config->sources, NULL)) ; for (i = 0; i < PQntuples(res); i++) dict_set(&config->sources, PQgetvalue(res, i, 0), NULL); PQclear(res); config->source_update = time(NULL); config->source_ncall = 0; fetch: config->source_ncall += 1; if (! dict_iter(&config->sources, &config->source_iter, &k, (void **)NULL)) { config->source_iter = NULL; if (! dict_iter(&config->sources, &config->source_iter, &k, (void **)NULL)) return (0); } if (strlcpy(dst, k, sz) >= sz) return (-1); return (1); }
static int table_mysql_fetch(int service, char *dst, size_t sz) { MYSQL_STMT *stmt; const char *k; int s; retry: if (service != K_SOURCE) return (-1); stmt = config->stmt_fetch_source; if (stmt == NULL) return (-1); if (config->source_ncall < config->source_refresh && time(NULL) - config->source_update < config->source_expire) goto fetch; if (mysql_stmt_execute(stmt)) { if (mysql_stmt_errno(stmt) == CR_SERVER_LOST || mysql_stmt_errno(stmt) == CR_SERVER_GONE_ERROR || mysql_stmt_errno(stmt) == CR_COMMANDS_OUT_OF_SYNC) { log_warnx("warn: table-mysql: trying to reconnect after error: %s", mysql_stmt_error(stmt)); if (config_connect(config)) goto retry; return (-1); } log_warnx("warn: table-mysql: mysql_stmt_execute: %s", mysql_stmt_error(stmt)); return (-1); } config->source_iter = NULL; while(dict_poproot(&config->sources, NULL, NULL)) ; while ((s = mysql_stmt_fetch(stmt)) == 0) dict_set(&config->sources, results_buffer[0], NULL); if (s && s != MYSQL_NO_DATA) log_warnx("warn: table-mysql: mysql_stmt_fetch: %s", mysql_stmt_error(stmt)); if (mysql_stmt_free_result(stmt)) log_warnx("warn: table-mysql: mysql_stmt_free_result: %s", mysql_stmt_error(stmt)); config->source_update = time(NULL); config->source_ncall = 0; fetch: config->source_ncall += 1; if (! dict_iter(&config->sources, &config->source_iter, &k, (void **)NULL)) { config->source_iter = NULL; if (! dict_iter(&config->sources, &config->source_iter, &k, (void **)NULL)) return (0); } if (strlcpy(dst, k, sz) >= sz) return (-1); return (1); }
void purge_config(uint8_t what) { struct listener *l; struct table *t; struct rule *r; struct pki *p; const char *k; void *iter_dict; if (what & PURGE_LISTENERS) { while ((l = TAILQ_FIRST(env->sc_listeners)) != NULL) { TAILQ_REMOVE(env->sc_listeners, l, entry); free(l); } free(env->sc_listeners); env->sc_listeners = NULL; } if (what & PURGE_TABLES) { while (dict_root(env->sc_tables_dict, NULL, (void **)&t)) table_destroy(t); free(env->sc_tables_dict); env->sc_tables_dict = NULL; } if (what & PURGE_RULES) { while ((r = TAILQ_FIRST(env->sc_rules)) != NULL) { TAILQ_REMOVE(env->sc_rules, r, r_entry); free(r); } free(env->sc_rules); env->sc_rules = NULL; } if (what & PURGE_PKI) { while (dict_poproot(env->sc_pki_dict, (void **)&p)) { explicit_bzero(p->pki_cert, p->pki_cert_len); free(p->pki_cert); if (p->pki_key) { explicit_bzero(p->pki_key, p->pki_key_len); free(p->pki_key); } if (p->pki_pkey) EVP_PKEY_free(p->pki_pkey); free(p); } free(env->sc_pki_dict); env->sc_pki_dict = NULL; } else if (what & PURGE_PKI_KEYS) { iter_dict = NULL; while (dict_iter(env->sc_pki_dict, &iter_dict, &k, (void **)&p)) { explicit_bzero(p->pki_cert, p->pki_cert_len); free(p->pki_cert); p->pki_cert = NULL; if (p->pki_key) { explicit_bzero(p->pki_key, p->pki_key_len); free(p->pki_key); p->pki_key = NULL; } if (p->pki_pkey) EVP_PKEY_free(p->pki_pkey); p->pki_pkey = NULL; } } }
static void table_clear_params(struct dict *params) { while (dict_poproot(params, NULL)) ; }
static int table_passwd_update(void) { FILE *fp; char *buf, *lbuf = NULL; char tmp[LINE_MAX]; size_t len; char *line; struct passwd pw; struct dict *npasswd; char *skip; /* Parse configuration */ fp = fopen(config, "r"); if (fp == NULL) return (0); npasswd = calloc(1, sizeof *passwd); if (npasswd == NULL) goto err; dict_init(npasswd); while ((buf = fgetln(fp, &len))) { if (buf[len - 1] == '\n') buf[len - 1] = '\0'; else { /* EOF without EOL, copy and add the NUL */ if ((lbuf = malloc(len + 1)) == NULL) err(1, NULL); memcpy(lbuf, buf, len); lbuf[len] = '\0'; buf = lbuf; } /* skip commented entries */ for (skip = buf; *skip; ++skip) if (*skip == '#') { *skip = '\0'; break; } /* skip empty lines */ if (strlen(buf) == 0) continue; if (strlcpy(tmp, buf, sizeof tmp) >= sizeof tmp) { log_warnx("warn: table-passwd: line too long"); goto err; } if (! parse_passwd_entry(&pw, tmp)) { log_warnx("warn: table-passwd: invalid entry"); goto err; } if ((line = strdup(buf)) == NULL) err(1, NULL); dict_set(npasswd, pw.pw_name, line); } free(lbuf); fclose(fp); /* swap passwd table and release old one*/ if (passwd) while (dict_poproot(passwd, (void**)&buf)) free(buf); passwd = npasswd; return (1); err: if (fp) fclose(fp); free(lbuf); /* release passwd table */ if (npasswd) { while (dict_poproot(npasswd, (void**)&buf)) free(buf); free(npasswd); } return (0); }