added ldap authentication

Sat, 29 Dec 2012 18:08:23 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sat, 29 Dec 2012 18:08:23 +0100
changeset 38
d07810b02147
parent 37
360b9aabe17e
child 39
de4bc3cd2d36

added ldap authentication

src/server/Makefile file | annotate | diff | comparison | revisions
src/server/config/conf.c file | annotate | diff | comparison | revisions
src/server/config/conf.h file | annotate | diff | comparison | revisions
src/server/daemon/authdb.c file | annotate | diff | comparison | revisions
src/server/daemon/authdb.h file | annotate | diff | comparison | revisions
src/server/daemon/config.c file | annotate | diff | comparison | revisions
src/server/daemon/httplistener.c file | annotate | diff | comparison | revisions
src/server/daemon/httprequest.c file | annotate | diff | comparison | revisions
src/server/daemon/ldap_auth.c file | annotate | diff | comparison | revisions
src/server/daemon/ldap_auth.h file | annotate | diff | comparison | revisions
src/server/daemon/objs.mk file | annotate | diff | comparison | revisions
src/server/daemon/protocol.c file | annotate | diff | comparison | revisions
src/server/daemon/session.c file | annotate | diff | comparison | revisions
src/server/daemon/session.h file | annotate | diff | comparison | revisions
src/server/daemon/webserver.c file | annotate | diff | comparison | revisions
src/server/daemon/ws-fn.c file | annotate | diff | comparison | revisions
src/server/safs/auth.c file | annotate | diff | comparison | revisions
src/server/safs/auth.h file | annotate | diff | comparison | revisions
templates/conf/mime.types file | annotate | diff | comparison | revisions
--- a/src/server/Makefile	Sat Dec 15 16:05:03 2012 +0100
+++ b/src/server/Makefile	Sat Dec 29 18:08:23 2012 +0100
@@ -31,7 +31,7 @@
 
 CFLAGS  = -xc99
 
-LDFLAGS = -pg -L/usr/lib/mps -R/usr/lib/mps -lplds4 -lplc4 -lnspr4 -lpthread -ldl -lposix4  -lsocket -lnsl -lgen -lm -lsendfile -lxerces-c
+LDFLAGS = -pg -L/usr/lib/mps -R/usr/lib/mps -lplds4 -lplc4 -lnspr4 -lpthread -ldl -lposix4  -lsocket -lnsl -lgen -lm -lsendfile -lxerces-c -lldap
 
 OBJ_DIR = $(BUILD_ROOT)build/
 
--- a/src/server/config/conf.c	Sat Dec 15 16:05:03 2012 +0100
+++ b/src/server/config/conf.c	Sat Dec 29 18:08:23 2012 +0100
@@ -286,12 +286,15 @@
     directive->directive_type = sstrdup_mp(mp, name);
     directive->type_num = cfg_get_directive_type_num(name);
     directive->condition = NULL; // set later by main parsing function
-    directive->param = NULL;
+    //directive->param = NULL;
 
     sstr_t param_str;
     param_str.ptr = name.ptr + i;
     param_str.length = line.length - i;
     param_str = sstrtrim(param_str);
+    directive->value = sstrdup_mp(mp, param_str);
+    
+    /*
     sstr_t pname;
     sstr_t pvalue;
     for(;;) {
@@ -314,12 +317,43 @@
 
         // add param to list
         
-        directive->param = ucx_list_append(directive->param, param);
+        //directive->param = ucx_list_append(directive->param, param);
     }
-
+    */
+    
     return directive;
 }
 
+UcxList* cfg_param_list(sstr_t param_str, UcxMempool *mp) {
+    sstr_t pname;
+    sstr_t pvalue;
+    UcxList *plist = NULL;
+    for(;;) {
+        param_str = cfg_param(param_str, &pname, &pvalue);
+        if(pname.length <= 0) {
+            break;
+        }
+        
+
+        // create param object
+        ConfigParam *param = OBJ_NEW(mp, ConfigParam);
+        param->name = sstrdup_mp(mp, pname);
+
+        if(pvalue.length > 0) {
+            param->value = sstrdup_mp(mp, pvalue);
+        } else {
+            param->value.ptr = NULL;
+            param->value.length = 0;
+        }
+
+        // add param to list
+        plist = ucx_list_append(plist, param); // TODO: use mp
+    }
+    return plist;
+}
+
+
+
 /*
  * gets the directive type number from a type string
  * valid types are:
@@ -519,13 +553,15 @@
         n.length = 0;
         return n;
     }
-    return cfg_directive_pstr1(d);
+    //return cfg_directive_pstr1(d);
+    return d->value;
 }
 
 /*
  * returns the name of the first parameter of the directive
  * useful for 'name value' directives
  */
