mirror of https://github.com/yandex/odyssey.git
return error if ldap connection establishment failed, rebind ldap
connection in case of server failture
This commit is contained in:
parent
a79125f4d0
commit
dc44b323d1
|
@ -5,6 +5,7 @@ project(odyssey C)
|
|||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/cmake)
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=aarch64")
|
||||
|
||||
set(CLANGCOMPILERSTANDART gnu11)
|
||||
|
||||
|
@ -53,19 +54,19 @@ execute_process(COMMAND ${CMAKE_C_COMPILER} --version
|
|||
set(OD_DEVEL_LVL -1)
|
||||
|
||||
if ("${CMAKE_BUILD_TYPE}" STREQUAL "")
|
||||
set(CMAKE_BUILD_TYPE "Debug")
|
||||
set(OD_DEVEL_LVL 1)
|
||||
set(CMAKE_BUILD_TYPE "Debug")
|
||||
set(OD_DEVEL_LVL 1)
|
||||
endif()
|
||||
if ("${CMAKE_BUILD_TYPE}" STREQUAL "Release")
|
||||
set(CMAKE_C_FLAGS "-std=${CLANGCOMPILERSTANDART} -pedantic -Wall -Wextra -Wstrict-aliasing -g -O2 -pthread -D_GNU_SOURCE")
|
||||
set(OD_DEVEL_LVL -1)
|
||||
set(CMAKE_C_FLAGS "-std=${CLANGCOMPILERSTANDART} -pedantic -Wall -Wextra -Wstrict-aliasing -g -O2 -pthread -D_GNU_SOURCE")
|
||||
set(OD_DEVEL_LVL -1)
|
||||
elseif("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
|
||||
set(CMAKE_C_FLAGS "-std=${CLANGCOMPILERSTANDART} -pedantic -Wall -Wextra -Wstrict-aliasing -g -O0 -pthread -D_GNU_SOURCE")
|
||||
set(OD_DEVEL_LVL 1)
|
||||
set(CMAKE_C_FLAGS "-std=${CLANGCOMPILERSTANDART} -pedantic -Wall -Wextra -Wstrict-aliasing -g -O0 -pthread -D_GNU_SOURCE -DLDAP_DBG")
|
||||
set(OD_DEVEL_LVL 1)
|
||||
elseif("${CMAKE_BUILD_TYPE}" STREQUAL "ASAN")
|
||||
set(CMAKE_C_FLAGS "-std=${CLANGCOMPILERSTANDART} -g -fsanitize=address,undefined -fno-sanitize-recover=all -pedantic -Wall -Wextra -Wstrict-aliasing -g -O0 -pthread -D_GNU_SOURCE")
|
||||
set(CMAKE_C_FLAGS "-std=${CLANGCOMPILERSTANDART} -g -fsanitize=address,undefined -fno-sanitize-recover=all -pedantic -Wall -Wextra -Wstrict-aliasing -g -O0 -pthread -D_GNU_SOURCE")
|
||||
elseif("${CMAKE_BUILD_TYPE}" STREQUAL "TSAN")
|
||||
set(CMAKE_C_FLAGS "-std=${CLANGCOMPILERSTANDART} -g -fsanitize=thread -fno-sanitize-recover=all -pedantic -Wall -Wextra -Wstrict-aliasing -g -O0 -pthread -D_GNU_SOURCE")
|
||||
set(CMAKE_C_FLAGS "-std=${CLANGCOMPILERSTANDART} -g -fsanitize=thread -fno-sanitize-recover=all -pedantic -Wall -Wextra -Wstrict-aliasing -g -O0 -pthread -D_GNU_SOURCE")
|
||||
endif()
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CC_FLAGS}")
|
||||
|
|
|
@ -5,8 +5,8 @@ do
|
|||
sleep 0.1
|
||||
|
||||
for __ in $(seq 1 10); do
|
||||
PGPASSWORD=lolol psql -h localhost -p6432 -dpostgres2 -Uuser3 -c 'select 3' &
|
||||
PGPASSWORD=lolol psql -h localhost -p6432 -dpostgres2 -Uuser3 -c 'select pg_sleep(1)' &
|
||||
PGPASSWORD=lolol psql -h localhost -p6432 -dpostgres2 -Uuser1 -c 'select 3' &
|
||||
PGPASSWORD=lolol psql -h localhost -p6432 -dpostgres2 -Uuser1 -c 'select pg_sleep(1)' &
|
||||
done
|
||||
|
||||
done
|
||||
|
|
|
@ -63,6 +63,16 @@ ldap_endpoint "ldap1" {
|
|||
ldapport 389
|
||||
}
|
||||
|
||||
ldap_endpoint "ldap_unreachable" {
|
||||
ldapscheme "ldap"
|
||||
ldapbasedn "dc=example,dc=org"
|
||||
ldapbinddn "cn=admin,dc=example,dc=org"
|
||||
ldapbindpasswd "admin"
|
||||
ldapsearchattribute "gecos"
|
||||
ldapserver "localhost"
|
||||
ldapport 38
|
||||
}
|
||||
|
||||
database default {
|
||||
user default {
|
||||
authentication "none"
|
||||
|
@ -102,7 +112,6 @@ database "postgres2" {
|
|||
authentication "clear_text"
|
||||
|
||||
storage "postgres_server"
|
||||
storage_password "1"
|
||||
pool "session"
|
||||
pool_size 10
|
||||
|
||||
|
@ -128,6 +137,43 @@ database "postgres2" {
|
|||
|
||||
server_lifetime 3600
|
||||
log_debug no
|
||||
ldap_endpoint_name "ldap_unreachable"
|
||||
|
||||
quantiles "0.99,0.95,0.5"
|
||||
client_max 107
|
||||
}
|
||||
user "user1" {
|
||||
authentication "clear_text"
|
||||
|
||||
storage "postgres_server"
|
||||
storage_password "lolol"
|
||||
pool "session"
|
||||
|
||||
ldap_pool_size 1
|
||||
|
||||
ldap_pool_timeout 0
|
||||
|
||||
pool_size 1
|
||||
|
||||
pool_timeout 0
|
||||
|
||||
pool_ttl 60
|
||||
|
||||
pool_discard no
|
||||
|
||||
pool_cancel yes
|
||||
|
||||
pool_rollback yes
|
||||
|
||||
client_fwd_error yes
|
||||
|
||||
application_name_add_host yes
|
||||
|
||||
reserve_session_server_connection no
|
||||
|
||||
server_lifetime 3600
|
||||
log_debug no
|
||||
|
||||
ldap_endpoint_name "ldap1"
|
||||
|
||||
quantiles "0.99,0.95,0.5"
|
||||
|
|
|
@ -33,8 +33,9 @@ int od_frontend_error(od_client_t *client, char *code, char *fmt, ...)
|
|||
machine_msg_t *msg;
|
||||
msg = od_frontend_error_msg(client, NULL, code, fmt, args);
|
||||
va_end(args);
|
||||
if (msg == NULL)
|
||||
if (msg == NULL) {
|
||||
return -1;
|
||||
}
|
||||
return od_write(&client->io, msg);
|
||||
}
|
||||
|
||||
|
@ -209,7 +210,9 @@ od_frontend_attach(od_client_t *client, char *context,
|
|||
continue;
|
||||
}
|
||||
od_debug(&instance->logger, context, client, server,
|
||||
"client %s attached to %s%.*s", client->id.id,
|
||||
"client %s%.*s attached to %s%.*s",
|
||||
client->id.id_prefix,
|
||||
(int)sizeof(client->id.id_prefix), client->id.id,
|
||||
server->id.id_prefix,
|
||||
(int)sizeof(server->id.id_prefix), server->id.id);
|
||||
|
||||
|
|
123
sources/ldap.c
123
sources/ldap.c
|
@ -18,15 +18,56 @@ od_retcode_t od_ldap_server_free(od_ldap_server_t *serv)
|
|||
ldap_unbind(serv->conn);
|
||||
}
|
||||
|
||||
free(serv->auth_user);
|
||||
if (serv->auth_user) {
|
||||
free(serv->auth_user);
|
||||
}
|
||||
free(serv);
|
||||
return OK_RESPONSE;
|
||||
}
|
||||
|
||||
//#define LDAP_DBG
|
||||
|
||||
static inline od_retcode_t od_ldap_error_report_client(od_client_t *cl, int rc)
|
||||
{
|
||||
switch (rc) {
|
||||
case LDAP_SUCCESS:
|
||||
return OK_RESPONSE;
|
||||
case LDAP_INVALID_CREDENTIALS:
|
||||
return NOT_OK_RESPONSE;
|
||||
case LDAP_UNAVAILABLE:
|
||||
case LDAP_UNWILLING_TO_PERFORM:
|
||||
case LDAP_BUSY: {
|
||||
od_frontend_error(cl, KIWI_SYNTAX_ERROR,
|
||||
"LDAP auth failed: ldap server is down");
|
||||
return NOT_OK_RESPONSE;
|
||||
}
|
||||
case LDAP_INVALID_SYNTAX: {
|
||||
od_frontend_error(
|
||||
cl, KIWI_SYNTAX_ERROR,
|
||||
"LDAP auth failed: invalid attribute value was specified");
|
||||
return NOT_OK_RESPONSE;
|
||||
}
|
||||
default: {
|
||||
#ifdef LDAP_DBG
|
||||
od_frontend_error(cl, KIWI_SYNTAX_ERROR,
|
||||
"LDAP auth failed: %s %d",
|
||||
ldap_err2string(rc), rc);
|
||||
#else
|
||||
od_frontend_error(cl, KIWI_SYNTAX_ERROR,
|
||||
"LDAP auth failed: unknown error");
|
||||
#endif
|
||||
return NOT_OK_RESPONSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline int od_init_ldap_conn(LDAP **l, char *uri)
|
||||
{
|
||||
od_retcode_t rc = ldap_initialize(l, uri);
|
||||
if (rc != LDAP_SUCCESS) {
|
||||
// set to null, we do not need to unbind this
|
||||
// ldap_initialize frees assosated memory
|
||||
*l = NULL;
|
||||
return NOT_OK_RESPONSE;
|
||||
}
|
||||
|
||||
|
@ -34,6 +75,8 @@ static inline int od_init_ldap_conn(LDAP **l, char *uri)
|
|||
rc = ldap_set_option(*l, LDAP_OPT_PROTOCOL_VERSION, &ldapversion);
|
||||
|
||||
if (rc != LDAP_SUCCESS) {
|
||||
// same as above
|
||||
*l = NULL;
|
||||
return NOT_OK_RESPONSE;
|
||||
}
|
||||
return OK_RESPONSE;
|
||||
|
@ -166,6 +209,7 @@ od_ldap_server_t *od_ldap_server_allocate()
|
|||
od_ldap_server_t *serv = malloc(sizeof(od_ldap_server_t));
|
||||
serv->conn = NULL;
|
||||
serv->endpoint = NULL;
|
||||
serv->auth_user = NULL;
|
||||
|
||||
return serv;
|
||||
}
|
||||
|
@ -184,33 +228,29 @@ static inline od_retcode_t od_ldap_server_init(od_logger_t *logger,
|
|||
server->endpoint = le;
|
||||
|
||||
if (od_init_ldap_conn(&server->conn, le->ldapurl) != OK_RESPONSE) {
|
||||
od_ldap_server_free(server);
|
||||
return NOT_OK_RESPONSE;
|
||||
}
|
||||
|
||||
if (od_ldap_server_prepare(logger, server, route) != OK_RESPONSE) {
|
||||
od_ldap_server_free(server);
|
||||
return NOT_OK_RESPONSE;
|
||||
}
|
||||
od_route_lock(route);
|
||||
od_ldap_server_pool_set(&route->ldap_pool, server, OD_SERVER_UNDEF);
|
||||
od_route_unlock(route);
|
||||
return OK_RESPONSE;
|
||||
}
|
||||
|
||||
static inline od_retcode_t od_ldap_server_auth(od_ldap_server_t *serv,
|
||||
od_client_t *cl,
|
||||
kiwi_password_t *tok)
|
||||
static inline int od_ldap_server_auth(od_ldap_server_t *serv, od_client_t *cl,
|
||||
kiwi_password_t *tok)
|
||||
{
|
||||
od_instance_t *instance = cl->global->instance;
|
||||
od_retcode_t rc;
|
||||
|
||||
int rc;
|
||||
rc = ldap_simple_bind_s(serv->conn, serv->auth_user, tok->password);
|
||||
|
||||
if (rc != LDAP_SUCCESS) {
|
||||
return NOT_OK_RESPONSE;
|
||||
od_route_t *route = cl->route;
|
||||
if (route->rule->client_fwd_error) {
|
||||
od_ldap_error_report_client(cl, rc);
|
||||
}
|
||||
return OK_RESPONSE;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static inline od_ldap_server_t *od_ldap_server_attach(od_route_t *route,
|
||||
|
@ -222,11 +262,10 @@ static inline od_ldap_server_t *od_ldap_server_attach(od_route_t *route,
|
|||
od_logger_t *logger = &instance->logger;
|
||||
|
||||
od_ldap_server_t *server = NULL;
|
||||
od_retcode_t rc;
|
||||
|
||||
od_route_lock(route);
|
||||
|
||||
#ifdef USE_POOL
|
||||
od_retcode_t rc;
|
||||
|
||||
/* get client server from route server pool */
|
||||
bool restart_read = false;
|
||||
|
@ -288,7 +327,21 @@ static inline od_ldap_server_t *od_ldap_server_attach(od_route_t *route,
|
|||
|
||||
/* create new server object */
|
||||
server = od_ldap_server_allocate();
|
||||
od_ldap_server_init(logger, server, route);
|
||||
|
||||
int ldap_rc = od_ldap_server_init(logger, server, route);
|
||||
|
||||
od_route_lock(route);
|
||||
od_ldap_server_pool_set(&route->ldap_pool, server,
|
||||
OD_SERVER_UNDEF);
|
||||
od_route_unlock(route);
|
||||
|
||||
if (ldap_rc != LDAP_SUCCESS) {
|
||||
if (route->rule->client_fwd_error) {
|
||||
od_ldap_error_report_client(client, ldap_rc);
|
||||
}
|
||||
od_ldap_server_free(server);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
od_route_lock(route);
|
||||
}
|
||||
|
@ -316,15 +369,43 @@ od_retcode_t od_auth_ldap(od_client_t *cl, kiwi_password_t *tok)
|
|||
return NOT_OK_RESPONSE;
|
||||
}
|
||||
|
||||
od_retcode_t rc = od_ldap_server_auth(serv, cl, tok);
|
||||
int ldap_rc = od_ldap_server_auth(serv, cl, tok);
|
||||
|
||||
switch (ldap_rc) {
|
||||
case LDAP_SUCCESS: {
|
||||
#ifndef USE_POOL
|
||||
od_ldap_conn_close(route, serv);
|
||||
od_ldap_conn_close(route, serv);
|
||||
#else
|
||||
od_ldap_server_pool_set(&route->ldap_pool, serv, OD_SERVER_IDLE);
|
||||
od_route_lock(route);
|
||||
od_ldap_server_pool_set(&route->ldap_pool, serv,
|
||||
OD_SERVER_IDLE);
|
||||
od_route_unlock(route);
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
return OK_RESPONSE;
|
||||
}
|
||||
case LDAP_INVALID_SYNTAX:
|
||||
case LDAP_INVALID_CREDENTIALS:
|
||||
#ifndef USE_POOL
|
||||
od_ldap_conn_close(route, serv);
|
||||
#else
|
||||
od_route_lock(route);
|
||||
od_ldap_server_pool_set(&route->ldap_pool, serv,
|
||||
OD_SERVER_IDLE);
|
||||
od_route_unlock(route);
|
||||
#endif
|
||||
return NOT_OK_RESPONSE;
|
||||
default:
|
||||
#ifndef USE_POOL
|
||||
od_ldap_conn_close(route, serv);
|
||||
#else
|
||||
od_route_lock(route);
|
||||
/*Need to rebind */
|
||||
od_ldap_server_pool_set(&route->ldap_pool, serv,
|
||||
OD_SERVER_UNDEF);
|
||||
od_route_unlock(route);
|
||||
#endif
|
||||
return NOT_OK_RESPONSE;
|
||||
}
|
||||
}
|
||||
|
||||
od_retcode_t od_ldap_conn_close(od_attribute_unused() od_route_t *route,
|
||||
|
|
Loading…
Reference in New Issue