[dovecot-cvs] dovecot/src/auth db-ldap.c, 1.41.2.7, 1.41.2.8 db-ldap.h, 1.20.2.4, 1.20.2.5 passdb-ldap.c, 1.44.2.3, 1.44.2.4 userdb-ldap.c, 1.40, 1.40.2.1
tss at dovecot.org
tss at dovecot.org
Sat Nov 4 15:00:31 UTC 2006
Update of /var/lib/cvs/dovecot/src/auth
In directory talvi:/tmp/cvs-serv21169/src/auth
Modified Files:
Tag: branch_1_0
db-ldap.c db-ldap.h passdb-ldap.c userdb-ldap.c
Log Message:
LDAP code changes: If auth binds are used, bind back to the default dn
before doing a search. Otherwise it could fail if user gave an invalid
password. Initial binding is now also done asynchronously. Reconnecting to
LDAP server wasn't working with auth binds. Use pass_attrs even with
auth_bind=yes since it may contain other non-password fields also. Updated
dovecot-ldap.conf to contain sasl_bind settings and reflect these changes.
Index: db-ldap.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/db-ldap.c,v
retrieving revision 1.41.2.7
retrieving revision 1.41.2.8
diff -u -d -r1.41.2.7 -r1.41.2.8
--- db-ldap.c 22 Sep 2006 13:26:44 -0000 1.41.2.7
+++ db-ldap.c 4 Nov 2006 15:00:28 -0000 1.41.2.8
@@ -52,7 +52,6 @@
DEF(SET_STR, sasl_mech),
DEF(SET_STR, sasl_realm),
DEF(SET_STR, sasl_authz_id),
- DEF(SET_STR, sasl_props),
DEF(SET_STR, deref),
DEF(SET_STR, scope),
DEF(SET_STR, base),
@@ -80,7 +79,6 @@
MEMBER(sasl_mech) NULL,
MEMBER(sasl_realm) NULL,
MEMBER(sasl_authz_id) NULL,
- MEMBER(sasl_props) NULL,
MEMBER(deref) "never",
MEMBER(scope) "subtree",
MEMBER(base) NULL,
@@ -96,6 +94,7 @@
static struct ldap_connection *ldap_connections = NULL;
+static int db_ldap_bind(struct ldap_connection *conn);
static void ldap_conn_close(struct ldap_connection *conn, bool flush_requests);
static int deref2str(const char *str)
@@ -143,8 +142,17 @@
{
int msgid;
- if (!conn->connected) {
- if (!db_ldap_connect(conn)) {
+ if (!conn->connected && !conn->connecting) {
+ if (db_ldap_connect(conn) < 0) {
+ request->callback(conn, request, NULL);
+ return;
+ }
+ }
+
+ if (conn->last_auth_bind) {
+ /* switch back to the default dn before doing the search
+ request. */
+ if (db_ldap_bind(conn) < 0) {
request->callback(conn, request, NULL);
return;
}
@@ -167,6 +175,7 @@
struct hash_table *old_requests;
struct hash_iterate_context *iter;
void *key, *value;
+ bool have_binds = FALSE;
i_assert(conn->connected);
@@ -176,22 +185,45 @@
old_requests = conn->requests;
conn->requests = hash_create(default_pool, conn->pool, 0, NULL, NULL);
+ conn->retrying = TRUE;
+ /* first retry all the search requests */
iter = hash_iterate_init(old_requests);
while (hash_iterate(iter, &key, &value)) {
struct ldap_request *request = value;
- i_assert(conn->connected);
- db_ldap_search(conn, request, conn->set.ldap_scope);
+ if (request->filter == NULL) {
+ /* bind request */
+ have_binds = TRUE;
+ } else {
+ i_assert(conn->connected);
+ db_ldap_search(conn, request, conn->set.ldap_scope);
+ }
}
hash_iterate_deinit(iter);
+
+ if (have_binds && conn->set.auth_bind) {
+ /* next retry all the bind requests. without auth binds the
+ only bind request can be the initial connection binding,
+ which we don't care to retry. */
+ iter = hash_iterate_init(old_requests);
+ while (hash_iterate(iter, &key, &value)) {
+ struct ldap_request *request = value;
+
+ if (request->filter == NULL)
+ request->callback(conn, request, NULL);
+ }
+ hash_iterate_deinit(iter);
+ }
hash_destroy(old_requests);
+
+ conn->retrying = FALSE;
}
static void ldap_conn_reconnect(struct ldap_connection *conn)
{
ldap_conn_close(conn, FALSE);
- if (!db_ldap_connect(conn)) {
+ if (db_ldap_connect(conn) < 0) {
/* failed to reconnect. fail all requests. */
ldap_conn_close(conn, TRUE);
}
@@ -275,12 +307,87 @@
}
#endif
-bool db_ldap_connect(struct ldap_connection *conn)
+static int db_ldap_connect_finish(struct ldap_connection *conn, int ret)
{
- int ret, fd;
+ if (ret == LDAP_SERVER_DOWN) {
+ i_error("LDAP: Can't connect to server: %s",
+ conn->set.uris != NULL ?
+ conn->set.uris : conn->set.hosts);
+ return -1;
+ }
+ if (ret != LDAP_SUCCESS) {
+ i_error("LDAP: binding failed (dn %s): %s",
+ conn->set.dn == NULL ? "(none)" : conn->set.dn,
+ ldap_get_error(conn));
+ return -1;
+ }
+
+ conn->connected = TRUE;
+
+ /* in case there are requests waiting, retry them */
+ ldap_conn_retry_requests(conn);
+ return 0;
+}
+
+static void db_ldap_bind_callback(struct ldap_connection *conn,
+ struct ldap_request *ldap_request,
+ LDAPMessage *res)
+{
+ int ret;
+
+ conn->connecting = FALSE;
+ i_free(ldap_request);
+
+ if (res == NULL) {
+ /* aborted */
+ return;
+ }
+
+ ret = ldap_parse_sasl_bind_result(conn->ld, res, NULL, FALSE);
+ if (ret != LDAP_SUCCESS) {
+ i_error("LDAP: ldap_parse_sasl_bind_result() failed: %s",
+ ldap_err2string(ret));
+ return;
+ }
+
+ ret = ldap_result2error(conn->ld, res, FALSE);
+ (void)db_ldap_connect_finish(conn, ret);
+}
+
+static int db_ldap_bind(struct ldap_connection *conn)
+{
+ struct ldap_request *ldap_request;
+ int msgid;
+
+ conn->connecting = TRUE;
+
+ ldap_request = i_new(struct ldap_request, 1);
+ ldap_request->callback = db_ldap_bind_callback;
+ ldap_request->context = conn;
+
+ msgid = ldap_bind(conn->ld, conn->set.dn, conn->set.
+ dnpass, LDAP_AUTH_SIMPLE);
+ if (msgid == -1) {
+ i_error("ldap_bind(%s) failed: %s",
+ conn->set.dn, ldap_get_error(conn));
+ return -1;
+ }
+ hash_insert(conn->requests, POINTER_CAST(msgid), ldap_request);
+
+ /* we're binding back to the original DN, not doing an
+ authentication bind */
+ conn->last_auth_bind = FALSE;
+ return 0;
+}
+int db_ldap_connect(struct ldap_connection *conn)
+{
+ unsigned int ldap_version;
+ int ret;
+
+ i_assert(!conn->connecting);
if (conn->connected)
- return TRUE;
+ return 0;
if (conn->ld == NULL) {
if (conn->set.uris != NULL) {
@@ -299,19 +406,34 @@
conn->set.hosts);
ret = ldap_set_option(conn->ld, LDAP_OPT_DEREF,
- (void *) &conn->set.ldap_deref);
+ (void *)&conn->set.ldap_deref);
if (ret != LDAP_SUCCESS) {
i_fatal("LDAP: Can't set deref option: %s",
ldap_err2string(ret));
}
+ /* If SASL binds are used, the protocol version needs to be
+ at least 3 */
+ ldap_version = conn->set.sasl_bind &&
+ conn->set.ldap_version < 3 ? 3 :
+ conn->set.ldap_version;
ret = ldap_set_option(conn->ld, LDAP_OPT_PROTOCOL_VERSION,
- (void *) &conn->set.ldap_version);
+ (void *)&ldap_version);
if (ret != LDAP_OPT_SUCCESS) {
i_fatal("LDAP: Can't set protocol version %u: %s",
- conn->set.ldap_version, ldap_err2string(ret));
+ ldap_version, ldap_err2string(ret));
}
+
+ /* get the connection's fd */
+ ret = ldap_get_option(conn->ld, LDAP_OPT_DESC,
+ (void *)&conn->fd);
+ if (ret != LDAP_SUCCESS) {
+ i_fatal("LDAP: Can't get connection fd: %s",
+ ldap_err2string(ret));
+ }
+ net_set_nonblock(conn->fd, TRUE);
}
+ i_assert(conn->fd != -1);
if (conn->set.tls) {
#ifdef LDAP_HAVE_START_TLS_S
@@ -319,11 +441,11 @@
if (ret != LDAP_SUCCESS) {
i_error("LDAP: ldap_start_tls_s() failed: %s",
ldap_err2string(ret));
- return FALSE;
+ return -1;
}
#else
i_error("LDAP: Your LDAP library doesn't support TLS");
- return FALSE;
+ return -1;
#endif
}
@@ -345,38 +467,15 @@
#else
i_fatal("LDAP: sasl_bind=yes but no SASL support compiled in");
#endif
+ if (db_ldap_connect_finish(conn, ret) < 0)
+ return -1;
} else {
- ret = ldap_simple_bind_s(conn->ld, conn->set.dn,
- conn->set.dnpass);
- }
- if (ret == LDAP_SERVER_DOWN) {
- i_error("LDAP: Can't connect to server: %s",
- conn->set.uris != NULL ?
- conn->set.uris : conn->set.hosts);
- return FALSE;
- }
- if (ret != LDAP_SUCCESS) {
- i_error("LDAP: binding failed (dn %s): %s",
- conn->set.dn == NULL ? "(none)" : conn->set.dn,
- ldap_get_error(conn));
- return FALSE;
- }
-
- conn->connected = TRUE;
-
- /* register LDAP input to ioloop */
- ret = ldap_get_option(conn->ld, LDAP_OPT_DESC, (void *) &fd);
- if (ret != LDAP_SUCCESS) {
- i_fatal("LDAP: Can't get connection fd: %s",
- ldap_err2string(ret));
+ if (db_ldap_bind(conn) < 0)
+ return -1;
}
- net_set_nonblock(fd, TRUE);
- conn->io = io_add(fd, IO_READ, ldap_input, conn);
-
- /* in case there are requests waiting, retry them */
- ldap_conn_retry_requests(conn);
- return TRUE;
+ conn->io = io_add(conn->fd, IO_READ, ldap_input, conn);
+ return 0;
}
static void ldap_conn_close(struct ldap_connection *conn, bool flush_requests)
@@ -404,15 +503,17 @@
ldap_unbind(conn->ld);
conn->ld = NULL;
}
+ conn->fd = -1;
}
void db_ldap_set_attrs(struct ldap_connection *conn, const char *attrlist,
char ***attr_names_r, struct hash_table *attr_map,
- const char *const default_attr_map[])
+ const char *const default_attr_map[],
+ const char *skip_attr)
{
const char *const *attr;
char *name, *value, *p;
- unsigned int i, size;
+ unsigned int i, j, size;
if (*attrlist == '\0')
return;
@@ -424,7 +525,7 @@
for (size = 0; attr[size] != NULL; size++) ;
*attr_names_r = p_new(conn->pool, char *, size + 1);
- for (i = 0; i < size; i++) {
+ for (i = j = 0; i < size; i++) {
p = strchr(attr[i], '=');
if (p == NULL) {
name = p_strdup(conn->pool, attr[i]);
@@ -435,9 +536,13 @@
value = p_strdup(conn->pool, p + 1);
}
- (*attr_names_r)[i] = name;
- if (*name != '\0')
+ if (skip_attr != NULL && strcmp(skip_attr, value) == 0)
+ name = "";
+
+ if (*name != '\0') {
hash_insert(attr_map, name, value);
+ (*attr_names_r)[j++] = name;
+ }
if (*default_attr_map != NULL)
default_attr_map++;
@@ -516,6 +621,7 @@
conn->refcount = 1;
conn->requests = hash_create(default_pool, pool, 0, NULL, NULL);
+ conn->fd = -1;
conn->config_path = p_strdup(pool, config_path);
conn->set = default_ldap_settings;
if (!settings_read(config_path, NULL, parse_setting, NULL, conn))
Index: db-ldap.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/db-ldap.h,v
retrieving revision 1.20.2.4
retrieving revision 1.20.2.5
diff -u -d -r1.20.2.4 -r1.20.2.5
--- db-ldap.h 19 Jun 2006 16:10:04 -0000 1.20.2.4
+++ db-ldap.h 4 Nov 2006 15:00:28 -0000 1.20.2.5
@@ -56,6 +56,7 @@
struct ldap_settings set;
LDAP *ld;
+ int fd; /* only set when ld is not NULL */
struct io *io;
struct hash_table *requests;
@@ -63,12 +64,16 @@
struct hash_table *pass_attr_map, *user_attr_map;
unsigned int connected:1;
+ unsigned int connecting:1;
+ unsigned int retrying:1; /* just reconnected, resending requests */
+ unsigned int last_auth_bind:1;
};
struct ldap_request {
db_search_callback_t *callback;
void *context;
+ /* for bind requests, base contains the DN and filter=NULL */
const char *base;
const char *filter;
char **attributes; /* points to pass_attr_names / user_attr_names */
@@ -86,12 +91,13 @@
void db_ldap_set_attrs(struct ldap_connection *conn, const char *attrlist,
char ***attr_names_r, struct hash_table *attr_map,
- const char *const default_attr_map[]);
+ const char *const default_attr_map[],
+ const char *skip_attr);
struct ldap_connection *db_ldap_init(const char *config_path);
void db_ldap_unref(struct ldap_connection **conn);
-bool db_ldap_connect(struct ldap_connection *conn);
+int db_ldap_connect(struct ldap_connection *conn);
const char *ldap_escape(const char *str,
const struct auth_request *auth_request);
Index: passdb-ldap.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/passdb-ldap.c,v
retrieving revision 1.44.2.3
retrieving revision 1.44.2.4
diff -u -d -r1.44.2.3 -r1.44.2.4
--- passdb-ldap.c 2 Nov 2006 21:19:43 -0000 1.44.2.3
+++ passdb-ldap.c 4 Nov 2006 15:00:28 -0000 1.44.2.4
@@ -34,84 +34,108 @@
} callback;
};
+struct ldap_query_save_context {
+ struct ldap_connection *conn;
+ struct auth_request *auth_request;
+ LDAPMessage *entry;
+
+ string_t *debug;
+ unsigned int userdb_fields:1;
+ unsigned int add_userdb_uid:1;
+ unsigned int add_userdb_gid:1;
+};
+
static void
-ldap_query_save_result(struct ldap_connection *conn, LDAPMessage *entry,
- struct auth_request *auth_request)
+ldap_query_save_attr(struct ldap_query_save_context *ctx, const char *attr)
{
- struct auth *auth = auth_request->auth;
- BerElement *ber;
+ struct auth *auth = ctx->auth_request->auth;
const char *name;
- char *attr, **vals;
+ char **vals;
unsigned int i;
- string_t *debug = NULL;
- bool userdb_fields = FALSE;
- bool add_userdb_uid = FALSE, add_userdb_gid = FALSE;
- attr = ldap_first_attribute(conn->ld, entry, &ber);
- while (attr != NULL) {
- name = hash_lookup(conn->pass_attr_map, attr);
- vals = ldap_get_values(conn->ld, entry, attr);
+ name = hash_lookup(ctx->conn->pass_attr_map, attr);
- if (auth->verbose_debug) {
- if (debug == NULL)
- debug = t_str_new(256);
- else
- str_append_c(debug, ' ');
- str_append(debug, attr);
- str_printfa(debug, "(%s)=",
- name != NULL ? name : "?unknown?");
- }
+ if (auth->verbose_debug) {
+ if (ctx->debug == NULL)
+ ctx->debug = t_str_new(256);
+ else
+ str_append_c(ctx->debug, ' ');
+ str_append(ctx->debug, attr);
+ str_printfa(ctx->debug, "(%s)=",
+ name != NULL ? name : "?unknown?");
+ }
- if (strncmp(name, "userdb_", 7) == 0) {
- /* in case we're trying to use prefetch userdb,
- see if we need to add global uid/gid */
- if (!userdb_fields) {
- add_userdb_uid = add_userdb_gid = TRUE;
- userdb_fields = TRUE;
- }
- if (strcmp(name, "userdb_uid") == 0)
- add_userdb_uid = FALSE;
- else if (strcmp(name, "userdb_gid") == 0)
- add_userdb_gid = FALSE;
+ if (name == NULL)
+ return;
+
+ if (strncmp(name, "userdb_", 7) == 0) {
+ /* in case we're trying to use prefetch userdb,
+ see if we need to add global uid/gid */
+ if (!ctx->userdb_fields) {
+ ctx->add_userdb_uid = ctx->add_userdb_gid = TRUE;
+ ctx->userdb_fields = TRUE;
}
+ if (strcmp(name, "userdb_uid") == 0)
+ ctx->add_userdb_uid = FALSE;
+ else if (strcmp(name, "userdb_gid") == 0)
+ ctx->add_userdb_gid = FALSE;
+ }
- if (name != NULL && vals != NULL && *name != '\0') {
- for (i = 0; vals[i] != NULL; i++) {
- if (debug != NULL) {
- if (i != 0)
- str_append_c(debug, '/');
- if (auth->verbose_debug_passwords ||
- strcmp(name, "password") != 0)
- str_append(debug, vals[i]);
- else {
- str_append(debug,
- PASSWORD_HIDDEN_STR);
- }
+ vals = ldap_get_values(ctx->conn->ld, ctx->entry, attr);
+ if (vals != NULL && *name != '\0') {
+ for (i = 0; vals[i] != NULL; i++) {
+ if (ctx->debug != NULL) {
+ if (i != 0)
+ str_append_c(ctx->debug, '/');
+ if (auth->verbose_debug_passwords ||
+ strcmp(name, "password") != 0)
+ str_append(ctx->debug, vals[i]);
+ else {
+ str_append(ctx->debug,
+ PASSWORD_HIDDEN_STR);
}
- auth_request_set_field(auth_request,
- name, vals[i],
- conn->set.default_pass_scheme);
}
+ auth_request_set_field(ctx->auth_request, name, vals[i],
+ ctx->conn->set.default_pass_scheme);
}
+ }
- ldap_value_free(vals);
+ ldap_value_free(vals);
+}
+
+static void
+ldap_query_save_result(struct ldap_connection *conn, LDAPMessage *entry,
+ struct auth_request *auth_request)
+{
+ struct ldap_query_save_context ctx;
+ BerElement *ber;
+ char *attr;
+
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.conn = conn;
+ ctx.auth_request = auth_request;
+ ctx.entry = entry;
+
+ attr = ldap_first_attribute(conn->ld, entry, &ber);
+ while (attr != NULL) {
+ ldap_query_save_attr(&ctx, attr);
ldap_memfree(attr);
attr = ldap_next_attribute(conn->ld, entry, ber);
}
- if (add_userdb_uid && conn->set.uid != (uid_t)-1) {
+ if (ctx.add_userdb_uid && conn->set.uid != (uid_t)-1) {
auth_request_set_field(auth_request, "userdb_uid",
dec2str(conn->set.uid), NULL);
}
- if (add_userdb_gid && conn->set.gid != (gid_t)-1) {
+ if (ctx.add_userdb_gid && conn->set.gid != (gid_t)-1) {
auth_request_set_field(auth_request, "userdb_gid",
dec2str(conn->set.gid), NULL);
}
- if (debug != NULL) {
+ if (ctx.debug != NULL) {
auth_request_log_debug(auth_request, "ldap",
- "%s", str_c(debug));
+ "%s", str_c(ctx.debug));
}
}
@@ -218,13 +242,41 @@
auth_request_unref(&auth_request);
}
+static void authbind_start(struct ldap_connection *conn,
+ struct ldap_request *ldap_request)
+{
+ struct passdb_ldap_request *passdb_ldap_request =
+ (struct passdb_ldap_request *)ldap_request;
+ struct auth_request *auth_request = ldap_request->context;
+ int msgid;
+
+ /* switch back to the default dn before doing the next search request */
+ conn->last_auth_bind = TRUE;
+
+ /* the DN is kept in base variable, a bit ugly.. */
+ msgid = ldap_bind(conn->ld, ldap_request->base,
+ auth_request->mech_password, LDAP_AUTH_SIMPLE);
+ if (msgid == -1) {
+ i_error("ldap_bind(%s) failed: %s",
+ ldap_request->base, ldap_get_error(conn));
+ passdb_ldap_request->callback.
+ verify_plain(PASSDB_RESULT_INTERNAL_FAILURE,
+ auth_request);
+ return;
+ }
+
+ /* Bind started */
+ auth_request_ref(auth_request);
+ hash_insert(conn->requests, POINTER_CAST(msgid), ldap_request);
+}
+
static void
handle_request_authbind(struct ldap_connection *conn,
- struct ldap_request *request, LDAPMessage *res)
+ struct ldap_request *ldap_request, LDAPMessage *res)
{
struct passdb_ldap_request *passdb_ldap_request =
- (struct passdb_ldap_request *)request;
- struct auth_request *auth_request = request->context;
+ (struct passdb_ldap_request *)ldap_request;
+ struct auth_request *auth_request = ldap_request->context;
enum passdb_result passdb_result;
int ret;
@@ -237,37 +289,20 @@
else if (ret == LDAP_INVALID_CREDENTIALS)
passdb_result = PASSDB_RESULT_PASSWORD_MISMATCH;
else {
- auth_request_log_error(request->context, "ldap",
+ auth_request_log_error(auth_request, "ldap",
"ldap_bind() failed: %s",
ldap_err2string(ret));
}
}
- passdb_ldap_request->callback.verify_plain(passdb_result, auth_request);
- auth_request_unref(&auth_request);
-}
-
-static void authbind_start(struct ldap_connection *conn,
- struct ldap_request *ldap_request, const char *dn)
-{
- struct passdb_ldap_request *passdb_ldap_request =
- (struct passdb_ldap_request *)ldap_request;
- struct auth_request *auth_request = ldap_request->context;
- int msgid;
-
- msgid = ldap_bind(conn->ld, dn, auth_request->mech_password,
- LDAP_AUTH_SIMPLE);
- if (msgid == -1) {
- i_error("ldap_bind(%s) failed: %s", dn, ldap_get_error(conn));
+ if (conn->retrying && res == NULL) {
+ /* reconnected, retry binding */
+ authbind_start(conn, ldap_request);
+ } else {
passdb_ldap_request->callback.
- verify_plain(PASSDB_RESULT_INTERNAL_FAILURE,
- auth_request);
- return;
+ verify_plain(passdb_result, auth_request);
}
-
- /* Bind started */
- auth_request_ref(auth_request);
- hash_insert(conn->requests, POINTER_CAST(msgid), ldap_request);
+ auth_request_unref(&auth_request);
}
static void
@@ -285,10 +320,15 @@
if (entry == NULL)
return;
+ ldap_query_save_result(conn, entry, auth_request);
+
/* switch the handler to the authenticated bind handler */
+ ldap_request->base =
+ p_strdup(auth_request->pool, ldap_get_dn(conn->ld, entry));
+ ldap_request->filter = NULL;
ldap_request->callback = handle_request_authbind;
- authbind_start(conn, ldap_request, ldap_get_dn(conn->ld, entry));
+ authbind_start(conn, ldap_request);
auth_request_unref(&auth_request);
}
@@ -345,7 +385,8 @@
ldap_request->callback = handle_request_authbind;
ldap_request->context = auth_request;
- authbind_start(conn, ldap_request, str_c(dn));
+ ldap_request->base = p_strdup(auth_request->pool, str_c(dn));
+ authbind_start(conn, ldap_request);
}
static void
@@ -369,9 +410,10 @@
var_expand(str, conn->set.pass_filter, vars);
ldap_request->filter = p_strdup(auth_request->pool, str_c(str));
- /* we don't want any attributes in our search results;
- we only need the DN. */
- ldap_request->attributes = p_new(auth_request->pool, char *, 1);
+ /* 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. */
+ ldap_request->attributes = conn->pass_attr_names;
auth_request_ref(auth_request);
ldap_request->context = auth_request;
@@ -395,6 +437,15 @@
struct ldap_connection *conn = module->conn;
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 (!conn->connected && !conn->connecting) {
+ if (db_ldap_connect(conn)< 0) {
+ callback(PASSDB_RESULT_INTERNAL_FAILURE, request);
+ return;
+ }
+ }
+
ldap_request = p_new(request->pool, struct passdb_ldap_request, 1);
ldap_request->callback.verify_plain = callback;
@@ -429,8 +480,11 @@
hash_create(default_pool, conn->pool, 0, str_hash,
(hash_cmp_callback_t *)strcmp);
+ if (conn->set.auth_bind_userdn != NULL)
+ conn->set.auth_bind = TRUE;
db_ldap_set_attrs(conn, conn->set.pass_attrs, &conn->pass_attr_names,
- conn->pass_attr_map, default_attr_map);
+ conn->pass_attr_map, default_attr_map,
+ conn->set.auth_bind ? "password" : NULL);
module->module.cache_key =
auth_cache_parse_key(auth_passdb->auth->pool,
conn->set.pass_filter);
Index: userdb-ldap.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/userdb-ldap.c,v
retrieving revision 1.40
retrieving revision 1.40.2.1
diff -u -d -r1.40 -r1.40.2.1
--- userdb-ldap.c 14 Feb 2006 17:43:04 -0000 1.40
+++ userdb-ldap.c 4 Nov 2006 15:00:28 -0000 1.40.2.1
@@ -219,7 +219,7 @@
(hash_cmp_callback_t *)strcmp);
db_ldap_set_attrs(conn, conn->set.user_attrs, &conn->user_attr_names,
- conn->user_attr_map, default_attr_map);
+ conn->user_attr_map, default_attr_map, NULL);
return &module->module;
}
More information about the dovecot-cvs
mailing list