db-ldap.c revision 594d203bdcbd160688bce5d5a6d65783b919ad49
a8d1a344e580f29699aed9b88d87fc3c6f5d113bSimo Sorce/* Copyright (C) 2003-2006 Timo Sirainen */
a8d1a344e580f29699aed9b88d87fc3c6f5d113bSimo Sorce# define LDAP_SASL_QUIET 0 /* Doesn't exist in Solaris LDAP */
65a38b8c9cabde6c46cc0e9868f54cb9bb10afbfFabiano Fidêncio/* Older versions may require calling ldap_result() twice */
197da163943868216f704fb34031e7d5576e8aeeJakub Hrozek/* Solaris LDAP library doesn't have LDAP_OPT_SUCCESS */
4db56d8c90a6467a216590e5ba3bdcd2a2bf1ae9Jakub Hrozek { type, #name, offsetof(struct ldap_settings, name) }
4db56d8c90a6467a216590e5ba3bdcd2a2bf1ae9Jakub Hrozek MEMBER(user_attrs) "uid,homeDirectory,,,uidNumber,gidNumber",
4db56d8c90a6467a216590e5ba3bdcd2a2bf1ae9Jakub Hrozek MEMBER(user_filter) "(&(objectClass=posixAccount)(uid=%u))",
4db56d8c90a6467a216590e5ba3bdcd2a2bf1ae9Jakub Hrozek MEMBER(pass_filter) "(&(objectClass=posixAccount)(uid=%u))",
4db56d8c90a6467a216590e5ba3bdcd2a2bf1ae9Jakub Hrozekstatic struct ldap_connection *ldap_connections = NULL;
4db56d8c90a6467a216590e5ba3bdcd2a2bf1ae9Jakub Hrozekstatic int db_ldap_bind(struct ldap_connection *conn);
4db56d8c90a6467a216590e5ba3bdcd2a2bf1ae9Jakub Hrozekstatic void ldap_conn_close(struct ldap_connection *conn, bool flush_requests);
4db56d8c90a6467a216590e5ba3bdcd2a2bf1ae9Jakub Hrozek i_fatal("LDAP: Unknown deref option '%s'", str);
4db56d8c90a6467a216590e5ba3bdcd2a2bf1ae9Jakub Hrozek i_fatal("LDAP: Unknown scope option '%s'", str);
65a38b8c9cabde6c46cc0e9868f54cb9bb10afbfFabiano Fidêncioconst char *ldap_get_error(struct ldap_connection *conn)
4db56d8c90a6467a216590e5ba3bdcd2a2bf1ae9Jakub Hrozek ret = ldap_get_option(conn->ld, LDAP_OPT_ERROR_NUMBER, (void *) &err);
4db56d8c90a6467a216590e5ba3bdcd2a2bf1ae9Jakub Hrozek return "??";
4db56d8c90a6467a216590e5ba3bdcd2a2bf1ae9Jakub Hrozekvoid db_ldap_add_delayed_request(struct ldap_connection *conn,
4db56d8c90a6467a216590e5ba3bdcd2a2bf1ae9Jakub Hrozekvoid db_ldap_search(struct ldap_connection *conn, struct ldap_request *request,
4db56d8c90a6467a216590e5ba3bdcd2a2bf1ae9Jakub Hrozek /* switch back to the default dn before doing the
4db56d8c90a6467a216590e5ba3bdcd2a2bf1ae9Jakub Hrozek search request. */
4db56d8c90a6467a216590e5ba3bdcd2a2bf1ae9Jakub Hrozek msgid = ldap_search(conn->ld, request->base, scope,
197da163943868216f704fb34031e7d5576e8aeeJakub Hrozek i_error("LDAP: ldap_search() failed (filter %s): %s",
197da163943868216f704fb34031e7d5576e8aeeJakub Hrozek hash_insert(conn->requests, POINTER_CAST(msgid), request);
7171a7584dda534dde5409f3e7f4657e845ece15Fabiano Fidênciostatic void ldap_conn_retry_requests(struct ldap_connection *conn)
a8d1a344e580f29699aed9b88d87fc3c6f5d113bSimo Sorce conn->requests = hash_create(default_pool, conn->pool, 0, NULL, NULL);
4358d76475f0292461a2a479d2149472db103c1dFabiano Fidêncio /* first retry all the search requests */
a8d1a344e580f29699aed9b88d87fc3c6f5d113bSimo Sorce /* bind request */
a8d1a344e580f29699aed9b88d87fc3c6f5d113bSimo Sorce db_ldap_search(conn, request, conn->set.ldap_scope);
a8d1a344e580f29699aed9b88d87fc3c6f5d113bSimo Sorce /* then delayed search requests */
a8d1a344e580f29699aed9b88d87fc3c6f5d113bSimo Sorce while (*p != NULL) {
a8d1a344e580f29699aed9b88d87fc3c6f5d113bSimo Sorce db_ldap_search(conn, request, conn->set.ldap_scope);
a8d1a344e580f29699aed9b88d87fc3c6f5d113bSimo Sorce /* next retry all the bind requests. without auth binds the
a8d1a344e580f29699aed9b88d87fc3c6f5d113bSimo Sorce only bind request can be the initial connection binding,
a8d1a344e580f29699aed9b88d87fc3c6f5d113bSimo Sorce which we don't care to retry. */
a8d1a344e580f29699aed9b88d87fc3c6f5d113bSimo Sorce if (conn->delayed_requests_head != NULL && conn->set.auth_bind) {
a8d1a344e580f29699aed9b88d87fc3c6f5d113bSimo Sorcestatic void ldap_conn_reconnect(struct ldap_connection *conn)
a8d1a344e580f29699aed9b88d87fc3c6f5d113bSimo Sorce /* failed to reconnect. fail all requests. */
a8d1a344e580f29699aed9b88d87fc3c6f5d113bSimo Sorce ret = ldap_result(conn->ld, LDAP_RES_ANY, 1, &timeout, &res);
a8d1a344e580f29699aed9b88d87fc3c6f5d113bSimo Sorce /* try again, there may be another in buffer */
a8d1a344e580f29699aed9b88d87fc3c6f5d113bSimo Sorce request = hash_lookup(conn->requests, POINTER_CAST(msgid));
a8d1a344e580f29699aed9b88d87fc3c6f5d113bSimo Sorce hash_remove(conn->requests, POINTER_CAST(msgid));
a8d1a344e580f29699aed9b88d87fc3c6f5d113bSimo Sorcesasl_interact(LDAP *ld __attr_unused__, unsigned flags __attr_unused__,
a8d1a344e580f29699aed9b88d87fc3c6f5d113bSimo Sorce struct ldap_sasl_bind_context *context = defaults;
a8d1a344e580f29699aed9b88d87fc3c6f5d113bSimo Sorce const char *str;
a8d1a344e580f29699aed9b88d87fc3c6f5d113bSimo Sorce for (in = interact; in->id != SASL_CB_LIST_END; in++) {
return LDAP_SUCCESS;
int ret;
int msgid;
int ret;
unsigned int ldap_version;
int ret;
#ifdef LDAP_HAVE_INITIALIZE
(void *)&ldap_version);
#ifdef LDAP_HAVE_START_TLS_S
#ifdef HAVE_LDAP_SASL
if (flush_requests) {
const char *const default_attr_map[],
const char *skip_attr)
const char *const *attr;
unsigned int i, j, size;
t_push();
for (i = j = 0; i < size; i++) {
if (p == NULL) {
t_pop();
#define IS_LDAP_ESCAPED_CHAR(c) \
if (IS_LDAP_ESCAPED_CHAR(*p))
return str;
if (IS_LDAP_ESCAPED_CHAR(*p))
void *context)
return conn;
return NULL;
return conn;
#ifndef LDAP_HAVE_INITIALIZE
return conn;
struct ldap_connection **p;
if (*p == conn) {