+/*
 sstr_t cfg_directive_pstr1(ConfigDirective *dir) {
     if(dir->param == NULL) {
         fprintf(stderr, "%s", "Error: cfg_directive_pstr1: param is NULL\n");
@@ -538,5 +574,5 @@
     ConfigParam *p = dir->param->data;
     return p->name;
 }
+*/
 
-
--- a/src/server/config/conf.h	Sat Dec 15 16:05:03 2012 +0100
+++ b/src/server/config/conf.h	Sat Dec 29 18:08:23 2012 +0100
@@ -99,7 +99,8 @@
     ConfigLine *end;
 
     sstr_t     directive_type;
-    UcxList    *param;
+    sstr_t     value;
+    //UcxList    *param;
     ConfigTag  *condition;
     int        type_num;
 } ConfigDirective;
@@ -117,6 +118,8 @@
 
 ConfigDirective* cfg_parse_directive(sstr_t line, UcxMempool *mp);
 
+UcxList* cfg_param_list(sstr_t param_str, UcxMempool *mp);
+
 int cfg_get_directive_type_num(sstr_t type);
 
 int cfg_get_basic_type(sstr_t line);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/daemon/authdb.c	Sat Dec 29 18:08:23 2012 +0100
@@ -0,0 +1,34 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 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 <stdio.h>
+#include <stdlib.h>
+
+#include "../ucx/map.h"
+#include "authdb.h"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/daemon/authdb.h	Sat Dec 29 18:08:23 2012 +0100
@@ -0,0 +1,92 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 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 AUTHDB_H
+#define	AUTHDB_H
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef struct auth_db AuthDB;
+typedef struct user    User;   
+
+/*
+ * get a user from the authentication database
+ * 
+ * param1: authentication database
+ * param2: user
+ */
+typedef User*(*authdb_get_user_f)(AuthDB*, char*);
+
+struct auth_db {
+    char                *name;
+    /* User* get_user(AuthDB *db, char *username) */
+    authdb_get_user_f   get_user;
+};
+
+/*
+ * verify the users password
+ * 
+ * param1: user
+ * param2: password
+ */
+typedef int(*user_verify_passwd_f)(User*, char*);
+
+/*
+ * check if the user is a member of a given group
+ * 
+ * param1: user
+ * param2: group
+ */
+typedef int(*user_check_group_f)(User*, char*);
+
+/*
+ * free the user object
+ */
+typedef void(*user_free_f)(User*);
+
+struct user {
+    char                   *name;
+    /* int verify_password(User *user, char *password) */
+    user_verify_passwd_f   verify_password;
+    /* int check_group(User *user, char *group) */
+    user_check_group_f     check_group;
+    /* void free(User*) */
+    user_free_f            free;
+};
+
+
+
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* AUTHDB_H */
+
--- a/src/server/daemon/config.c	Sat Dec 15 16:05:03 2012 +0100
+++ b/src/server/daemon/config.c	Sat Dec 29 18:08:23 2012 +0100
@@ -46,6 +46,7 @@
 #include "log.h"
 #include "event.h"
 #include "threadpools.h"
+#include "ldap_auth.h"
 #include "configmanager.h"
 
 #include "vserver.h"
@@ -61,6 +62,7 @@
     printf("load_init_conf\n");
 
     InitConfig *cfg = load_init_config(file);
+    UcxMempool *mp = cfg->parser.mp;
     if(cfg == NULL) {
         return;
     }
@@ -73,7 +75,7 @@
         /* create NSAPI directive */
         directive *d = malloc(sizeof(directive));
         d->param = pblock_create_pool(cfg_pool, 8);
