src/server/daemon/ldap_auth.c

changeset 97
09fbefc0e6a9
parent 91
fac51f87def0
child 101
7fbcdbad0baa
--- a/src/server/daemon/ldap_auth.c	Mon Nov 04 10:55:27 2013 +0100
+++ b/src/server/daemon/ldap_auth.c	Sun Aug 17 15:15:32 2014 +0200
@@ -34,6 +34,8 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include <ucx/utils.h>
+
 #include "ldap_auth.h"
 
 static void ws_ldap_close(LDAP *ldap) {
@@ -57,14 +59,17 @@
     if (!authdb->config.groupsearch) {
         authdb->config.groupsearch = "uniquemember";
     }
+    
+    // initialize group cache
+    authdb->groups.first = NULL;
+    authdb->groups.last = NULL;
+    authdb->groups.map = ucx_map_new(32);
 
     return (AuthDB*) authdb;
 }
 
-User* ldap_get_user(AuthDB *db, char *username) {
-    LDAPAuthDB *authdb = (LDAPAuthDB*) db;
+LDAP* get_ldap_session(LDAPAuthDB *authdb) {
     LDAPConfig *config = &authdb->config;
-
     LDAP *ld = NULL;
 #ifdef LINUX
     char *ldap_uri = NULL;
@@ -74,19 +79,17 @@
     if(init_ret) {
         fprintf(stderr, "ldap_initialize failed\n");
     }
-    
 #else
     ld = ldap_init(config->hostname, config->port);
 #endif
-    if (ld == NULL) {
-        fprintf(stderr, "ldap_init failed\n");
+    if(!ld) {
         return NULL;
     }
     
     int ldapv = LDAP_VERSION3;
     ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &ldapv);
-
-    //int r = ldap_simple_bind_s(ld, config->binddn, config->bindpw);
+    
+    // admin bind
     struct berval cred;
     cred.bv_val = config->bindpw;
     cred.bv_len = strlen(config->bindpw);
@@ -101,14 +104,26 @@
             &server_cred);
     if (r != LDAP_SUCCESS) {
         ws_ldap_close(ld);
-        
         fprintf(stderr, "ldap_simple_bind_s failed: %s\n", ldap_err2string(r));
         return NULL;
     }
+    
+    return ld;
+}
+
+User* ldap_get_user(AuthDB *db, char *username) {
+    LDAPAuthDB *authdb = (LDAPAuthDB*) db;
+    LDAPConfig *config = &authdb->config;
+
+    LDAP *ld = get_ldap_session(authdb);
+    if (ld == NULL) {
+        fprintf(stderr, "ldap_init failed\n");
+        return NULL;
+    }
 
     // get the user dn
-
     // TODO: use config for filter
+    // TODO: use asprintf
     char filter[128];
     int s = snprintf(filter, 127, "uid=%s", username);
     filter[s] = 0;
@@ -117,7 +132,7 @@
     struct timeval timeout;
     timeout.tv_sec = 8;
     timeout.tv_usec = 0;
-    r = ldap_search_ext_s(
+    int r = ldap_search_ext_s(
             ld,
             config->basedn,
             LDAP_SCOPE_SUBTREE,
@@ -140,6 +155,7 @@
     if (msg) {
         LDAPUser *user = malloc(sizeof(LDAPUser));
         if (user != NULL) {
+            user->authdb = authdb;
             user->user.verify_password = ldap_user_verify_password;
             user->user.check_group = ldap_user_check_group;
             user->user.free = ldap_user_free;
@@ -162,6 +178,97 @@
     return NULL;
 }
 
+LDAPGroup* ldap_get_group(LDAPAuthDB *authdb, char *group) {
+    printf("ldap_get_group: %s\n", group);
+    
+    LDAPConfig *config = &authdb->config;
+    
+    LDAP *ld = get_ldap_session(authdb);
+    if (ld == NULL) {
+        fprintf(stderr, "ldap_init failed\n");
+        return NULL;
+    }
+    
+    // get the user dn
+    // TODO: use config for filter
+    // TODO: use asprintf
+    char filter[128];
+    int s = snprintf(filter, 127, "cn=%s", group);
+    filter[s] = 0;
+
+    LDAPMessage *result;
+    struct timeval timeout;
+    timeout.tv_sec = 8;
+    timeout.tv_usec = 0;
+    int r = ldap_search_ext_s(
+            ld,
+            config->basedn,
+            LDAP_SCOPE_SUBTREE,
+            filter,
+            NULL,
+            0,
+            NULL,        // server controls
+            NULL,        // client controls
+            &timeout,
+            1,           // size limit
+            &result);
+    if (r != LDAP_SUCCESS) {
+        ws_ldap_close(ld);
+        
+        fprintf(stderr, "ldap_search_ext_s failed\n");
+        return NULL;
+    }
+    
+    LDAPGroup *wsgroup = NULL;
+    LDAPMessage *msg = ldap_first_entry(ld, result);
+    if (msg) {
+        // create group object
+        wsgroup = malloc(sizeof(LDAPGroup));
+        wsgroup->name = strdup(group);
+        wsgroup->members = NULL;
+        wsgroup->nmembers = 0;
+        wsgroup->update = 0;
+        wsgroup->next = NULL;
+        
+        // get attributes
+        BerElement *ber = NULL;
+        char *attribute = attribute=ldap_first_attribute(ld, msg, &ber);
+        while(attribute != NULL) {
+            printf("attribute: %s\n", attribute);
+            if(!strcasecmp(attribute, "memberuid")) {
+                // get all memberuid values and add the users to the group obj
+                
+                struct berval **values = ldap_get_values_len(ld, msg, attribute);
+                if(values) {
+                    int count = ldap_count_values_len(values);
+                    wsgroup->members = calloc(count, sizeof(LDAPMember));
+                    wsgroup->nmembers = count;
+                    for(int i=0;i<count;i++) {
+                        sstr_t member = sstrn(
+                                values[i]->bv_val,
+                                values[i]->bv_len);
+                        wsgroup->members[i].name = sstrdup(member).ptr;
+                        // TODO: uid?
+                        printf("added member: %.*s\n", member.length, member.ptr);
+                    }
+                }
+            }
+            
+            attribute = ldap_next_attribute(ld, msg, ber); 
+        }
+        
+        if(ber) {
+            //ldap_ber_free(ber, 0);
+        }
+        if(attribute) {
+            ldap_memfree(attribute);
+        }
+    }
+    
+    ws_ldap_close(ld);
+    return wsgroup;
+}
+
 int ldap_user_verify_password(User *u, char *password) {
     LDAPUser *user = (LDAPUser*)u;
     
@@ -187,9 +294,23 @@
     }
 }
 
-int ldap_user_check_group(User *user, char *group) {
-    // TODO
-    return 0;
+int ldap_user_check_group(User *u, char *group_str) {
+    LDAPUser *user = (LDAPUser*)u;
+    
+    int ret = 0;
+    
+    LDAPGroup *group = ldap_get_group(user->authdb, group_str);
+    for(int i=0;i<group->nmembers;i++) {
+        char *member = group->members[i].name;
+        if(!strcmp(member, u->name)) {
+            printf("is member\n");
+            ret = 1;
+        }
+    }
+    
+    // TODO: free or cache group
+    
+    return ret;
 }
 
 void ldap_user_free(User *u) {

mercurial