passdb-ldap.c revision e73fbb6673433e8dd6d67a5873ecec0634734248
/* Copyright (c) 2003-2017 Dovecot authors, see the included COPYING file */
#include "auth-common.h"
#include "passdb.h"
#include "ioloop.h"
#include "array.h"
#include "str.h"
#include "password-scheme.h"
#include "auth-cache.h"
#include "db-ldap.h"
#include <ldap.h>
struct ldap_passdb_module {
struct passdb_module module;
struct ldap_connection *conn;
};
struct passdb_ldap_request {
union {
struct ldap_request ldap;
struct ldap_request_search search;
struct ldap_request_bind bind;
} request;
const char *dn;
union {
} callback;
unsigned int entries;
bool require_password;
};
static void
struct auth_request *auth_request,
struct ldap_request_search *ldap_request,
{
struct db_ldap_result_iterate_context *ldap_iter;
continue;
}
"Multiple values found for '%s', "
}
}
}
static void
struct passdb_ldap_request *ldap_request,
{
enum passdb_result passdb_result;
int ret;
} else if (ldap_request->entries == 0) {
"pass_filter matched multiple objects, aborting");
"No password returned (and no nopassword)");
} else {
/* passdb_password may change on the way,
so we'll need to strdup. */
}
/* auth_request_set_field() sets scheme */
} else {
}
}
}
static void
{
struct passdb_ldap_request *ldap_request =
(struct passdb_ldap_request *)request;
return;
}
if (ldap_request->entries++ == 0) {
/* first entry */
}
}
static void
{
struct passdb_ldap_request *passdb_ldap_request =
(struct passdb_ldap_request *)ldap_request;
enum passdb_result passdb_result;
const char *str;
int ret;
if (ret == LDAP_SUCCESS)
else if (ret == LDAP_INVALID_CREDENTIALS) {
str = "Password mismatch (for LDAP bind)";
")", NULL);
}
"%s", str);
} else if (ret == LDAP_NO_SUCH_OBJECT) {
} else {
"ldap_bind() failed: %s",
}
}
}
struct ldap_request_bind *brequest)
{
struct passdb_ldap_request *passdb_ldap_request =
(struct passdb_ldap_request *)brequest;
/* Assume that empty password fails. This is especially
important with Windows 2003 AD, which always returns success
with empty passwords. */
"Login attempt with empty password");
return;
}
}
enum passdb_result passdb_result)
{
} else {
}
}
static void
struct passdb_ldap_request *request,
{
enum passdb_result passdb_result;
} else {
"pass_filter matched multiple objects, aborting");
}
}
struct ldap_request *ldap_request,
{
struct passdb_ldap_request *passdb_ldap_request =
(struct passdb_ldap_request *)ldap_request;
struct passdb_ldap_request *brequest;
char *dn;
if (passdb_ldap_request->entries++ > 0) {
/* too many replies */
return;
}
/* first entry */
/* save dn */
/* failure */
} else if (auth_request->skip_password_check) {
/* we've already verified that the password matched -
we just wanted to get any extra fields */
} else {
/* create a new bind request */
struct passdb_ldap_request, 1);
}
}
struct passdb_ldap_request *request,
bool require_password)
{
struct ldap_passdb_module *module =
(struct ldap_passdb_module *)_module;
const char *error;
ldap_escape, &error) <= 0) {
return;
}
str_truncate(str, 0);
"Failed to expand pass_filter=%s: %s",
return;
}
"base=%s scope=%s filter=%s fields=%s",
}
struct passdb_ldap_request *request)
{
struct ldap_passdb_module *module =
(struct ldap_passdb_module *)_module;
const char *error;
ldap_escape, &error) <= 0) {
return;
}
str_truncate(str, 0);
"Failed to expand pass_filter=%s: %s",
return;
}
/* we don't need the attributes to perform authentication, but they
may contain some extra parameters. if a password is returned,
it's just ignored. */
"bind search: base=%s filter=%s",
}
static void
struct passdb_ldap_request *request)
{
struct ldap_passdb_module *module =
(struct ldap_passdb_module *)_module;
const char *error;
"Failed to expand auth_bind_userdn=%s: %s",
return;
}
}
static void
const char *password ATTR_UNUSED,
{
struct ldap_passdb_module *module =
(struct ldap_passdb_module *)_module;
struct passdb_ldap_request *ldap_request;
/* reconnect if needed. this is also done by db_ldap_search(), but
with auth binds we'll have to do it ourself */
if (db_ldap_connect(conn)< 0) {
return;
}
else
}
{
struct ldap_passdb_module *module =
(struct ldap_passdb_module *)_module;
struct passdb_ldap_request *ldap_request;
bool require_password;
/* with auth_bind=yes we don't necessarily have a password.
this will fail actual password credentials lookups, but it's fine
}
static struct passdb_module *
{
struct ldap_passdb_module *module;
struct ldap_connection *conn;
}
{
struct ldap_passdb_module *module =
(struct ldap_passdb_module *)_module;
}
{
struct ldap_passdb_module *module =
(struct ldap_passdb_module *)_module;
}
#ifndef PLUGIN_BUILD
struct passdb_module_interface passdb_ldap =
#else
#endif
{
"ldap",
};
#else
struct passdb_module_interface passdb_ldap = {
.name = "ldap"
};
#endif