-        UcxList *param = dir->param;
+        UcxList *param = cfg_param_list(dir->value, mp);
         while(param != NULL) {
             ConfigParam *p = param->data;
             pblock_nvlinsert(
@@ -116,6 +118,7 @@
     serverconfig->pool = pool_create();
     serverconfig->listeners = NULL;
     serverconfig->host_vs = ucx_map_new(16);
+    serverconfig->authdbs = ucx_map_new(16);
     // TODO: init serverconfig stuff
     
     
@@ -351,7 +354,57 @@
 }
 
 int cfg_handle_authdb(ServerConfiguration *cfg, ServerConfigObject *obj) {
-    /* TODO: authdb*/
+    sstr_t name = cfg_directivelist_get_str(obj->directives, sstr("Name"));
+    sstr_t type = cfg_directivelist_get_str(obj->directives, sstr("Type"));
+    
+    if(!sstrcmp(type, sstr("ldap"))) {
+        LDAPConfig conf;
+        
+        sstr_t host = cfg_directivelist_get_str(
+                obj->directives,
+                sstr("Host"));
+        sstr_t port = cfg_directivelist_get_str(
+                obj->directives,
+                sstr("Port"));
+        sstr_t basedn = cfg_directivelist_get_str(
+                obj->directives,
+                sstr("BaseDN"));
+        sstr_t binddn = cfg_directivelist_get_str(
+                obj->directives,
+                sstr("BindDN"));
+        sstr_t basepw = cfg_directivelist_get_str(
+                obj->directives,
+                sstr("BindPW"));
+        
+        host = sstrdup(host);
+        port = sstrdup(port);
+        basedn = sstrdup(basedn);
+        binddn = sstrdup(binddn);
+        basepw = sstrdup(basepw);
+        
+        conf.hostname = host.ptr;
+        conf.port = atoi(port.ptr);
+        conf.basedn = basedn.ptr;
+        conf.binddn = binddn.ptr;
+        conf.bindpw = basepw.ptr;
+        
+        name = sstrdup(name);
+        
+        AuthDB *authdb = create_ldap_authdb(name.ptr, &conf);
+        printf("authdb: %d\n", authdb);
+        ucx_map_sstr_put(cfg->authdbs, name, authdb);
+        
+        // TODO: create_ldap_authdb should copy the strings
+        /*
+        free(host.ptr);
+        free(port.ptr);
+        free(basedn.ptr);
+        free(binddn.ptr);
+        free(basepw.ptr);
+        free(name.ptr);
+        */
+        
+    }
 
     return 0;
 }
@@ -440,6 +493,7 @@
 
     // new conf function test
     ObjectConfig *cfg = load_object_config(file);
+    UcxMempool   *mp = cfg->parser.mp;
     if(cfg == NULL) {
         return NULL;
     }
@@ -486,7 +540,7 @@
                 d->param = pblock_create_pool(conf->pool, 8);
 
                 /* add params */
-                UcxList *param = cfgdir->param;
+                UcxList *param = cfg_param_list(cfgdir->value, mp);
                 while(param != NULL) {
                     ConfigParam *p = param->data;
                     pblock_nvlinsert(
--- a/src/server/daemon/httplistener.c	Sat Dec 15 16:05:03 2012 +0100
+++ b/src/server/daemon/httplistener.c	Sat Dec 29 18:08:23 2012 +0100
@@ -137,6 +137,7 @@
     // end remove
 
     HttpListener *listener = malloc(sizeof(HttpListener));
+    listener->cfg = conf->cfg;
     listener->name = conf->name;
     listener->default_vs.vs_name = conf->vs.ptr;
     if(conf->threadpool.ptr != NULL) {
@@ -279,6 +280,8 @@
                 conn);
 
         /* ready for new connection */
+        
+        // this acceptor is outdated
         if(acceptor_exit) {
             break;
         }
--- a/src/server/daemon/httprequest.c	Sat Dec 15 16:05:03 2012 +0100
+++ b/src/server/daemon/httprequest.c	Sat Dec 29 18:08:23 2012 +0100
@@ -83,6 +83,9 @@
     sn->sn.next = NULL;
     sn->sn.fill = 1;
     sn->sn.subject = NULL;
+    
+    // the session needs the current server configuration
+    sn->config = request->connection->listener->cfg; // TODO: ref
 
     /* add ip to sn->client pblock */
     char ip_str[INET_ADDRSTRLEN];
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/daemon/ldap_auth.c	Sat Dec 29 18:08:23 2012 +0100
@@ -0,0 +1,136 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "ldap_auth.h"
+
+AuthDB* create_ldap_authdb(char *name, LDAPConfig *conf) {
+    LDAPAuthDB *authdb = malloc(sizeof (LDAPAuthDB));
+    authdb->authdb.name = strdup(name);
+    authdb->authdb.get_user = ldap_get_user;
+    authdb->config = *conf;
+
+    if (!authdb->config.usersearch) {
+        authdb->config.usersearch = "uid";
+    }
+    if (!authdb->config.groupsearch) {
+        authdb->config.groupsearch = "uniquemember";
+    }
+
+    return (AuthDB*) authdb;
+}
+
+User* ldap_get_user(AuthDB *db, char *username) {
+    LDAPAuthDB *authdb = (LDAPAuthDB*) db;
+    LDAPConfig *config = &authdb->config;
+
+    LDAP *ld = ldap_init(config->hostname, config->port);
+    if (ld == NULL) {
+        fprintf(stderr, "ldap_init failed\n");
+        return NULL;
+    }
+
+    int r = ldap_simple_bind_s(ld, config->binddn, config->bindpw);
+    if (r != LDAP_SUCCESS) {
+        ldap_unbind(ld);
+        fprintf(stderr, "ldap_simple_bind_s failed: %s\n", ldap_err2string(r));
+        return NULL;
+    }
+
+    // get the user dn
+
+    // TODO: use config for filter
+    char filter[128];
+    int s = snprintf(filter, 127, "uid=%s", username);
+    filter[s] = 0;
+
+    LDAPMessage *result;
+    r = ldap_search_s(
+            ld,
+            config->basedn,
+            LDAP_SCOPE_SUBTREE,
+            filter,
+            NULL,
+            0,
+            &result);
+    if (r != LDAP_SUCCESS) {
+        ldap_unbind(ld);
+        fprintf(stderr, "ldap_search_s failed\n");
+        return NULL;
+    }
+
+    LDAPMessage *msg = ldap_first_entry(ld, result);
+    if (msg) {
+        LDAPUser *user = malloc(sizeof (LDAPUser));
+        if (user != NULL) {
+            user->user.verify_password = ldap_user_verify_password;
+            user->user.check_group = ldap_user_check_group;
+            user->user.free = ldap_user_free;
+            user->user.name = username; // must not be freed
+
+            user->ldap = ld;
+            user->userdn = ldap_get_dn(ld, msg);
+
+            ldap_msgfree(result);
+
+            return (User*)user;
+        }
+    }
+
+    ldap_unbind(ld);
+    return NULL;
+}
+
+int ldap_user_verify_password(User *u, char *password) {
+    LDAPUser *user = (LDAPUser*)u;
+    
+    int r = ldap_simple_bind_s(user->ldap, user->userdn, password);
+    if(r == LDAP_SUCCESS) {
+        printf("ldap password ok\n");
+        return 1;
+    } else {
+        printf("ldap password not ok\n");
+        return 0;
+    }
+}
+
+int ldap_user_check_group(User *user, char *group) {
+    // TODO
+    return 0;
+}
+
+void ldap_user_free(User *u) {
+    LDAPUser *user = (LDAPUser*) u;
+    ldap_memfree(user->userdn);
+    // TODO: use connection pool
+    ldap_unbind(user->ldap);
+    free(user);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/server/daemon/ldap_auth.h	Sat Dec 29 18:08:23 2012 +0100
@@ -0,0 +1,79 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2011 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_AUTH_H
+#define	LDAP_AUTH_H
+
+#include "authdb.h"
+#include <ldap.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef struct ldap_auth_db LDAPAuthDB; 
+typedef struct ldap_config  LDAPConfig;
+typedef struct ldap_user    LDAPUser;
+   
+struct ldap_config {
+    char   *hostname;
+    int    port;
+    int    ssl;
+    char   *basedn;
+    char   *binddn;
+    char   *bindpw;
+    char   *usersearch;
+    char   *groupsearch;
+};
+
+struct ldap_auth_db {
+    AuthDB     authdb;
+    LDAPConfig config;
+};
+
+struct ldap_user {
+    User         user;
+    LDAPAuthDB   *authdb;
+    LDAP         *ldap;
+    char         *userdn;
+};
+
+AuthDB* create_ldap_authdb(char *name, LDAPConfig *conf);
+
+User* ldap_get_user(AuthDB *sb, char *username);
+
+int ldap_user_verify_password(User *user, char *password);
+int ldap_user_check_group(User *user, char *group);
+void ldap_user_free(User *user);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* LDAP_AUTH_H */
+
--- a/src/server/daemon/objs.mk	Sat Dec 15 16:05:03 2012 +0100
+++ b/src/server/daemon/objs.mk	Sat Dec 29 18:08:23 2012 +0100
@@ -47,6 +47,8 @@
 DAEMONOBJ += log.o
 DAEMONOBJ += event.o
 DAEMONOBJ += threadpools.o
+DAEMONOBJ += authdb.o
+DAEMONOBJ += ldap_auth.o
 
 #ifeq ($(OS), SunOS)
 DAEMONOBJ += event_solaris.o
--- a/src/server/daemon/protocol.c	Sat Dec 15 16:05:03 2012 +0100
+++ b/src/server/daemon/protocol.c	Sat Dec 29 18:08:23 2012 +0100
@@ -308,6 +308,8 @@
     sbuf_free(out);
     
     rq->senthdrs = 1;
+    
+    return 0;
 }
 
 int request_header(char *name, char **value, Session *sn, Request *rq) {
@@ -317,6 +319,8 @@
         *value = pp->value;
         return REQ_PROCEED;
     } else {
-        return REQ_ABORTED;
+        //return REQ_ABORTED;
+        *value = NULL;
+        return REQ_NOACTION;
     }
 }
--- a/src/server/daemon/session.c	Sat Dec 15 16:05:03 2012 +0100
+++ b/src/server/daemon/session.c	Sat Dec 29 18:08:23 2012 +0100
@@ -34,3 +34,9 @@
     // TODO: implement
     return NULL;
 }
+
+
+NSAPI_PUBLIC void* session_get_config(Session *s) {
+    NSAPISession *sn = (NSAPISession*)s;
+    return sn->config;
+}
--- a/src/server/daemon/session.h	Sat Dec 15 16:05:03 2012 +0100
+++ b/src/server/daemon/session.h	Sat Dec 29 18:08:23 2012 +0100
@@ -31,6 +31,7 @@
 
 #include "../public/nsapi.h"
 #include "../util/thrpool.h"
+#include "config.h"
 
 #ifdef	__cplusplus
 extern "C" {
@@ -43,10 +44,17 @@
     int          sys_fd; /* system file descriptor */
     threadpool_t *currentpool;
     threadpool_t *defaultpool;
+    
+    ServerConfiguration *config;
 };
 
 NSAPI_PUBLIC char *session_dns_lookup(Session *s, int verify);
 
+/* new functions */
+
+// get the server configuration of this session
+NSAPI_PUBLIC void* session_get_config(Session *s);
+
 #ifdef	__cplusplus
 }
 #endif
