Sat, 11 Mar 2023 11:56:55 +0100
add ldap resource pool type implementation
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/server/daemon/ldap_resource.c Sat Mar 11 11:56:55 2023 +0100 @@ -0,0 +1,213 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2023 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "ldap_resource.h" + +#include "../util/util.h" + + + +static ResourceType ldap_resource_type = { + (resource_pool_init_func)ldap_resourcepool_init, + (resource_pool_destroy_func)ldap_resourcepool_destroy, + (resource_pool_createresource_func)ldap_resourcepool_createresource, + (resource_pool_freeresource_func)ldap_resourcepool_freeresource, + (resource_pool_prepare_func)ldap_resourcepool_prepare, + (resource_pool_finish_func)ldap_resourcepool_finish, + (resource_pool_getresourcedata_func)ldap_resourcepool_getresourcedata +}; + + +ResourceType* ldap_get_resource_type(void) { + return &ldap_resource_type; +} + +LDAP* ws_ldap_resource_create_connection( + const char *hostname, + int port, + int ssl, + int ldap_version) +{ + LDAP *ld = NULL; + +#ifdef SOLARIS + ld = ldap_init(config->hostname, config->port); + if(ld) { + ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &ldap_version); + } else { + log_ereport( + LOG_FAILURE, + "ldap_resource_create_connection failed: host: %s port: %d", + hostname, + port); + } +#else + char *ldap_uri = NULL; + asprintf(&ldap_uri, "ldap://%s:%d", hostname, port); + ld = ws_ldap_resource_create_uri_connection(ldap_uri, ldap_version); + free(ldap_uri); +#endif + if(!ld) { + return NULL; + } + + return NULL; +} + +LDAP* ws_ldap_resource_create_uri_connection( + const char *uri, + int ldap_version) +{ +#ifdef SOLARIS + log_ereport(LOG_FAILURE, "ldap_resource_create_connection_uri is not implemented on Solaris yet"); + return NULL; +#else + + LDAP *ld = NULL; + int init_ret = ldap_initialize(&ld, uri); + if(init_ret) { + log_ereport( + LOG_FAILURE, + "ldap_resource_create_connection failed: uri: %s", + uri); + } + return ld; +#endif +} + +void ws_ldap_close(LDAP *ldap) { +#ifdef SOLARIS + ldap_unbind(ldap); +#else + ldap_unbind_ext_s(ldap, NULL, NULL); +#endif +} + + +/* + * Validates settings from the pb pblock + * and creates an LDAPResourcePool object + * + * LDAPResourcePool contains all settings necessary for creating + * ldap connections. + */ +void * ldap_resourcepool_init(pool_handle_t *pool, const char *rpname, pblock *pb) { + char *ldap_uri = pblock_findval("Uri", pb); + char *host = pblock_findval("Host", pb); + char *port = pblock_findval("Port", pb); + + if(!ldap_uri || !host) { + log_ereport(LOG_MISCONFIG, "Resource pool %s: No host or ldap uri specified", rpname); + return NULL; + } + if(ldap_uri && host) { + log_ereport(LOG_MISCONFIG, "Resource pool %s: Either Uri or Host must be specified, not both", rpname); + return NULL; + } + + int64_t port_i = 0; + if(host) { + if(port) { + if(util_strtoint(port, &port_i)) { + if(port_i < 1 || port_i > 65535) { + log_ereport(LOG_MISCONFIG, "Resource pool %s: Port %s is out of range", rpname, port); + } + } else { + log_ereport(LOG_MISCONFIG, "Resource pool %s: Port '%s' is not a valid number", rpname, port); + } + } else { + port_i = LDAP_PORT; + } + } + + LDAPResourcePool *ldap_pool = pool_malloc(pool, sizeof(LDAPResourcePool)); + if(!ldap_pool) { + return NULL; + } + + ldap_pool->name = rpname; + ldap_pool->pool = pool; + ldap_pool->ldap_uri = ldap_uri; + ldap_pool->host = host; + ldap_pool->port = (int)port_i; + + return ldap_pool; +} + +void ldap_resourcepool_destroy(LDAPResourcePool *pool) { + // unused +} + +void * ldap_resourcepool_createresource(LDAPResourcePool *respool) { + LDAP *ldap = NULL; + if(respool->ldap_uri) { + ldap = ws_ldap_resource_create_uri_connection(respool->ldap_uri, LDAP_VERSION3); + } else { + ldap = ws_ldap_resource_create_connection(respool->host, respool->port, FALSE, LDAP_VERSION3); + } + + if(!ldap) { + log_ereport( + LOG_FAILURE, + "Resource pool %s: %s: cannot create LDAP session", + respool->name, + respool->ldap_uri ? respool->ldap_uri : respool->host); + return NULL; + } + + LDAPResource *res = pool_malloc(respool->pool, sizeof(LDAPResource)); + if(!res) { + ws_ldap_close(ldap); + log_ereport(LOG_CATASTROPHE, "ldap_resourcepool_createresource: OOM"); + return NULL; + } + res->ldap = ldap; + + return res; +} + +void ldap_resourcepool_freeresource(LDAPResourcePool *pool, LDAPResource *res) { + if(res->ldap) { + ws_ldap_close(res->ldap); + } + pool_free(pool->pool, res); +} + +int ldap_resourcepool_prepare(LDAPResourcePool *pool, LDAPResource *res) { + // unused + return 0; +} + +int ldap_resourcepool_finish(LDAPResourcePool *pool, LDAPResource *res) { + // unused + return 0; +} + +void * ldap_resourcepool_getresourcedata(LDAPResource *res) { + return res->ldap; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/server/daemon/ldap_resource.h Sat Mar 11 11:56:55 2023 +0100 @@ -0,0 +1,119 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2023 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LDAP_RESOURCE_H +#define LDAP_RESOURCE_H + +#include "resourcepool.h" + +#include <ldap.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef LDAP_PORT +#define LDAP_PORT 389 +#endif +#ifndef LDAPS_PORT +#define LDAPS_PORT 636 +#endif + +typedef struct LDAPResourcePool { + /* + * ResourcePool parameters + */ + pblock *param; + + /* + * Cfg memorypool + */ + pool_handle_t *pool; + + /* + * ResourcePool name + */ + const char *name; + + /* + * ldap uri + */ + char *ldap_uri; + + /* + * ldap host + * + * only used when no ldap_uri is specified + */ + char *host; + + /* + * ldap port + */ + int port; + + +} LDAPResourcePool; + +typedef struct LDAPResource { + LDAP *ldap; +} LDAPResource; + +ResourceType* ldap_get_resource_type(void); + + +LDAP* ws_ldap_resource_create_connection( + const char *hostname, + int port, + int ssl, + int ldap_version); + +LDAP* ws_ldap_resource_create_uri_connection( + const char *uri, + int ldap_version); + +void ws_ldap_close(LDAP *ldap); + + +/* resource pool implementation functions */ +void * ldap_resourcepool_init(pool_handle_t *pool, const char *rpname, pblock *pb); +void ldap_resourcepool_destroy(LDAPResourcePool *pool); +void * ldap_resourcepool_createresource(LDAPResourcePool *respool); +void ldap_resourcepool_freeresource(LDAPResourcePool *pool, LDAPResource *res); +int ldap_resourcepool_prepare(LDAPResourcePool *pool, LDAPResource *res); +int ldap_resourcepool_finish(LDAPResourcePool *pool, LDAPResource *res); +void * ldap_resourcepool_getresourcedata(LDAPResource *res); + + + +#ifdef __cplusplus +} +#endif + +#endif /* LDAP_RESOURCE_H */ +
--- a/src/server/daemon/objs.mk Fri Mar 10 23:00:02 2023 +0100 +++ b/src/server/daemon/objs.mk Sat Mar 11 11:56:55 2023 +0100 @@ -50,6 +50,7 @@ DAEMONOBJ += event.o DAEMONOBJ += threadpools.o DAEMONOBJ += auth.o +DAEMONOBJ += ldap_resource.o DAEMONOBJ += ldap_auth.o DAEMONOBJ += keyfile_auth.o DAEMONOBJ += error.o
--- a/src/server/daemon/webserver.c Fri Mar 10 23:00:02 2023 +0100 +++ b/src/server/daemon/webserver.c Sat Mar 11 11:56:55 2023 +0100 @@ -62,6 +62,7 @@ #include "auth.h" #include "srvctrl.h" #include "resourcepool.h" +#include "ldap_resource.h" extern struct FuncStruct webserver_funcs[]; @@ -96,6 +97,10 @@ log_ereport(LOG_FAILURE, "resource pool init failed"); return -1; } + if(resourcepool_register_type("ldap", ldap_get_resource_type())) { + log_ereport(LOG_FAILURE, "webserver-init: Cannot register ldap resourcepool type"); + return -1; + } // load init.conf InitConfig *init_config = load_init_conf("config/init.conf");