diff -r 0185b13bf41f -r 09fbefc0e6a9 src/server/daemon/ldap_auth.c --- 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 #include +#include + #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;ibv_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;inmembers;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) {