--- a/src/server/daemon/webserver.c	Sat Dec 15 16:05:03 2012 +0100
+++ b/src/server/daemon/webserver.c	Sat Dec 29 18:08:23 2012 +0100
@@ -38,6 +38,7 @@
 #include "config.h"
 #include "configmanager.h"
 #include "httplistener.h"
+#include "authdb.h"
 #include "webserver.h"
 #include "log.h"
 
@@ -52,7 +53,7 @@
     // init NSAPI functions
     func_init();
     add_functions(webserver_funcs);
-
+    
     // load init.conf
     load_init_conf("conf/init.conf");
 
--- a/src/server/daemon/ws-fn.c	Sat Dec 15 16:05:03 2012 +0100
+++ b/src/server/daemon/ws-fn.c	Sat Dec 29 18:08:23 2012 +0100
@@ -52,6 +52,7 @@
     { "webdav-service", webdav_service, NULL, 0},
     { "admin-index", adm_index, NULL, 0},
     { "auth-basic", auth_basic, NULL, 0 },
+    { "auth-db", auth_db, NULL, 0 },
     { "require-auth", require_auth, NULL, 0},
     { "print-message", print_message, NULL, 0},
     {NULL, NULL, NULL, 0}
--- a/src/server/safs/auth.c	Sat Dec 15 16:05:03 2012 +0100
+++ b/src/server/safs/auth.c	Sat Dec 29 18:08:23 2012 +0100
@@ -33,6 +33,10 @@
 
 #include <strings.h>
 
