# HG changeset patch # User Olaf Wintermann # Date 1408281332 -7200 # Node ID 09fbefc0e6a97154898427161dd20d8e10371529 # Parent 0185b13bf41f574fa7b164aa7846d251922a16ee added ldap group support diff -r 0185b13bf41f -r 09fbefc0e6a9 make/gcc.mk --- a/make/gcc.mk Mon Nov 04 10:55:27 2013 +0100 +++ b/make/gcc.mk Sun Aug 17 15:15:32 2014 +0200 @@ -31,7 +31,7 @@ CC = gcc CXX = g++ -LD = gcc +LD = g++ SHLIB_CFLAGS = -fPIC SHLIB_LDFLAGS = -shared diff -r 0185b13bf41f -r 09fbefc0e6a9 src/server/config/acl.c --- a/src/server/config/acl.c Mon Nov 04 10:55:27 2013 +0100 +++ b/src/server/config/acl.c Sun Aug 17 15:15:32 2014 +0200 @@ -64,7 +64,7 @@ ACLFile *aclf = p; UcxAllocator *mp = aclf->parser.mp; - if(sstrsuffix(line, sstr("ACL "))) { + if(sstrprefix(line, sstr("ACL "))) { sstr_t param = sstrsubs(line, 4); UcxList *plist = cfg_param_list(param, mp); ACLConfig *acl = OBJ_NEW(mp, ACLConfig); @@ -92,7 +92,7 @@ if(type.ptr) { acl->type = type; } - } else if(sstrsuffix(line, sstr("Authenticate "))) { + } else if(sstrprefix(line, sstr("Authenticate "))) { sstr_t param = sstrsubs(line, 13); UcxList *plist = cfg_param_list(param, mp); aclf->cur->authparam = plist; diff -r 0185b13bf41f -r 09fbefc0e6a9 src/server/config/keyfile.c --- a/src/server/config/keyfile.c Mon Nov 04 10:55:27 2013 +0100 +++ b/src/server/config/keyfile.c Sun Aug 17 15:15:32 2014 +0200 @@ -44,6 +44,8 @@ int r = cfg_parse_basic_file((ConfigParser*)conf, in); if(r != 0) { + fclose(in); + free(conf); // TODO: free return NULL; } diff -r 0185b13bf41f -r 09fbefc0e6a9 src/server/config/mimeconf.c --- a/src/server/config/mimeconf.c Mon Nov 04 10:55:27 2013 +0100 +++ b/src/server/config/mimeconf.c Sun Aug 17 15:15:32 2014 +0200 @@ -51,6 +51,8 @@ conf->ntypes = 0; int r = cfg_parse_basic_file((ConfigParser*)conf, in); if(r != 0) { + fclose(in); + free(conf); // TODO: free return NULL; } diff -r 0185b13bf41f -r 09fbefc0e6a9 src/server/daemon/keyfile_auth.c --- a/src/server/daemon/keyfile_auth.c Mon Nov 04 10:55:27 2013 +0100 +++ b/src/server/daemon/keyfile_auth.c Sun Aug 17 15:15:32 2014 +0200 @@ -97,8 +97,8 @@ user->groups = calloc(ngroups, sizeof(sstr_t)); for(int i=0;igroups[i] = sstrdup(groups[i]); - sstrdup(groups[i]); + user->groups[i] = sstrdup(groups[i]); + //sstrdup(groups[i]); // wtf? } // add to keyfile @@ -139,9 +139,11 @@ int ssha_verify(KeyfileUser *user, char *password) { /* * SSHA: SHA1(pw + salt) + 8 bytes salt - * the SSHA hash is already base64 decoded + * user->hash is already base64 decoded */ + // TODO: variable length salt + char *salt = user->hash + user->hashlen - 8; // last 8 bytes are the salt size_t pwlen = strlen(password); 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) { diff -r 0185b13bf41f -r 09fbefc0e6a9 src/server/daemon/ldap_auth.h --- a/src/server/daemon/ldap_auth.h Mon Nov 04 10:55:27 2013 +0100 +++ b/src/server/daemon/ldap_auth.h Sun Aug 17 15:15:32 2014 +0200 @@ -30,16 +30,21 @@ #define LDAP_AUTH_H #include "../public/auth.h" +#include #include +#include #ifdef __cplusplus extern "C" { #endif -typedef struct ldap_auth_db LDAPAuthDB; -typedef struct ldap_config LDAPConfig; -typedef struct ldap_user LDAPUser; - +typedef struct ldap_auth_db LDAPAuthDB; +typedef struct ldap_config LDAPConfig; +typedef struct ldap_user LDAPUser; +typedef struct ldap_group LDAPGroup; +typedef struct ldap_member LDAPMember; +typedef struct ldap_group_cache LDAPGroupCache; + struct ldap_config { char *hostname; int port; @@ -51,9 +56,16 @@ char *groupsearch; }; +struct ldap_group_cache { + LDAPGroup *first; + LDAPGroup *last; + UcxMap *map; +}; + struct ldap_auth_db { - AuthDB authdb; - LDAPConfig config; + AuthDB authdb; + LDAPConfig config; + LDAPGroupCache groups; }; struct ldap_user { @@ -61,12 +73,31 @@ LDAPAuthDB *authdb; LDAP *ldap; char *userdn; + int uid; + int gid; +}; + +struct ldap_member { + char *name; + int uid; +}; + +struct ldap_group { + char *name; + LDAPMember *members; + size_t nmembers; + time_t update; + LDAPGroup *next; }; AuthDB* create_ldap_authdb(char *name, LDAPConfig *conf); +LDAP* get_ldap_session(LDAPAuthDB *authdb); + User* ldap_get_user(AuthDB *sb, char *username); +LDAPGroup* ldap_get_group(LDAPAuthDB *authdb, char *group); + int ldap_user_verify_password(User *user, char *password); int ldap_user_check_group(User *user, char *group); void ldap_user_free(User *user); diff -r 0185b13bf41f -r 09fbefc0e6a9 src/server/daemon/vfs.c --- a/src/server/daemon/vfs.c Mon Nov 04 10:55:27 2013 +0100 +++ b/src/server/daemon/vfs.c Sun Aug 17 15:15:32 2014 +0200 @@ -305,9 +305,7 @@ // open directory #ifdef BSD DIR *sys_dir = opendir(path); - if(sys_dir) { - int dir_fd = dirfd(sys_dir); - } + int dir_fd = sys_dir ? dirfd(sys_dir) : 0; #else int dir_fd = open(path, O_RDONLY); if(dir_fd == -1) { diff -r 0185b13bf41f -r 09fbefc0e6a9 src/server/safs/nametrans.c --- a/src/server/safs/nametrans.c Mon Nov 04 10:55:27 2013 +0100 +++ b/src/server/safs/nametrans.c Sun Aug 17 15:15:32 2014 +0200 @@ -83,7 +83,7 @@ int document_root(pblock *pb, Session *sn, Request *rq) { char *root = pblock_findkeyval(pb_key_root, pb); if(!root) { - log_ereport(LOG_MISCONFIG, "document-root: missing rootparameter"); + log_ereport(LOG_MISCONFIG, "document-root: missing root parameter"); protocol_status(sn, rq, 500, NULL); return REQ_ABORTED; }