add ldap resource pool type implementation

Sat, 11 Mar 2023 11:56:55 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sat, 11 Mar 2023 11:56:55 +0100
changeset 461
9b20b8f3582b
parent 460
b9a447b02046
child 462
72848970541a

add ldap resource pool type implementation

src/server/daemon/ldap_resource.c file | annotate | diff | comparison | revisions
src/server/daemon/ldap_resource.h file | annotate | diff | comparison | revisions
src/server/daemon/objs.mk file | annotate | diff | comparison | revisions
src/server/daemon/webserver.c file | annotate | diff | comparison | revisions
--- /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");

mercurial