passdb-ldap.c revision 35136dd2baf8dc30e4e754294ed81ff48e8c1e64
a11689fe3fbb3bca11b9cb4ae5faf27db96401ccTimo Sirainen/* Copyright (C) 2003 Timo Sirainen */
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include "common.h"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#ifdef PASSDB_LDAP
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include "hash.h"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include "str.h"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include "var-expand.h"
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen#include "password-scheme.h"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include "auth-cache.h"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include "db-ldap.h"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include "passdb.h"
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen#include <ldap.h>
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen#include <stdlib.h>
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenstatic const char *default_attr_map[] = {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen "user", "password", NULL
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen};
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainenstruct ldap_passdb_module {
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen struct passdb_module module;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen struct ldap_connection *conn;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen};
d595049948579def2d82718dbce0a6b49a281402Timo Sirainen
d595049948579def2d82718dbce0a6b49a281402Timo Sirainenstruct passdb_ldap_request {
d595049948579def2d82718dbce0a6b49a281402Timo Sirainen struct ldap_request request;
d595049948579def2d82718dbce0a6b49a281402Timo Sirainen
d595049948579def2d82718dbce0a6b49a281402Timo Sirainen union {
d595049948579def2d82718dbce0a6b49a281402Timo Sirainen verify_plain_callback_t *verify_plain;
d595049948579def2d82718dbce0a6b49a281402Timo Sirainen lookup_credentials_callback_t *lookup_credentials;
d595049948579def2d82718dbce0a6b49a281402Timo Sirainen } callback;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen};
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainenstruct ldap_query_save_context {
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen struct ldap_connection *conn;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen struct auth_request *auth_request;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen LDAPMessage *entry;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen string_t *debug;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen unsigned int userdb_fields:1;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen unsigned int add_userdb_uid:1;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen unsigned int add_userdb_gid:1;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen};
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainenstatic void
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainenldap_query_save_attr(struct ldap_query_save_context *ctx, const char *attr)
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen{
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen struct auth *auth = ctx->auth_request->auth;
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen const char *name;
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen char **vals;
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen unsigned int i;
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen name = hash_lookup(ctx->conn->pass_attr_map, attr);
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen if (auth->verbose_debug) {
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen if (ctx->debug == NULL)
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen ctx->debug = t_str_new(256);
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen else
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen str_append_c(ctx->debug, ' ');
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen str_append(ctx->debug, attr);
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen str_printfa(ctx->debug, "(%s)=",
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen name != NULL ? name : "?unknown?");
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen }
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen if (name == NULL)
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen return;
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen if (strncmp(name, "userdb_", 7) == 0) {
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen /* in case we're trying to use prefetch userdb,
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen see if we need to add global uid/gid */
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen if (!ctx->userdb_fields) {
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen ctx->add_userdb_uid = ctx->add_userdb_gid = TRUE;
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen ctx->userdb_fields = TRUE;
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen }
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen if (strcmp(name, "userdb_uid") == 0)
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen ctx->add_userdb_uid = FALSE;
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen else if (strcmp(name, "userdb_gid") == 0)
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen ctx->add_userdb_gid = FALSE;
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen }
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen vals = ldap_get_values(ctx->conn->ld, ctx->entry, attr);
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen if (vals != NULL && *name != '\0') {
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen for (i = 0; vals[i] != NULL; i++) {
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen if (ctx->debug != NULL) {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (i != 0)
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen str_append_c(ctx->debug, '/');
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen if (auth->verbose_debug_passwords ||
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen strcmp(name, "password") != 0)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen str_append(ctx->debug, vals[i]);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen else {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen str_append(ctx->debug,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen PASSWORD_HIDDEN_STR);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen }
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen }
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen auth_request_set_field(ctx->auth_request, name, vals[i],
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen ctx->conn->set.default_pass_scheme);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen }
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen }
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen ldap_value_free(vals);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen}
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenstatic void
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenldap_query_save_result(struct ldap_connection *conn, LDAPMessage *entry,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen struct auth_request *auth_request)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen{
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen struct ldap_query_save_context ctx;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen BerElement *ber;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen char *attr;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen memset(&ctx, 0, sizeof(ctx));
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen ctx.conn = conn;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen ctx.auth_request = auth_request;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen ctx.entry = entry;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen attr = ldap_first_attribute(conn->ld, entry, &ber);
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen while (attr != NULL) {
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen ldap_query_save_attr(&ctx, attr);
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen ldap_memfree(attr);
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen attr = ldap_next_attribute(conn->ld, entry, ber);
bbc30fd4fa86723f6a72309ad3a2a96f34eabd6cTimo Sirainen }
bbc30fd4fa86723f6a72309ad3a2a96f34eabd6cTimo Sirainen
bbc30fd4fa86723f6a72309ad3a2a96f34eabd6cTimo Sirainen if (ctx.add_userdb_uid && conn->set.uid != (uid_t)-1) {
bbc30fd4fa86723f6a72309ad3a2a96f34eabd6cTimo Sirainen auth_request_set_field(auth_request, "userdb_uid",
bbc30fd4fa86723f6a72309ad3a2a96f34eabd6cTimo Sirainen dec2str(conn->set.uid), NULL);
bbc30fd4fa86723f6a72309ad3a2a96f34eabd6cTimo Sirainen }
bbc30fd4fa86723f6a72309ad3a2a96f34eabd6cTimo Sirainen if (ctx.add_userdb_gid && conn->set.gid != (gid_t)-1) {
bbc30fd4fa86723f6a72309ad3a2a96f34eabd6cTimo Sirainen auth_request_set_field(auth_request, "userdb_gid",
bbc30fd4fa86723f6a72309ad3a2a96f34eabd6cTimo Sirainen dec2str(conn->set.gid), NULL);
bbc30fd4fa86723f6a72309ad3a2a96f34eabd6cTimo Sirainen }
bbc30fd4fa86723f6a72309ad3a2a96f34eabd6cTimo Sirainen
bbc30fd4fa86723f6a72309ad3a2a96f34eabd6cTimo Sirainen if (ctx.debug != NULL) {
bbc30fd4fa86723f6a72309ad3a2a96f34eabd6cTimo Sirainen auth_request_log_debug(auth_request, "ldap",
bbc30fd4fa86723f6a72309ad3a2a96f34eabd6cTimo Sirainen "result: %s", str_c(ctx.debug));
bbc30fd4fa86723f6a72309ad3a2a96f34eabd6cTimo Sirainen }
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen}
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainenstatic LDAPMessage *
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainenhandle_request_get_entry(struct ldap_connection *conn,
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen struct auth_request *auth_request,
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen struct passdb_ldap_request *request, LDAPMessage *res)
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen{
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen enum passdb_result passdb_result;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen LDAPMessage *entry;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen int ret;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen passdb_result = PASSDB_RESULT_INTERNAL_FAILURE;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen if (res != NULL) {
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen /* LDAP query returned something */
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen ret = ldap_result2error(conn->ld, res, 0);
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen if (ret != LDAP_SUCCESS) {
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen auth_request_log_error(auth_request, "ldap",
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen "ldap_search(%s) failed: %s",
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen request->request.filter,
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen ldap_err2string(ret));
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen } else {
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen /* get the reply */
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen entry = ldap_first_entry(conn->ld, res);
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen if (entry != NULL) {
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen /* success */
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen return entry;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen }
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen /* no entries returned */
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen auth_request_log_info(auth_request, "ldap",
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen "unknown user");
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen passdb_result = PASSDB_RESULT_USER_UNKNOWN;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen }
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen }
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen request->callback.verify_plain(passdb_result, auth_request);
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen auth_request_unref(&auth_request);
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen return NULL;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen}
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainenstatic void handle_request(struct ldap_connection *conn,
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen struct ldap_request *request, LDAPMessage *res)
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen{
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen struct passdb_ldap_request *ldap_request =
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen (struct passdb_ldap_request *)request;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen struct auth_request *auth_request = request->context;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen enum passdb_result passdb_result;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen LDAPMessage *entry;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen const char *password, *scheme;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen int ret;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen entry = handle_request_get_entry(conn, auth_request, ldap_request, res);
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen if (entry == NULL)
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen return;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen /* got first LDAP entry */
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen passdb_result = PASSDB_RESULT_INTERNAL_FAILURE;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen password = NULL;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen ldap_query_save_result(conn, entry, auth_request);
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen if (auth_request->passdb_password == NULL) {
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen auth_request_log_error(auth_request, "ldap",
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen "No password in reply");
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen } else if (ldap_next_entry(conn->ld, entry) != NULL) {
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen auth_request_log_error(auth_request, "ldap",
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen "Multiple password replies");
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen } else {
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen /* passdb_password may change on the way,
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen so we'll need to strdup. */
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen password = t_strdup(auth_request->passdb_password);
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen if (password == NULL)
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen auth_request->no_password = TRUE;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen passdb_result = PASSDB_RESULT_OK;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen }
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen scheme = password_get_scheme(&password);
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen /* auth_request_set_field() sets scheme */
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen i_assert(password == NULL || scheme != NULL);
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen if (auth_request->credentials != -1) {
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen passdb_handle_credentials(passdb_result, password, scheme,
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen ldap_request->callback.lookup_credentials,
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen auth_request);
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen auth_request_unref(&auth_request);
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen return;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen }
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen /* verify plain */
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen if (password == NULL) {
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen ldap_request->callback.verify_plain(passdb_result,
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen auth_request);
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen auth_request_unref(&auth_request);
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen return;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen }
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen ret = auth_request_password_verify(auth_request,
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen auth_request->mech_password,
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen password, scheme, "ldap");
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen ldap_request->callback.verify_plain(ret > 0 ? PASSDB_RESULT_OK :
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen PASSDB_RESULT_PASSWORD_MISMATCH,
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen auth_request);
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen auth_request_unref(&auth_request);
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen}
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainenstatic void authbind_start(struct ldap_connection *conn,
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen struct ldap_request *ldap_request)
1b33e848e84e6f74aa0e3339c32fa96bc15102a2Timo Sirainen{
1b33e848e84e6f74aa0e3339c32fa96bc15102a2Timo Sirainen struct passdb_ldap_request *passdb_ldap_request =
1b33e848e84e6f74aa0e3339c32fa96bc15102a2Timo Sirainen (struct passdb_ldap_request *)ldap_request;
1b33e848e84e6f74aa0e3339c32fa96bc15102a2Timo Sirainen struct auth_request *auth_request = ldap_request->context;
1b33e848e84e6f74aa0e3339c32fa96bc15102a2Timo Sirainen int msgid;
1b33e848e84e6f74aa0e3339c32fa96bc15102a2Timo Sirainen
1b33e848e84e6f74aa0e3339c32fa96bc15102a2Timo Sirainen if (!conn->connecting) {
1b33e848e84e6f74aa0e3339c32fa96bc15102a2Timo Sirainen /* switch back to the default dn before doing the next search
1b33e848e84e6f74aa0e3339c32fa96bc15102a2Timo Sirainen request */
1b33e848e84e6f74aa0e3339c32fa96bc15102a2Timo Sirainen conn->last_auth_bind = TRUE;
1b33e848e84e6f74aa0e3339c32fa96bc15102a2Timo Sirainen
1b33e848e84e6f74aa0e3339c32fa96bc15102a2Timo Sirainen /* the DN is kept in base variable, a bit ugly.. */
1b33e848e84e6f74aa0e3339c32fa96bc15102a2Timo Sirainen msgid = ldap_bind(conn->ld, ldap_request->base,
1b33e848e84e6f74aa0e3339c32fa96bc15102a2Timo Sirainen auth_request->mech_password,
1b33e848e84e6f74aa0e3339c32fa96bc15102a2Timo Sirainen LDAP_AUTH_SIMPLE);
1b33e848e84e6f74aa0e3339c32fa96bc15102a2Timo Sirainen if (msgid == -1) {
1b33e848e84e6f74aa0e3339c32fa96bc15102a2Timo Sirainen i_error("ldap_bind(%s) failed: %s",
1b33e848e84e6f74aa0e3339c32fa96bc15102a2Timo Sirainen ldap_request->base, ldap_get_error(conn));
1b33e848e84e6f74aa0e3339c32fa96bc15102a2Timo Sirainen passdb_ldap_request->callback.
1b33e848e84e6f74aa0e3339c32fa96bc15102a2Timo Sirainen verify_plain(PASSDB_RESULT_INTERNAL_FAILURE,
1b33e848e84e6f74aa0e3339c32fa96bc15102a2Timo Sirainen auth_request);
1b33e848e84e6f74aa0e3339c32fa96bc15102a2Timo Sirainen return;
1b33e848e84e6f74aa0e3339c32fa96bc15102a2Timo Sirainen }
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen hash_insert(conn->requests, POINTER_CAST(msgid), ldap_request);
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen auth_request_log_debug(auth_request, "ldap", "bind: dn=%s",
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen ldap_request->base);
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen } else {
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen db_ldap_add_delayed_request(conn, ldap_request);
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen }
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen /* Bind started */
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen auth_request_ref(auth_request);
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen}
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainenstatic void
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainenhandle_request_authbind(struct ldap_connection *conn,
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen struct ldap_request *ldap_request, LDAPMessage *res)
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen{
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen struct passdb_ldap_request *passdb_ldap_request =
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen (struct passdb_ldap_request *)ldap_request;
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen struct auth_request *auth_request = ldap_request->context;
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen enum passdb_result passdb_result;
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen int ret;
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen passdb_result = PASSDB_RESULT_INTERNAL_FAILURE;
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen if (res != NULL) {
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen ret = ldap_result2error(conn->ld, res, 0);
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen if (ret == LDAP_SUCCESS)
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen passdb_result = PASSDB_RESULT_OK;
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen else if (ret == LDAP_INVALID_CREDENTIALS) {
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen auth_request_log_info(auth_request, "ldap",
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen "invalid credentials");
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen passdb_result = PASSDB_RESULT_PASSWORD_MISMATCH;
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen } else {
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen auth_request_log_error(auth_request, "ldap",
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen "ldap_bind() failed: %s",
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen ldap_err2string(ret));
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen }
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen }
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen if (conn->retrying && res == NULL) {
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen /* reconnected, retry binding */
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen authbind_start(conn, ldap_request);
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen } else {
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen passdb_ldap_request->callback.
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen verify_plain(passdb_result, auth_request);
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen }
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen auth_request_unref(&auth_request);
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen}
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainenstatic void
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainenhandle_request_authbind_search(struct ldap_connection *conn,
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen struct ldap_request *ldap_request,
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen LDAPMessage *res)
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen{
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen struct passdb_ldap_request *passdb_ldap_request =
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen (struct passdb_ldap_request *)ldap_request;
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen struct auth_request *auth_request = ldap_request->context;
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen LDAPMessage *entry;
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen entry = handle_request_get_entry(conn, auth_request,
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen passdb_ldap_request, res);
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen if (entry == NULL)
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen return;
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen ldap_query_save_result(conn, entry, auth_request);
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen /* switch the handler to the authenticated bind handler */
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen ldap_request->base =
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen p_strdup(auth_request->pool, ldap_get_dn(conn->ld, entry));
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen ldap_request->filter = NULL;
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen ldap_request->callback = handle_request_authbind;
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen authbind_start(conn, ldap_request);
1b33e848e84e6f74aa0e3339c32fa96bc15102a2Timo Sirainen auth_request_unref(&auth_request);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen}
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainenstatic void ldap_lookup_pass(struct auth_request *auth_request,
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen struct ldap_request *ldap_request)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen{
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen struct passdb_module *_module = auth_request->passdb->passdb;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen struct ldap_passdb_module *module =
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen (struct ldap_passdb_module *)_module;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen struct ldap_connection *conn = module->conn;
28cb56e6957f06717e876cecb7aabc820fdf632eTimo Sirainen const struct var_expand_table *vars;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen const char **attr_names = (const char **)conn->pass_attr_names;
9e1211fd8b7a12b1a4e4c2b7714164e504f127d0Timo Sirainen string_t *str;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen vars = auth_request_get_var_expand_table(auth_request, ldap_escape);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen str = t_str_new(512);
ebded144e74a668973ec9ba6e7e169d4e6dc766cTimo Sirainen var_expand(str, conn->set.base, vars);
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen ldap_request->base = p_strdup(auth_request->pool, str_c(str));
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen str_truncate(str, 0);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen var_expand(str, conn->set.pass_filter, vars);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen ldap_request->filter = p_strdup(auth_request->pool, str_c(str));
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen auth_request_ref(auth_request);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen ldap_request->callback = handle_request;
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen ldap_request->context = auth_request;
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen ldap_request->attributes = conn->pass_attr_names;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen auth_request_log_debug(auth_request, "ldap", "pass search: "
e9e5e84ffb2ce2e606a24ce6d930580367562ff0Timo Sirainen "base=%s scope=%s filter=%s fields=%s",
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen ldap_request->base, conn->set.scope,
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen ldap_request->filter,
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen t_strarray_join(attr_names, ","));
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen db_ldap_search(conn, ldap_request, conn->set.ldap_scope);
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen}
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainenstatic void
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainenldap_verify_plain_auth_bind_userdn(struct auth_request *auth_request,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen struct ldap_request *ldap_request)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen{
d595049948579def2d82718dbce0a6b49a281402Timo Sirainen struct passdb_module *_module = auth_request->passdb->passdb;
d595049948579def2d82718dbce0a6b49a281402Timo Sirainen struct ldap_passdb_module *module =
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen (struct ldap_passdb_module *)_module;
d595049948579def2d82718dbce0a6b49a281402Timo Sirainen struct ldap_connection *conn = module->conn;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen const struct var_expand_table *vars;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen string_t *dn;
9e1211fd8b7a12b1a4e4c2b7714164e504f127d0Timo Sirainen
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen vars = auth_request_get_var_expand_table(auth_request, ldap_escape);
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen dn = t_str_new(512);
d595049948579def2d82718dbce0a6b49a281402Timo Sirainen var_expand(dn, conn->set.auth_bind_userdn, vars);
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen ldap_request->callback = handle_request_authbind;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen ldap_request->context = auth_request;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen ldap_request->base = p_strdup(auth_request->pool, str_c(dn));
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen authbind_start(conn, ldap_request);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen}
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenstatic void
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenldap_verify_plain_authbind(struct auth_request *auth_request,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen struct ldap_request *ldap_request)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen{
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen struct passdb_module *_module = auth_request->passdb->passdb;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen struct ldap_passdb_module *module =
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen (struct ldap_passdb_module *)_module;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen struct ldap_connection *conn = module->conn;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen const struct var_expand_table *vars;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen string_t *str;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen vars = auth_request_get_var_expand_table(auth_request, ldap_escape);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen str = t_str_new(512);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen var_expand(str, conn->set.base, vars);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen ldap_request->base = p_strdup(auth_request->pool, str_c(str));
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen str_truncate(str, 0);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen var_expand(str, conn->set.pass_filter, vars);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen ldap_request->filter = p_strdup(auth_request->pool, str_c(str));
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen /* we don't need the attributes to perform authentication, but they
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen may contain some extra parameters. if a password is returned,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen it's just ignored. */
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen ldap_request->attributes = conn->pass_attr_names;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen auth_request_ref(auth_request);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen ldap_request->context = auth_request;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen ldap_request->callback = handle_request_authbind_search;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen auth_request_log_debug(auth_request, "ldap",
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen "bind search: base=%s filter=%s",
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen ldap_request->base, ldap_request->filter);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen db_ldap_search(conn, ldap_request, LDAP_SCOPE_SUBTREE);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen}
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenstatic void
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenldap_verify_plain(struct auth_request *request,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen const char *password __attr_unused__,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen verify_plain_callback_t *callback)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen{
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen struct passdb_module *_module = request->passdb->passdb;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen struct ldap_passdb_module *module =
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen (struct ldap_passdb_module *)_module;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen struct ldap_connection *conn = module->conn;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen struct passdb_ldap_request *ldap_request;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen /* reconnect if needed. this is also done by db_ldap_search(), but
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen with auth binds we'll have to do it ourself */
d595049948579def2d82718dbce0a6b49a281402Timo Sirainen if (db_ldap_connect(conn)< 0) {
d595049948579def2d82718dbce0a6b49a281402Timo Sirainen callback(PASSDB_RESULT_INTERNAL_FAILURE, request);
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen return;
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen }
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen
a78d5bd9772681a232de56b3dd6acefee66cc71bTimo Sirainen ldap_request = p_new(request->pool, struct passdb_ldap_request, 1);
d595049948579def2d82718dbce0a6b49a281402Timo Sirainen ldap_request->callback.verify_plain = callback;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (conn->set.auth_bind_userdn != NULL)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen ldap_verify_plain_auth_bind_userdn(request, &ldap_request->request);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen else if (conn->set.auth_bind)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen ldap_verify_plain_authbind(request, &ldap_request->request);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen else
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen ldap_lookup_pass(request, &ldap_request->request);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen}
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenstatic void ldap_lookup_credentials(struct auth_request *request,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen lookup_credentials_callback_t *callback)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen{
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen struct passdb_ldap_request *ldap_request;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen ldap_request = p_new(request->pool, struct passdb_ldap_request, 1);
1b33e848e84e6f74aa0e3339c32fa96bc15102a2Timo Sirainen ldap_request->callback.lookup_credentials = callback;
1b33e848e84e6f74aa0e3339c32fa96bc15102a2Timo Sirainen
1b33e848e84e6f74aa0e3339c32fa96bc15102a2Timo Sirainen ldap_lookup_pass(request, &ldap_request->request);
1b33e848e84e6f74aa0e3339c32fa96bc15102a2Timo Sirainen}
1b33e848e84e6f74aa0e3339c32fa96bc15102a2Timo Sirainen
1b33e848e84e6f74aa0e3339c32fa96bc15102a2Timo Sirainenstatic struct passdb_module *
1b33e848e84e6f74aa0e3339c32fa96bc15102a2Timo Sirainenpassdb_ldap_preinit(struct auth_passdb *auth_passdb, const char *args)
1b33e848e84e6f74aa0e3339c32fa96bc15102a2Timo Sirainen{
1b33e848e84e6f74aa0e3339c32fa96bc15102a2Timo Sirainen struct ldap_passdb_module *module;
1b33e848e84e6f74aa0e3339c32fa96bc15102a2Timo Sirainen struct ldap_connection *conn;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen module = p_new(auth_passdb->auth->pool, struct ldap_passdb_module, 1);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen module->conn = conn = db_ldap_init(args);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen conn->pass_attr_map =
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen hash_create(default_pool, conn->pool, 0, str_hash,
1b33e848e84e6f74aa0e3339c32fa96bc15102a2Timo Sirainen (hash_cmp_callback_t *)strcmp);
1b33e848e84e6f74aa0e3339c32fa96bc15102a2Timo Sirainen
1b33e848e84e6f74aa0e3339c32fa96bc15102a2Timo Sirainen if (conn->set.auth_bind_userdn != NULL)
1b33e848e84e6f74aa0e3339c32fa96bc15102a2Timo Sirainen conn->set.auth_bind = TRUE;
1b33e848e84e6f74aa0e3339c32fa96bc15102a2Timo Sirainen db_ldap_set_attrs(conn, conn->set.pass_attrs, &conn->pass_attr_names,
1b33e848e84e6f74aa0e3339c32fa96bc15102a2Timo Sirainen conn->pass_attr_map, default_attr_map,
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen conn->set.auth_bind ? "password" : NULL);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen module->module.cache_key =
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen auth_cache_parse_key(auth_passdb->auth->pool,
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen conn->set.pass_filter);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen module->module.default_pass_scheme = conn->set.default_pass_scheme;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen return &module->module;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen}
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenstatic void passdb_ldap_init(struct passdb_module *_module,
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen const char *args __attr_unused__)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen{
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen struct ldap_passdb_module *module =
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen (struct ldap_passdb_module *)_module;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen (void)db_ldap_connect(module->conn);
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen if (module->conn->set.auth_bind) {
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen /* Credential lookups can't be done with authentication binds */
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen _module->iface.lookup_credentials = NULL;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen }
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen}
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainenstatic void passdb_ldap_deinit(struct passdb_module *_module)
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen{
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen struct ldap_passdb_module *module =
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen (struct ldap_passdb_module *)_module;
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen db_ldap_unref(&module->conn);
9e1211fd8b7a12b1a4e4c2b7714164e504f127d0Timo Sirainen}
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainenstruct passdb_module_interface passdb_ldap = {
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen "ldap",
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen passdb_ldap_preinit,
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen passdb_ldap_init,
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen passdb_ldap_deinit,
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen ldap_verify_plain,
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen ldap_lookup_credentials,
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen NULL
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen};
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen#endif
1358e2c58ce29231485a5cfa454756d429ad3d2cTimo Sirainen