+#include "../daemon/authdb.h"
+#include "../daemon/config.h"
+#include "../daemon/session.h"
+
 #include "auth.h"
 
 
@@ -197,3 +201,82 @@
     free(user);
     return ret;
 }
+
+int auth_db(pblock *param, Session *sn, Request *rq) {
+    // TODO: reimplement this function and auth_basic to avoid code redundancy
+    
+    //pblock *npb;
+    //pb_param *pp;
+    //int ret;
+
+    char *auth;
+    char *db;
+    char *user;
+    char *pw;
+    
+    if(request_header("authorization", &auth, sn, rq) == REQ_ABORTED)
+        return REQ_ABORTED;
+
+    if(!auth)
+        return REQ_NOACTION;
+
+    db = pblock_findval("db", param);
+
+    if(!db) {
+        // TODO: log error
+        //log_error(LOG_MISCONFIG, "basic-auth", sn, rq,
+        //          XP_GetAdminStr(DBT_authError1));
+        protocol_status(sn, rq, PROTOCOL_SERVER_ERROR, NULL);
+        return REQ_ABORTED;
+    }
+
+    /* Skip leading whitespace */
+    while(*auth && (*auth == ' '))
+        ++auth;
+    if(!(*auth)) {
+        protocol_status(sn, rq, PROTOCOL_FORBIDDEN, NULL);
+        return REQ_ABORTED;
+    }
+
+    /* Verify correct type */
+    if((strlen(auth) < 6) || strncasecmp(auth, "basic ", 6))
+        return REQ_NOACTION;
+
+    /* Skip whitespace */
+    auth += 6;
+    while(*auth && (*auth == ' '))
+        ++auth;
+
+    if(!*auth)
+        return REQ_NOACTION;
+
+    /* Uuencoded user:password now */
+    if(!(user = _uudecode(auth)))
+        return REQ_NOACTION;
+
+    if(!(pw = strchr(user, ':'))) {
+        free(user);
+        return REQ_NOACTION;
+    }
+    *pw++ = '\0';
+
+    // get auth db
+    ServerConfiguration *config = session_get_config(sn);
+    sstr_t dbname = sstr(db);
+    AuthDB *authdb = ucx_map_sstr_get(config->authdbs, dbname);
+    
+    User *auth_user = authdb->get_user(authdb, user);
+    if(auth_user && !auth_user->verify_password(auth_user, pw)) {
+        fprintf(stderr, "authdb user not authenticated: %s\n", user);
+        free(user);
+        return REQ_NOACTION;
+    }
+    
+
+    pblock_nvinsert("auth-type", "basic", rq->vars);
+    pblock_nvinsert("auth-user", user, rq->vars);
+    pblock_nvinsert("auth-db", db, rq->vars);
+    
+    free(user);
+    return REQ_PROCEED;
+}
--- a/src/server/safs/auth.h	Sat Dec 15 16:05:03 2012 +0100
+++ b/src/server/safs/auth.h	Sat Dec 29 18:08:23 2012 +0100
@@ -37,6 +37,8 @@
 
 int auth_basic(pblock *param, Session *sn, Request *rq);
 
+int auth_db(pblock *param, Session *sn, Request *rq);
+
 
 #ifdef	__cplusplus
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/templates/conf/mime.types	Sat Dec 29 18:08:23 2012 +0100
@@ -0,0 +1,16 @@
+type=image/png                                   exts=png
+type=image/x-icon                                exts=ico
+type=image/gif                                   exts=gif
+type=image/jpeg                                  exts=jpeg,jpg,jpe,jfif,pjpeg,pjp
+type=image/tiff                                  exts=tiff,tif
+type=image/bmp                                   exts=bmp
+type=application/pdf                             exts=pdf
+type=application/postscript                      exts=ai,eps,ps
+type=application/x-sh                            exts=sh
+type=text/css                                    exts=css
+type=text/html                                   exts=htm,html
+type=text/plain                                  exts=txt
+type=text/xml                                    exts=xml
+type=application/x-javascript                    exts=js
+type=application/x-javascript;charset=UTF-8      exts=jsu
+type=application/x-tex                           exts=tex

mercurial