mirror of https://github.com/yandex/odyssey.git
Add HBA config file support, add hba reload logic. (#442)
Add HBA config file support, add hba reload logic. Currently supported: local/host/hostssl/hostnossl IPv4/IPv6 address ranges rules reload on receiving SIGHUP simple tests What to improve: default db/user @<file> support in db/user fields ? set auth method for each hba rule ? replace rw_lock with coroutine synchronization ? make parser kind of configurable Authored-by: Alexander Belev <belyov97@gmail.com> Co-authored-by: Dmitry Vasiliev <dmitrivasilyev@ozon.ru>
This commit is contained in:
parent
7a769c50dd
commit
f9a1ec21bc
|
@ -62,6 +62,7 @@ COPY ./docker/prep_stmts/pstmts.conf /etc/odyssey/pstmts.conf
|
|||
COPY --from=base /ody-integration-test/pkg/ody-integration-test /ody-integration-test
|
||||
COPY --from=base /prep_stmts/pkg/pstmts-test /pstmts-test
|
||||
COPY ./docker/scram /scram
|
||||
COPY ./docker/hba /hba
|
||||
COPY ./docker/auth_query /auth_query
|
||||
COPY ./docker/ldap /ldap
|
||||
COPY ./docker/lagpolling /lagpolling
|
||||
|
|
|
@ -24,6 +24,8 @@ local all postgres trust
|
|||
host postgres user1 127.0.0.1/32 trust
|
||||
host db1 user1 127.0.0.1/32 trust
|
||||
host all postgres 127.0.0.1/32 trust
|
||||
host all user_allow 127.0.0.1/32 trust
|
||||
host all user_reject 127.0.0.1/32 trust
|
||||
EOF
|
||||
|
||||
sed -i 's/max_connections = 100/max_connections = 2000/g' /etc/postgresql/14/main/postgresql.conf
|
||||
|
@ -36,7 +38,7 @@ if ! /usr/bin/pg_ctlcluster 14 main start && psql -h localhost -p 5432 -U postgr
|
|||
fi
|
||||
|
||||
# Create databases
|
||||
for database_name in db scram_db ldap_db auth_query_db db1; do
|
||||
for database_name in db scram_db ldap_db auth_query_db db1 hba_db; do
|
||||
sudo -u postgres createdb $database_name >> "$SETUP_LOG" 2>&1 || {
|
||||
echo "ERROR: 'createdb $database_name' failed, examine the log"
|
||||
cat "$SETUP_LOG"
|
||||
|
@ -102,6 +104,14 @@ psql -h localhost -p 5432 -U user1 -d db1 -c "CREATE SCHEMA sh1" >> $SETUP_LOG 2
|
|||
exit 1
|
||||
}
|
||||
|
||||
# Create users
|
||||
psql -h localhost -p 5432 -U postgres -c "create user user_allow password 'correct_password'; create user user_reject password 'correct_password'; create user user_unknown password 'correct_password';" >> $SETUP_LOG 2>&1 || {
|
||||
echo "ERROR: users creation failed, examine the log"
|
||||
cat "$SETUP_LOG"
|
||||
cat "$PG_LOG"
|
||||
exit 1
|
||||
}
|
||||
|
||||
for i in `seq 0 9`
|
||||
do
|
||||
# Create users
|
||||
|
|
|
@ -20,8 +20,6 @@ then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
ody-stop
|
||||
|
||||
# auth query
|
||||
/auth_query/test_auth_query.sh
|
||||
if [ $? -eq 1 ]
|
||||
|
@ -29,8 +27,16 @@ then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
# odyssey hba test
|
||||
/hba/test.sh
|
||||
if [ $? -eq 1 ]
|
||||
then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#prepared statements in transaction pooling
|
||||
/usr/bin/odyssey /etc/odyssey/pstmts.conf
|
||||
sleep 1
|
||||
/pstmts-test
|
||||
|
||||
ody-stop
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
storage "postgres_server" {
|
||||
type "remote"
|
||||
host "127.0.0.1"
|
||||
port 5432
|
||||
}
|
||||
|
||||
database "hba_db" {
|
||||
user "user_allow" {
|
||||
authentication "clear_text"
|
||||
password "correct_password"
|
||||
|
||||
storage "postgres_server"
|
||||
storage_db "hba_db"
|
||||
|
||||
pool "session"
|
||||
}
|
||||
|
||||
user "user_reject" {
|
||||
authentication "clear_text"
|
||||
password "correct_password"
|
||||
|
||||
storage "postgres_server"
|
||||
storage_db "hba_db"
|
||||
|
||||
pool "session"
|
||||
}
|
||||
|
||||
user "user_unknown" {
|
||||
authentication "clear_text"
|
||||
password "correct_password"
|
||||
|
||||
storage "postgres_server"
|
||||
storage_db "hba_db"
|
||||
|
||||
pool "session"
|
||||
}
|
||||
}
|
||||
|
||||
daemonize yes
|
||||
pid_file "/var/run/odyssey.pid"
|
||||
|
||||
unix_socket_dir "/tmp"
|
||||
unix_socket_mode "0644"
|
||||
|
||||
locks_dir "/tmp"
|
||||
|
||||
log_format "%p %t %l [%i %s] (%c) %m\n"
|
||||
log_file "/var/log/odyssey.log"
|
||||
log_to_stdout no
|
||||
log_config yes
|
||||
log_debug yes
|
||||
log_session yes
|
||||
log_stats no
|
||||
log_query yes
|
||||
|
||||
hba_file "/hba/odyssey_hba.conf"
|
|
@ -0,0 +1,4 @@
|
|||
local hba_db user_allow allow
|
||||
local hba_db user_reject deny
|
||||
host hba_db user_allow 127.0.0.0/24 allow
|
||||
host hba_db user_reject 127.0.0.0/24 deny
|
|
@ -0,0 +1,6 @@
|
|||
include "/hba/common.conf"
|
||||
|
||||
listen {
|
||||
host "*"
|
||||
port 6432
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
#!/bin/bash -x
|
||||
|
||||
set -ex
|
||||
|
||||
#
|
||||
# TCP
|
||||
#
|
||||
|
||||
/usr/bin/odyssey /hba/tcp.conf
|
||||
|
||||
PGPASSWORD=correct_password psql -h localhost -p 6432 -U user_allow -c "SELECT 1" hba_db > /dev/null 2>&1 || {
|
||||
echo "ERROR: failed auth with hba trust, correct password and plain password in config"
|
||||
|
||||
cat /var/log/odyssey.log
|
||||
echo "
|
||||
|
||||
"
|
||||
cat /var/log/postgresql/postgresql-14-main.log
|
||||
|
||||
exit 1
|
||||
}
|
||||
|
||||
PGPASSWORD=incorrect_password psql -h localhost -p 6432 -U user_allow -c "SELECT 1" hba_db > /dev/null 2>&1 && {
|
||||
echo "ERROR: successfully auth with hba trust, but incorrect password"
|
||||
|
||||
cat /var/log/odyssey.log
|
||||
echo "
|
||||
|
||||
"
|
||||
cat /var/log/postgresql/postgresql-14-main.log
|
||||
|
||||
exit 1
|
||||
}
|
||||
|
||||
PGPASSWORD=correct_password psql -h localhost -p 6432 -U user_reject -c "SELECT 1" hba_db > /dev/null 2>&1 && {
|
||||
echo "ERROR: successfully auth with hba reject"
|
||||
|
||||
cat /var/log/odyssey.log
|
||||
echo "
|
||||
|
||||
"
|
||||
cat /var/log/postgresql/postgresql-14-main.log
|
||||
|
||||
exit 1
|
||||
}
|
||||
|
||||
PGPASSWORD=correct_password psql -h localhost -p 6432 -U user_unknown -c "SELECT 1" hba_db > /dev/null 2>&1 && {
|
||||
echo "ERROR: successfully auth without hba rule"
|
||||
|
||||
cat /var/log/odyssey.log
|
||||
echo "
|
||||
|
||||
"
|
||||
cat /var/log/postgresql/postgresql-14-main.log
|
||||
|
||||
exit 1
|
||||
}
|
||||
|
||||
ody-stop
|
||||
|
||||
#
|
||||
# Unix
|
||||
#
|
||||
|
||||
/usr/bin/odyssey /hba/unix.conf
|
||||
|
||||
PGPASSWORD=correct_password psql -h /tmp -p 6432 -U user_allow -c "SELECT 1" hba_db > /dev/null 2>&1 || {
|
||||
echo "ERROR: failed auth with hba trust, correct password and plain password in config"
|
||||
|
||||
cat /var/log/odyssey.log
|
||||
echo "
|
||||
|
||||
"
|
||||
cat /var/log/postgresql/postgresql-14-main.log
|
||||
|
||||
exit 1
|
||||
}
|
||||
|
||||
PGPASSWORD=correct_password psql -h /tmp -p 6432 -U user_reject -c "SELECT 1" hba_db > /dev/null 2>&1 && {
|
||||
echo "ERROR: successfully auth with hba reject"
|
||||
|
||||
cat /var/log/odyssey.log
|
||||
echo "
|
||||
|
||||
"
|
||||
cat /var/log/postgresql/postgresql-14-main.log
|
||||
|
||||
exit 1
|
||||
}
|
||||
|
||||
ody-stop
|
|
@ -0,0 +1,5 @@
|
|||
include "/hba/common.conf"
|
||||
|
||||
listen {
|
||||
port 6432
|
||||
}
|
|
@ -258,6 +258,21 @@ reply with 'too many connections'.
|
|||
|
||||
`client_max 100`
|
||||
|
||||
#### hba\_file *string*
|
||||
|
||||
Path to file containing host based authentication rules.
|
||||
Omit this option to disable HBA.
|
||||
|
||||
`hba_file "path"`
|
||||
|
||||
HBA file format follows the format of the PostgreSQL `pg_hba.conf` file.
|
||||
* Supported record types: `local`, `host`, `hostssl`, `hostnossl`.
|
||||
* Database field: `all`, `sameuser`, multiple names.
|
||||
* User field: `all`, multiple names.
|
||||
* Address field: IPv4 or IPv6 range.
|
||||
* Auth-method field: `deny` or `reject` (equivalent keywords), which leads to immediate disconnection,
|
||||
`allow` or `trust` (also equivalent keywords), which means applying auth method specified in matching route.
|
||||
|
||||
### Listen
|
||||
|
||||
Listen section defines listening servers used for accepting
|
||||
|
|
|
@ -46,7 +46,10 @@ set(od_src
|
|||
query.c
|
||||
storage.c
|
||||
murmurhash.c
|
||||
hashmap.c)
|
||||
hashmap.c
|
||||
hba.c
|
||||
hba_reader.c
|
||||
hba_rule.c)
|
||||
|
||||
if (PAM_FOUND)
|
||||
list(APPEND od_src pam.c)
|
||||
|
|
|
@ -54,6 +54,7 @@ void od_config_init(od_config_t *config)
|
|||
config->cache_coroutine = 0;
|
||||
config->cache_msg_gc_size = 0;
|
||||
config->coroutine_stack_size = 4;
|
||||
config->hba_file = NULL;
|
||||
od_list_init(&config->listen);
|
||||
}
|
||||
|
||||
|
@ -90,6 +91,8 @@ void od_config_free(od_config_t *config)
|
|||
free(config->log_syslog_facility);
|
||||
if (config->locks_dir) {
|
||||
free(config->locks_dir);
|
||||
if (config->hba_file)
|
||||
free(config->hba_file);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -73,6 +73,7 @@ struct od_config {
|
|||
int cache_coroutine;
|
||||
int cache_msg_gc_size;
|
||||
int coroutine_stack_size;
|
||||
char *hba_file;
|
||||
od_list_t listen;
|
||||
};
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ typedef struct {
|
|||
od_rules_t *rules;
|
||||
od_error_t *error;
|
||||
char *config_file;
|
||||
od_hba_rules_t *hba_rules;
|
||||
char *data;
|
||||
int data_size;
|
||||
} od_config_reader_t;
|
||||
|
|
|
@ -134,6 +134,7 @@ typedef enum {
|
|||
OD_LCATCHUP_TIMEOUT,
|
||||
OD_LCATCHUP_CHECKS,
|
||||
OD_LOPTIONS,
|
||||
OD_LHBA_FILE,
|
||||
} od_lexeme_t;
|
||||
|
||||
static od_keyword_t od_config_keywords[] = {
|
||||
|
@ -261,6 +262,7 @@ static od_keyword_t od_config_keywords[] = {
|
|||
od_keyword("auth_module", OD_LAUTH_MODULE),
|
||||
od_keyword("password_passthrough", OD_LAUTH_PASSWORD_PASSTHROUGH),
|
||||
od_keyword("load_module", OD_LMODULE),
|
||||
od_keyword("hba_file", OD_LHBA_FILE),
|
||||
|
||||
/* ldap */
|
||||
od_keyword("ldap_endpoint", OD_LLDAP_ENDPOINT),
|
||||
|
@ -1630,6 +1632,23 @@ error:
|
|||
return NOT_OK_RESPONSE;
|
||||
}
|
||||
|
||||
static int od_config_reader_hba_import(od_config_reader_t *config_reader)
|
||||
{
|
||||
od_config_reader_t reader;
|
||||
memset(&reader, 0, sizeof(reader));
|
||||
reader.config = config_reader->config;
|
||||
reader.error = config_reader->error;
|
||||
reader.hba_rules = config_reader->hba_rules;
|
||||
int rc;
|
||||
rc = od_config_reader_open(&reader, config_reader->config->hba_file);
|
||||
if (rc == -1)
|
||||
return -1;
|
||||
rc = od_hba_reader_parse(&reader);
|
||||
od_config_reader_close(&reader);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int od_config_reader_parse(od_config_reader_t *reader,
|
||||
od_extention_t *extentions)
|
||||
{
|
||||
|
@ -1665,7 +1684,8 @@ static int od_config_reader_parse(od_config_reader_t *reader,
|
|||
return NOT_OK_RESPONSE;
|
||||
rc = od_config_reader_import(
|
||||
reader->config, reader->rules, reader->error,
|
||||
extentions, reader->global, config_file);
|
||||
extentions, reader->global, reader->hba_rules,
|
||||
config_file);
|
||||
free(config_file);
|
||||
if (rc == -1) {
|
||||
goto error;
|
||||
|
@ -2035,6 +2055,15 @@ static int od_config_reader_parse(od_config_reader_t *reader,
|
|||
}
|
||||
continue;
|
||||
}
|
||||
case OD_LHBA_FILE: {
|
||||
rc = od_config_reader_string(reader, &config->hba_file);
|
||||
if (rc == -1)
|
||||
goto error;
|
||||
rc = od_config_reader_hba_import(reader);
|
||||
if (rc == -1)
|
||||
goto error;
|
||||
continue;
|
||||
}
|
||||
default:
|
||||
od_config_reader_error(reader, &token,
|
||||
"unexpected parameter");
|
||||
|
@ -2055,13 +2084,15 @@ success:
|
|||
|
||||
int od_config_reader_import(od_config_t *config, od_rules_t *rules,
|
||||
od_error_t *error, od_extention_t *extentions,
|
||||
od_global_t *global, char *config_file)
|
||||
od_global_t *global, od_hba_rules_t *hba_rules,
|
||||
char *config_file)
|
||||
{
|
||||
od_config_reader_t reader;
|
||||
memset(&reader, 0, sizeof(reader));
|
||||
reader.error = error;
|
||||
reader.config = config;
|
||||
reader.rules = rules;
|
||||
reader.hba_rules = hba_rules;
|
||||
reader.global = global;
|
||||
int rc;
|
||||
rc = od_config_reader_open(&reader, config_file);
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
*/
|
||||
|
||||
extern int od_config_reader_import(od_config_t *, od_rules_t *, od_error_t *,
|
||||
od_extention_t *, od_global_t *, char *);
|
||||
od_extention_t *, od_global_t *,
|
||||
od_hba_rules_t *, char *);
|
||||
|
||||
#define OD_READER_ERROR_MAX_LEN 1 << 8
|
||||
|
||||
|
|
|
@ -2125,8 +2125,16 @@ void od_frontend(void *arg)
|
|||
}
|
||||
}
|
||||
|
||||
/* HBA check */
|
||||
rc = od_hba_process(client);
|
||||
|
||||
/* client authentication */
|
||||
rc = od_auth_frontend(client);
|
||||
if (rc == OK_RESPONSE) {
|
||||
rc = od_auth_frontend(client);
|
||||
} else {
|
||||
od_frontend_error(client, KIWI_INVALID_PASSWORD,
|
||||
"host based authentication rejected");
|
||||
}
|
||||
|
||||
if (rc != OK_RESPONSE) {
|
||||
/* rc == -1
|
||||
|
|
|
@ -16,11 +16,13 @@ struct od_global {
|
|||
void *cron;
|
||||
void *worker_pool;
|
||||
void *extentions;
|
||||
void *hba;
|
||||
};
|
||||
|
||||
static inline void od_global_init(od_global_t *global, void *instance,
|
||||
void *system, void *router, void *cron,
|
||||
void *worker_pool, void *extentions)
|
||||
void *worker_pool, void *extentions,
|
||||
void *hba)
|
||||
{
|
||||
global->instance = instance;
|
||||
global->system = system;
|
||||
|
@ -28,6 +30,7 @@ static inline void od_global_init(od_global_t *global, void *instance,
|
|||
global->cron = cron;
|
||||
global->worker_pool = worker_pool;
|
||||
global->extentions = extentions;
|
||||
global->hba = hba;
|
||||
}
|
||||
|
||||
#endif /* ODYSSEY_GLOBAL_H */
|
||||
|
|
|
@ -0,0 +1,164 @@
|
|||
|
||||
/*
|
||||
* Odyssey.
|
||||
*
|
||||
* Scalable PostgreSQL connection pooler.
|
||||
*/
|
||||
|
||||
#include <odyssey.h>
|
||||
|
||||
void od_hba_init(od_hba_t *hba)
|
||||
{
|
||||
pthread_mutexattr_init(&hba->attr);
|
||||
pthread_rwlockattr_setkind_np(
|
||||
&hba->attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
|
||||
pthread_mutex_init(&hba->lock, &hba->attr);
|
||||
od_hba_rules_init(&hba->rules);
|
||||
}
|
||||
|
||||
void od_hba_free(od_hba_t *hba)
|
||||
{
|
||||
od_hba_rules_free(&hba->rules);
|
||||
pthread_mutex_destroy(&hba->lock);
|
||||
pthread_mutexattr_destroy(&hba->attr);
|
||||
}
|
||||
|
||||
void od_hba_lock(od_hba_t *hba)
|
||||
{
|
||||
pthread_mutex_lock(&hba->lock);
|
||||
}
|
||||
|
||||
void od_hba_unlock(od_hba_t *hba)
|
||||
{
|
||||
pthread_mutex_unlock(&hba->lock);
|
||||
}
|
||||
|
||||
void od_hba_reload(od_hba_t *hba, od_hba_rules_t *rules)
|
||||
{
|
||||
od_hba_lock(hba);
|
||||
|
||||
od_list_init(&hba->rules);
|
||||
memcpy(&hba->rules, &rules, sizeof(hba->rules));
|
||||
|
||||
od_hba_unlock(hba);
|
||||
}
|
||||
|
||||
bool od_hba_validate_addr(od_hba_rule_t *rule, struct sockaddr_storage *sa)
|
||||
{
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *)sa;
|
||||
struct sockaddr_in *rule_addr = (struct sockaddr_in *)&rule->addr;
|
||||
struct sockaddr_in *rule_mask = (struct sockaddr_in *)&rule->mask;
|
||||
in_addr_t client_addr = sin->sin_addr.s_addr;
|
||||
in_addr_t client_net = rule_mask->sin_addr.s_addr & client_addr;
|
||||
return (client_net ^ rule_addr->sin_addr.s_addr) == 0;
|
||||
}
|
||||
|
||||
bool od_hba_validate_addr6(od_hba_rule_t *rule, struct sockaddr_storage *sa)
|
||||
{
|
||||
struct sockaddr_in6 *sin = (struct sockaddr_in6 *)sa;
|
||||
struct sockaddr_in6 *rule_addr = (struct sockaddr_in6 *)&rule->addr;
|
||||
struct sockaddr_in6 *rule_mask = (struct sockaddr_in6 *)&rule->mask;
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
uint8_t client_net_byte = rule_mask->sin6_addr.s6_addr[i] &
|
||||
sin->sin6_addr.s6_addr[i];
|
||||
if (client_net_byte ^ rule_addr->sin6_addr.s6_addr[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool od_hba_validate_name(char *client_name, od_hba_rule_name_t *name,
|
||||
char *client_other_name)
|
||||
{
|
||||
if (name->flags & OD_HBA_NAME_ALL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((name->flags & OD_HBA_NAME_SAMEUSER) &&
|
||||
strcmp(client_name, client_other_name) == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
od_list_t *i;
|
||||
od_hba_rule_name_item_t *item;
|
||||
od_list_foreach(&name->values, i)
|
||||
{
|
||||
item = od_container_of(i, od_hba_rule_name_item_t, link);
|
||||
if (item->value != NULL &&
|
||||
strcmp(client_name, item->value) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int od_hba_process(od_client_t *client)
|
||||
{
|
||||
od_instance_t *instance = client->global->instance;
|
||||
od_hba_t *hba = client->global->hba;
|
||||
od_list_t *i;
|
||||
od_hba_rule_t *rule;
|
||||
od_hba_rules_t *rules;
|
||||
|
||||
if (instance->config.hba_file == NULL) {
|
||||
return OK_RESPONSE;
|
||||
}
|
||||
|
||||
struct sockaddr_storage sa;
|
||||
int salen = sizeof(sa);
|
||||
struct sockaddr *saddr = (struct sockaddr *)&sa;
|
||||
int rc = machine_getpeername(client->io.io, saddr, &salen);
|
||||
if (rc == -1)
|
||||
return -1;
|
||||
|
||||
od_hba_lock(hba);
|
||||
rules = &hba->rules;
|
||||
od_hba_unlock(hba);
|
||||
|
||||
od_list_foreach(rules, i)
|
||||
{
|
||||
rule = od_container_of(i, od_hba_rule_t, link);
|
||||
if (sa.ss_family == AF_UNIX) {
|
||||
if (rule->connection_type != OD_CONFIG_HBA_LOCAL)
|
||||
continue;
|
||||
} else if (rule->connection_type == OD_CONFIG_HBA_LOCAL) {
|
||||
continue;
|
||||
} else if (rule->connection_type == OD_CONFIG_HBA_HOSTSSL &&
|
||||
!client->startup.is_ssl_request) {
|
||||
continue;
|
||||
} else if (rule->connection_type == OD_CONFIG_HBA_HOSTNOSSL &&
|
||||
client->startup.is_ssl_request) {
|
||||
continue;
|
||||
} else if (sa.ss_family == AF_INET) {
|
||||
if (rule->addr.ss_family != AF_INET ||
|
||||
!od_hba_validate_addr(rule, &sa)) {
|
||||
continue;
|
||||
}
|
||||
} else if (sa.ss_family == AF_INET6) {
|
||||
if (rule->addr.ss_family != AF_INET6 ||
|
||||
!od_hba_validate_addr6(rule, &sa)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!od_hba_validate_name(client->rule->db_name,
|
||||
&rule->database,
|
||||
client->rule->user_name)) {
|
||||
continue;
|
||||
}
|
||||
if (!od_hba_validate_name(client->rule->user_name, &rule->user,
|
||||
client->rule->db_name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
rc = rule->auth_method == OD_CONFIG_HBA_ALLOW ? OK_RESPONSE :
|
||||
NOT_OK_RESPONSE;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
return NOT_OK_RESPONSE;
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef ODYSSEY_HBA_H
|
||||
#define ODYSSEY_HBA_H
|
||||
|
||||
/*
|
||||
* Odyssey.
|
||||
*
|
||||
* Scalable PostgreSQL connection pooler.
|
||||
*/
|
||||
|
||||
typedef struct od_hba od_hba_t;
|
||||
|
||||
struct od_hba {
|
||||
pthread_mutex_t lock;
|
||||
pthread_mutexattr_t attr;
|
||||
|
||||
od_hba_rules_t rules;
|
||||
};
|
||||
|
||||
void od_hba_init(od_hba_t *hba);
|
||||
void od_hba_free(od_hba_t *hba);
|
||||
void od_hba_reload(od_hba_t *hba, od_hba_rules_t *rules);
|
||||
int od_hba_process(od_client_t *client);
|
||||
|
||||
#endif // ODYSSEY_HBA_H
|
|
@ -0,0 +1,397 @@
|
|||
|
||||
/*
|
||||
* Odyssey.
|
||||
*
|
||||
* Scalable PostgreSQL connection pooler.
|
||||
*/
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <kiwi.h>
|
||||
#include <machinarium.h>
|
||||
#include <odyssey.h>
|
||||
|
||||
enum { OD_LLOCAL,
|
||||
OD_LHOST,
|
||||
OD_LHOSTSSL,
|
||||
OD_LHOSTNOSSL,
|
||||
OD_LALL,
|
||||
OD_LSAMEUSER,
|
||||
OD_LALLOW,
|
||||
OD_LDENY,
|
||||
};
|
||||
|
||||
static od_keyword_t od_hba_keywords[] = {
|
||||
/* connection types */
|
||||
od_keyword("local", OD_LLOCAL),
|
||||
od_keyword("host", OD_LHOST),
|
||||
od_keyword("hostssl", OD_LHOSTSSL),
|
||||
od_keyword("hostnossl", OD_LHOSTNOSSL),
|
||||
/* db/user */
|
||||
od_keyword("all", OD_LALL),
|
||||
od_keyword("sameuser", OD_LSAMEUSER),
|
||||
/* auth type */
|
||||
od_keyword("allow", OD_LALLOW),
|
||||
od_keyword("trust", OD_LALLOW),
|
||||
od_keyword("deny", OD_LDENY),
|
||||
od_keyword("reject", OD_LDENY),
|
||||
};
|
||||
|
||||
static void od_hba_reader_error(od_config_reader_t *reader, char *msg)
|
||||
{
|
||||
od_errorf(reader->error, "%s:%d %s", reader->config_file,
|
||||
reader->parser.line, msg);
|
||||
}
|
||||
|
||||
static int od_hba_parser_next(od_parser_t *parser, od_token_t *token)
|
||||
{
|
||||
/* try to use backlog */
|
||||
if (parser->backlog_count > 0) {
|
||||
*token = parser->backlog[parser->backlog_count - 1];
|
||||
parser->backlog_count--;
|
||||
return token->type;
|
||||
}
|
||||
/* skip white spaces and comments */
|
||||
for (;;) {
|
||||
while (parser->pos < parser->end && isspace(*parser->pos)) {
|
||||
if (*parser->pos == '\n')
|
||||
parser->line++;
|
||||
parser->pos++;
|
||||
}
|
||||
if (od_unlikely(parser->pos == parser->end)) {
|
||||
token->type = OD_PARSER_EOF;
|
||||
return token->type;
|
||||
}
|
||||
if (*parser->pos != '#')
|
||||
break;
|
||||
while (parser->pos < parser->end && *parser->pos != '\n')
|
||||
parser->pos++;
|
||||
if (parser->pos == parser->end) {
|
||||
token->type = OD_PARSER_EOF;
|
||||
return token->type;
|
||||
}
|
||||
parser->line++;
|
||||
}
|
||||
|
||||
/* symbols */
|
||||
if (*parser->pos != '\"' && ispunct(*parser->pos)) {
|
||||
token->type = OD_PARSER_SYMBOL;
|
||||
token->line = parser->line;
|
||||
token->value.num = *parser->pos;
|
||||
parser->pos++;
|
||||
return token->type;
|
||||
}
|
||||
|
||||
if (isalnum(*parser->pos)) {
|
||||
token->type = OD_PARSER_KEYWORD;
|
||||
token->line = parser->line;
|
||||
token->value.string.pointer = parser->pos;
|
||||
while (parser->pos < parser->end && *parser->pos != ',' &&
|
||||
(isalnum(*parser->pos) || ispunct(*parser->pos)))
|
||||
parser->pos++;
|
||||
token->value.string.size =
|
||||
parser->pos - token->value.string.pointer;
|
||||
return token->type;
|
||||
}
|
||||
|
||||
if (*parser->pos == '\"') {
|
||||
token->type = OD_PARSER_STRING;
|
||||
token->line = parser->line;
|
||||
parser->pos++;
|
||||
token->value.string.pointer = parser->pos;
|
||||
while (parser->pos < parser->end && *parser->pos != '\"') {
|
||||
if (*parser->pos == '\n') {
|
||||
token->type = OD_PARSER_ERROR;
|
||||
return token->type;
|
||||
}
|
||||
parser->pos++;
|
||||
}
|
||||
if (od_unlikely(parser->pos == parser->end)) {
|
||||
token->type = OD_PARSER_ERROR;
|
||||
return token->type;
|
||||
}
|
||||
token->value.string.size =
|
||||
parser->pos - token->value.string.pointer;
|
||||
parser->pos++;
|
||||
return token->type;
|
||||
}
|
||||
|
||||
/* error */
|
||||
token->type = OD_PARSER_ERROR;
|
||||
token->line = parser->line;
|
||||
return token->type;
|
||||
}
|
||||
|
||||
static int od_hba_reader_match_string(od_token_t token, char **value)
|
||||
{
|
||||
char *copy = malloc(token.value.string.size + 1);
|
||||
if (copy == NULL) {
|
||||
return NOT_OK_RESPONSE;
|
||||
}
|
||||
memcpy(copy, token.value.string.pointer, token.value.string.size);
|
||||
copy[token.value.string.size] = 0;
|
||||
if (*value)
|
||||
free(*value);
|
||||
*value = copy;
|
||||
return OK_RESPONSE;
|
||||
}
|
||||
|
||||
static int od_hba_reader_value(od_config_reader_t *reader, void **dest)
|
||||
{
|
||||
od_token_t token;
|
||||
int rc;
|
||||
char *string_value = NULL;
|
||||
rc = od_hba_parser_next(&reader->parser, &token);
|
||||
switch (rc) {
|
||||
case OD_PARSER_EOF:
|
||||
return rc;
|
||||
case OD_PARSER_KEYWORD: {
|
||||
od_keyword_t *match;
|
||||
match = od_keyword_match(od_hba_keywords, &token);
|
||||
if (match) {
|
||||
*dest = match;
|
||||
return OD_PARSER_KEYWORD;
|
||||
}
|
||||
if (od_hba_reader_match_string(token, &string_value) ==
|
||||
OK_RESPONSE) {
|
||||
*dest = string_value;
|
||||
return OD_PARSER_STRING;
|
||||
}
|
||||
od_hba_reader_error(reader, "unable to read string");
|
||||
return -1;
|
||||
}
|
||||
case OD_PARSER_STRING:
|
||||
if (od_hba_reader_match_string(token, &string_value) ==
|
||||
OK_RESPONSE) {
|
||||
*dest = string_value;
|
||||
return OD_PARSER_STRING;
|
||||
}
|
||||
od_hba_reader_error(reader, "unable to read string");
|
||||
return -1;
|
||||
default:
|
||||
od_hba_reader_error(reader, "expected string or keyword");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int od_hba_reader_address(struct sockaddr_storage *dest,
|
||||
const char *addr)
|
||||
{
|
||||
int rc;
|
||||
rc = inet_pton(AF_INET, addr, &((struct sockaddr_in *)dest)->sin_addr);
|
||||
if (rc > 0) {
|
||||
dest->ss_family = AF_INET;
|
||||
return 0;
|
||||
}
|
||||
if (inet_pton(AF_INET6, addr,
|
||||
&((struct sockaddr_in6 *)dest)->sin6_addr) > 0) {
|
||||
dest->ss_family = AF_INET6;
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int od_hba_reader_prefix(od_hba_rule_t *hba, char *prefix)
|
||||
{
|
||||
char *end = NULL;
|
||||
unsigned long int len = strtoul(prefix, &end, 10);
|
||||
|
||||
if (hba->addr.ss_family == AF_INET) {
|
||||
if (len > 32)
|
||||
return -1;
|
||||
uint32_t mask = 0;
|
||||
unsigned int i;
|
||||
struct sockaddr_in *addr = (struct sockaddr_in *)&hba->mask;
|
||||
for (i = 0; i < len / 8; ++i) {
|
||||
mask = 0xff | (mask << 8);
|
||||
}
|
||||
if (len % 8 != 0)
|
||||
mask = mask | ((len % 8) << (i * 8));
|
||||
addr->sin_addr.s_addr = mask;
|
||||
return 0;
|
||||
} else if (hba->addr.ss_family == AF_INET6) {
|
||||
if (len > 128)
|
||||
return -1;
|
||||
unsigned int i;
|
||||
struct sockaddr_in6 *addr = (struct sockaddr_in6 *)&hba->mask;
|
||||
for (i = 0; i < len / 8; ++i) {
|
||||
addr->sin6_addr.s6_addr[i] = 0xff;
|
||||
}
|
||||
if (len % 8 != 0)
|
||||
addr->sin6_addr.s6_addr[i] = len & 7;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int od_hba_reader_name(od_config_reader_t *reader,
|
||||
struct od_hba_rule_name *name, bool is_db)
|
||||
{
|
||||
od_keyword_t *keyword = NULL;
|
||||
int rc;
|
||||
void *value = NULL;
|
||||
od_token_t token;
|
||||
while (1) {
|
||||
rc = od_hba_reader_value(reader, &value);
|
||||
switch (rc) {
|
||||
case OD_PARSER_STRING: {
|
||||
struct od_hba_rule_name_item *item =
|
||||
od_hba_rule_name_item_add(name);
|
||||
item->value = (char *)value;
|
||||
break;
|
||||
}
|
||||
case OD_PARSER_KEYWORD:
|
||||
keyword = (od_keyword_t *)value;
|
||||
switch (keyword->id) {
|
||||
case OD_LALL:
|
||||
name->flags |= OD_HBA_NAME_ALL;
|
||||
break;
|
||||
case OD_LSAMEUSER:
|
||||
if (is_db) {
|
||||
name->flags |= OD_HBA_NAME_SAMEUSER;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
od_hba_reader_error(reader, "expected name or keyword");
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = od_hba_parser_next(&reader->parser, &token);
|
||||
if (rc == OD_PARSER_SYMBOL && token.value.num == ',') {
|
||||
continue;
|
||||
}
|
||||
|
||||
od_parser_push(&reader->parser, &token);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int od_hba_reader_parse(od_config_reader_t *reader)
|
||||
{
|
||||
od_hba_rule_t *hba = NULL;
|
||||
|
||||
for (;;) {
|
||||
hba = od_hba_rule_create();
|
||||
if (hba == NULL) {
|
||||
od_hba_reader_error(reader, "memory allocation error");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* connection type */
|
||||
od_keyword_t *keyword = NULL;
|
||||
void *connection_type = NULL;
|
||||
od_hba_rule_conn_type_t conn_type;
|
||||
int rc;
|
||||
rc = od_hba_reader_value(reader, &connection_type);
|
||||
if (rc == OD_PARSER_EOF) {
|
||||
return 0;
|
||||
}
|
||||
if (rc != OD_PARSER_KEYWORD) {
|
||||
od_hba_reader_error(reader, "invalid connection type");
|
||||
goto error;
|
||||
}
|
||||
keyword = (od_keyword_t *)connection_type;
|
||||
switch (keyword->id) {
|
||||
case OD_LLOCAL:
|
||||
conn_type = OD_CONFIG_HBA_LOCAL;
|
||||
break;
|
||||
case OD_LHOST:
|
||||
conn_type = OD_CONFIG_HBA_HOST;
|
||||
break;
|
||||
case OD_LHOSTSSL:
|
||||
conn_type = OD_CONFIG_HBA_HOSTSSL;
|
||||
break;
|
||||
case OD_LHOSTNOSSL:
|
||||
conn_type = OD_CONFIG_HBA_HOSTNOSSL;
|
||||
break;
|
||||
default:
|
||||
od_hba_reader_error(reader, "invalid connection type");
|
||||
goto error;
|
||||
}
|
||||
hba->connection_type = conn_type;
|
||||
|
||||
/* db & user name */
|
||||
if (od_hba_reader_name(reader, &hba->database, true) != 0) {
|
||||
goto error;
|
||||
}
|
||||
if (od_hba_reader_name(reader, &hba->user, false) != 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (conn_type != OD_CONFIG_HBA_LOCAL) {
|
||||
void *address = NULL;
|
||||
char *mask = NULL;
|
||||
|
||||
/* ip address */
|
||||
rc = od_hba_reader_value(reader, &address);
|
||||
if (rc != OD_PARSER_STRING) {
|
||||
od_hba_reader_error(reader,
|
||||
"expected IP address");
|
||||
goto error;
|
||||
}
|
||||
mask = strchr(address, '/');
|
||||
if (mask)
|
||||
*mask++ = 0;
|
||||
|
||||
if (od_hba_reader_address(&hba->addr, address) == -1) {
|
||||
od_hba_reader_error(reader,
|
||||
"invalid IP address");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* network mask */
|
||||
if (mask) {
|
||||
if (od_hba_reader_prefix(hba, mask) == -1) {
|
||||
od_hba_reader_error(
|
||||
reader,
|
||||
"invalid network prefix length");
|
||||
goto error;
|
||||
}
|
||||
|
||||
} else {
|
||||
rc = od_hba_reader_value(reader, &address);
|
||||
if (rc != OD_PARSER_STRING) {
|
||||
od_hba_reader_error(
|
||||
reader,
|
||||
"expected network mask");
|
||||
goto error;
|
||||
}
|
||||
if (od_hba_reader_address(&hba->mask,
|
||||
address) == -1) {
|
||||
od_hba_reader_error(
|
||||
reader, "invalid network mask");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* auth method */
|
||||
void *auth_method = NULL;
|
||||
rc = od_hba_reader_value(reader, &auth_method);
|
||||
if (rc != OD_PARSER_KEYWORD) {
|
||||
od_hba_reader_error(reader, "expected auth method");
|
||||
goto error;
|
||||
}
|
||||
|
||||
keyword = (od_keyword_t *)auth_method;
|
||||
switch (keyword->id) {
|
||||
case OD_LALLOW:
|
||||
hba->auth_method = OD_CONFIG_HBA_ALLOW;
|
||||
break;
|
||||
case OD_LDENY:
|
||||
hba->auth_method = OD_CONFIG_HBA_DENY;
|
||||
break;
|
||||
default:
|
||||
od_hba_reader_error(
|
||||
reader,
|
||||
"invalid auth method: only allow/deny or trust/reject is now supported");
|
||||
goto error;
|
||||
}
|
||||
|
||||
od_hba_rules_add(reader->hba_rules, hba);
|
||||
}
|
||||
error:
|
||||
od_hba_rule_free(hba);
|
||||
return -1;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef ODYSSEY_HBA_READER_H
|
||||
#define ODYSSEY_HBA_READER_H
|
||||
|
||||
int od_hba_reader_parse(od_config_reader_t *reader);
|
||||
|
||||
#endif // ODYSSEY_HBA_READER_H
|
|
@ -0,0 +1,75 @@
|
|||
|
||||
/*
|
||||
* Odyssey.
|
||||
*
|
||||
* Scalable PostgreSQL connection pooler.
|
||||
*/
|
||||
|
||||
#include <machinarium.h>
|
||||
#include <kiwi.h>
|
||||
#include <odyssey.h>
|
||||
|
||||
od_hba_rule_name_item_t *od_hba_rule_name_item_add(od_hba_rule_name_t *name)
|
||||
{
|
||||
od_hba_rule_name_item_t *item;
|
||||
item = (od_hba_rule_name_item_t *)malloc(sizeof(*item));
|
||||
if (item == NULL)
|
||||
return NULL;
|
||||
memset(item, 0, sizeof(*item));
|
||||
od_list_init(&item->link);
|
||||
od_list_append(&name->values, &item->link);
|
||||
return item;
|
||||
}
|
||||
|
||||
od_hba_rule_t *od_hba_rule_create()
|
||||
{
|
||||
od_hba_rule_t *hba;
|
||||
hba = (od_hba_rule_t *)malloc(sizeof(*hba));
|
||||
if (hba == NULL)
|
||||
return NULL;
|
||||
memset(hba, 0, sizeof(*hba));
|
||||
od_list_init(&hba->database.values);
|
||||
od_list_init(&hba->user.values);
|
||||
return hba;
|
||||
}
|
||||
|
||||
void od_hba_rule_free(od_hba_rule_t *hba)
|
||||
{
|
||||
od_list_t *i, *n;
|
||||
od_hba_rule_name_item_t *item;
|
||||
od_list_foreach_safe(&hba->database.values, i, n)
|
||||
{
|
||||
item = od_container_of(i, od_hba_rule_name_item_t, link);
|
||||
free(item->value);
|
||||
free(item);
|
||||
}
|
||||
od_list_foreach_safe(&hba->user.values, i, n)
|
||||
{
|
||||
item = od_container_of(i, od_hba_rule_name_item_t, link);
|
||||
free(item->value);
|
||||
free(item);
|
||||
}
|
||||
free(hba);
|
||||
}
|
||||
|
||||
void od_hba_rules_init(od_hba_rules_t *rules)
|
||||
{
|
||||
od_list_init(rules);
|
||||
}
|
||||
|
||||
void od_hba_rules_free(od_hba_rules_t *rules)
|
||||
{
|
||||
od_list_t *i, *n;
|
||||
od_list_foreach_safe(rules, i, n)
|
||||
{
|
||||
od_hba_rule_t *hba;
|
||||
hba = od_container_of(i, od_hba_rule_t, link);
|
||||
od_hba_rule_free(hba);
|
||||
}
|
||||
}
|
||||
|
||||
void od_hba_rules_add(od_hba_rules_t *rules, od_hba_rule_t *rule)
|
||||
{
|
||||
od_list_init(&rule->link);
|
||||
od_list_append(rules, &rule->link);
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
#ifndef ODYSSEY_HBA_RULE_H
|
||||
#define ODYSSEY_HBA_RULE_H
|
||||
|
||||
/*
|
||||
* Odyssey.
|
||||
*
|
||||
* Scalable PostgreSQL connection pooler.
|
||||
*/
|
||||
|
||||
#define OD_HBA_NAME_ALL 1
|
||||
#define OD_HBA_NAME_SAMEUSER 2
|
||||
|
||||
typedef struct od_hba_rule od_hba_rule_t;
|
||||
|
||||
typedef enum {
|
||||
OD_CONFIG_HBA_LOCAL,
|
||||
OD_CONFIG_HBA_HOST,
|
||||
OD_CONFIG_HBA_HOSTSSL,
|
||||
OD_CONFIG_HBA_HOSTNOSSL
|
||||
} od_hba_rule_conn_type_t;
|
||||
|
||||
typedef enum {
|
||||
OD_CONFIG_HBA_ALLOW,
|
||||
OD_CONFIG_HBA_DENY,
|
||||
} od_hba_rule_auth_method_t;
|
||||
|
||||
typedef struct od_hba_rule_name_item od_hba_rule_name_item_t;
|
||||
|
||||
struct od_hba_rule_name_item {
|
||||
char *value;
|
||||
od_list_t link;
|
||||
};
|
||||
|
||||
typedef struct od_hba_rule_name od_hba_rule_name_t;
|
||||
|
||||
struct od_hba_rule_name {
|
||||
unsigned int flags;
|
||||
od_list_t values;
|
||||
};
|
||||
|
||||
struct od_hba_rule {
|
||||
od_hba_rule_conn_type_t connection_type;
|
||||
od_hba_rule_name_t database;
|
||||
od_hba_rule_name_t user;
|
||||
struct sockaddr_storage addr;
|
||||
struct sockaddr_storage mask;
|
||||
od_hba_rule_auth_method_t auth_method;
|
||||
od_list_t link;
|
||||
};
|
||||
|
||||
typedef od_list_t od_hba_rules_t;
|
||||
|
||||
od_hba_rule_name_item_t *od_hba_rule_name_item_add(od_hba_rule_name_t *name);
|
||||
od_hba_rule_t *od_hba_rule_create();
|
||||
void od_hba_rule_free(od_hba_rule_t *hba);
|
||||
void od_hba_rules_init(od_hba_rules_t *rules);
|
||||
void od_hba_rules_free(od_hba_rules_t *rules);
|
||||
void od_hba_rules_add(od_hba_rules_t *rules, od_hba_rule_t *rule);
|
||||
#endif /* ODYSSEY_HBA_RULE_H */
|
|
@ -95,21 +95,23 @@ int od_instance_main(od_instance_t *instance, int argc, char **argv)
|
|||
od_worker_pool_t worker_pool;
|
||||
od_extention_t extentions;
|
||||
od_global_t global;
|
||||
od_hba_t hba;
|
||||
|
||||
od_system_init(&system);
|
||||
od_router_init(&router, &global);
|
||||
od_cron_init(&cron);
|
||||
od_worker_pool_init(&worker_pool);
|
||||
od_extentions_init(&extentions);
|
||||
od_hba_init(&hba);
|
||||
od_global_init(&global, instance, &system, &router, &cron, &worker_pool,
|
||||
&extentions);
|
||||
&extentions, &hba);
|
||||
|
||||
/* read config file */
|
||||
od_error_t error;
|
||||
od_error_init(&error);
|
||||
int rc;
|
||||
rc = od_config_reader_import(&instance->config, &router.rules, &error,
|
||||
&extentions, &global,
|
||||
&extentions, &global, &hba.rules,
|
||||
instance->config_file);
|
||||
if (rc == -1) {
|
||||
od_error(&instance->logger, "config", NULL, NULL, "%s",
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#include "sources/storage.h"
|
||||
#include "sources/pool.h"
|
||||
#include "sources/rules.h"
|
||||
#include "sources/hba_rule.h"
|
||||
|
||||
#include "sources/config_common.h"
|
||||
|
||||
|
@ -95,11 +96,13 @@
|
|||
#include "sources/module.h"
|
||||
#include "sources/extention.h"
|
||||
|
||||
#include "sources/hba_reader.h"
|
||||
#include "sources/config_reader.h"
|
||||
|
||||
#include "sources/auth.h"
|
||||
#include "sources/query.h"
|
||||
#include "sources/auth_query.h"
|
||||
#include "sources/hba.h"
|
||||
|
||||
#include "sources/od_dlsym.h"
|
||||
#include "sources/daemon.h"
|
||||
|
|
|
@ -349,6 +349,7 @@ void od_system_config_reload(od_system_t *system)
|
|||
od_instance_t *instance = system->global->instance;
|
||||
od_router_t *router = system->global->router;
|
||||
od_extention_t *extentions = system->global->extentions;
|
||||
od_hba_t *hba = system->global->hba;
|
||||
|
||||
od_log(&instance->logger, "config", NULL, NULL,
|
||||
"importing changes from '%s'", instance->config_file);
|
||||
|
@ -366,9 +367,13 @@ void od_system_config_reload(od_system_t *system)
|
|||
od_rules_t rules;
|
||||
od_rules_init(&rules);
|
||||
|
||||
od_hba_rules_t hba_rules;
|
||||
od_hba_rules_init(&hba_rules);
|
||||
|
||||
int rc;
|
||||
rc = od_config_reader_import(&config, &rules, &error, extentions,
|
||||
system->global, instance->config_file);
|
||||
system->global, &hba_rules,
|
||||
instance->config_file);
|
||||
if (rc == -1) {
|
||||
od_error(&instance->logger, "config", NULL, NULL, "%s",
|
||||
error.error);
|
||||
|
@ -394,6 +399,7 @@ void od_system_config_reload(od_system_t *system)
|
|||
return;
|
||||
}
|
||||
od_config_reload(&instance->config, &config);
|
||||
od_hba_reload(hba, &hba_rules);
|
||||
|
||||
pthread_mutex_unlock(&router->rules.mu);
|
||||
|
||||
|
@ -451,6 +457,7 @@ void od_system_config_reload(od_system_t *system)
|
|||
}
|
||||
|
||||
od_config_free(&config);
|
||||
od_hba_rules_free(&hba_rules);
|
||||
|
||||
if (instance->config.log_config)
|
||||
od_rules_print(&rules, &instance->logger);
|
||||
|
|
Loading…
Reference in New Issue