src/server/daemon/ldap_auth.c

Sun, 17 Mar 2013 12:47:59 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 17 Mar 2013 12:47:59 +0100
changeset 55
b7908bf38f9f
parent 49
1fd94945796e
child 63
66442f81f823
permissions
-rw-r--r--

vfs can read directories

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 2013 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 ldapv = 3;
    ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &ldapv);

    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);
}

mercurial