mirror of https://github.com/yandex/odyssey.git
130 lines
2.7 KiB
C
130 lines
2.7 KiB
C
|
|
/*
|
|
* Odyssey.
|
|
*
|
|
* Scalable PostgreSQL connection pooler.
|
|
*/
|
|
|
|
#include <odyssey.h>
|
|
|
|
void od_hba_init(od_hba_t *hba)
|
|
{
|
|
pthread_mutex_init(&hba->lock, NULL);
|
|
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);
|
|
}
|
|
|
|
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_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 ||
|
|
sa.ss_family == AF_INET6) {
|
|
if (!od_address_validate(&rule->address_range, &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;
|
|
}
|