db-ldap.c revision fc4ff2356fee6389d4cf2b3f12f4098a436f0502
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng/* Copyright (c) 2003-2007 Dovecot authors, see the included COPYING file */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng# define LDAP_SASL_QUIET 0 /* Doesn't exist in Solaris LDAP */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng/* Older versions may require calling ldap_result() twice */
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer/* Solaris LDAP library doesn't have LDAP_OPT_SUCCESS */
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer const char *name, *value, *template, *val_1_arr[2];
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer const char *const *static_attrs;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng unsigned int value_idx;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng const char *passwd;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng const char *realm;
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai#define DEF_STR(name) DEF_STRUCT_STR(name, ldap_settings)
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai#define DEF_INT(name) DEF_STRUCT_INT(name, ldap_settings)
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai#define DEF_BOOL(name) DEF_STRUCT_BOOL(name, ldap_settings)
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavaistatic struct setting_def setting_defs[] = {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng MEMBER(user_attrs) "homeDirectory=home,uidNumber=uid,gidNumber=gid",
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng MEMBER(user_filter) "(&(objectClass=posixAccount)(uid=%u))",
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng MEMBER(pass_attrs) "uid=user,userPassword=password",
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng MEMBER(pass_filter) "(&(objectClass=posixAccount)(uid=%u))",
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic struct ldap_connection *ldap_connections = NULL;
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic int db_ldap_bind(struct ldap_connection *conn);
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic void db_ldap_conn_close(struct ldap_connection *conn);
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic int ldap_get_errno(struct ldap_connection *conn)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ret = ldap_get_option(conn->ld, LDAP_OPT_ERROR_NUMBER, (void *) &err);
da14cebe459d3275048785f25bd869cb09b5307fEric Chengconst char *ldap_get_error(struct ldap_connection *conn)
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic void ldap_conn_reconnect(struct ldap_connection *conn)
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic int ldap_handle_error(struct ldap_connection *conn)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* invalid input */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* connection problems */
1eee170a5f6cf875d905524fea524c7c5c870aa0Erik Nordmarkstatic int db_ldap_request_bind(struct ldap_connection *conn,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng i_assert(request->type == LDAP_REQUEST_TYPE_BIND);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng i_assert(conn->conn_state == LDAP_CONN_STATE_BOUND_AUTH ||
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng conn->conn_state == LDAP_CONN_STATE_BOUND_DEFAULT);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng request->msgid = ldap_bind(conn->ld, brequest->dn,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng auth_request_log_error(request->auth_request, "ldap",
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng "ldap_bind(%s) failed: %s",
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* broken request, remove it */
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic int db_ldap_request_search(struct ldap_connection *conn,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng i_assert(conn->conn_state == LDAP_CONN_STATE_BOUND_DEFAULT);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ldap_search(conn->ld, srequest->base, conn->set.ldap_scope,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng auth_request_log_error(request->auth_request, "ldap",
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng "ldap_search() failed (filter %s): %s",
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* broken request, remove it */
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic bool db_ldap_request_queue_next(struct ldap_connection *conn)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng unsigned int queue_size = queue_count(conn->request_queue);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* no non-pending requests */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (queue_size > DB_LDAP_MAX_PENDING_REQUESTS) {
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy /* wait until server has replied to some requests */
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy /* we can't do binds until all existing requests are finished */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* wait until we're in bound state */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* bind to default dn first */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* we can do anything in this state */
61af1958c03f88647637805ecf6bdb99b9eef36bGarrett D'Amore /* success */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng } else if (ret < 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* disconnected */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* broken request, remove from queue */
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyervoid db_ldap_request(struct ldap_connection *conn,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng queue_count(conn->request_queue) >= DB_LDAP_MAX_QUEUE_SIZE) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* Queue is full already, fail this request */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng auth_request_log_error(request->auth_request, "ldap",
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng "Request queue is full");
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic int db_ldap_connect_finish(struct ldap_connection *conn, int ret)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng conn->conn_state = LDAP_CONN_STATE_BOUND_DEFAULT;
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic void db_ldap_default_bind_finished(struct ldap_connection *conn,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* lost connection, close it */
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic void db_ldap_abort_requests(struct ldap_connection *conn,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng unsigned int max_count,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng while (queue_count(conn->request_queue) > 0 && max_count > 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* timed out, abort */
da14cebe459d3275048785f25bd869cb09b5307fEric Chengdb_ldap_handle_result(struct ldap_connection *conn, LDAPMessage *res)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng struct ldap_request *const *requests, *request = NULL;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng unsigned int i, count;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng requests = count == 0 ? NULL : array_idx(&conn->request_array, 0);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng for (i = 0; i < count; i++) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng request = requests[queue_idx(conn->request_queue, i)];
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng i_error("LDAP: Reply with unknown msgid %d", msgid);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng i_assert(conn->conn_state == LDAP_CONN_STATE_BINDING);
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer if (ret != LDAP_SUCCESS && request->type == LDAP_REQUEST_TYPE_SEARCH) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* handle search failures here */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng auth_request_log_error(request->auth_request, "ldap",
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng "ldap_search(%s) failed: %s",
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (i > 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* see if there are timed out requests */
783f25cedcc2d0e6828b895b5f67e9dabca8cd39Michael Speerstatic void ldap_input(struct ldap_connection *conn)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ret = ldap_result(conn->ld, LDAP_RES_ANY, 1, &timeout, &res);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* try again, there may be another in buffer */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* send more requests */
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou } else if (ldap_get_errno(conn) != LDAP_SERVER_DOWN) {
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou i_error("LDAP: ldap_result() failed: %s", ldap_get_error(conn));
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou } else if (queue_count(conn->request_queue) > 0 ||
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng i_error("LDAP: Connection lost to LDAP server, reconnecting");
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* server probably disconnected an idle connection. don't
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng reconnect until the next request comes. */
da14cebe459d3275048785f25bd869cb09b5307fEric Chengsasl_interact(LDAP *ld ATTR_UNUSED, unsigned flags ATTR_UNUSED,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng struct db_ldap_sasl_bind_context *context = defaults;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng const char *str;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng for (in = interact; in->id != SASL_CB_LIST_END; in++) {
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic int db_ldap_bind(struct ldap_connection *conn)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng i_assert(conn->conn_state != LDAP_CONN_STATE_BINDING);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng msgid = ldap_bind(conn->ld, conn->set.dn, conn->set.dnpass,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (db_ldap_connect_finish(conn, ldap_get_errno(conn)) < 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* lost connection, close it */
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic void db_ldap_get_fd(struct ldap_connection *conn)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* get the connection's fd */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ret = ldap_get_option(conn->ld, LDAP_OPT_DESC, (void *)&conn->fd);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* Solaris LDAP library seems to be broken */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng i_fatal("LDAP: Buggy LDAP library returned wrong fd: %d",
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (conn->conn_state != LDAP_CONN_STATE_DISCONNECTED)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (ldap_initialize(&conn->ld, conn->set.uris) != LDAP_SUCCESS)
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai i_fatal("LDAP: Your LDAP library doesn't support "
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng "'uris' setting, use 'hosts' instead.");
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai conn->ld = ldap_init(conn->set.hosts, LDAP_PORT);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai i_fatal("LDAP: ldap_init() failed with hosts: %s",
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai ret = ldap_set_option(conn->ld, LDAP_OPT_DEREF,
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai i_fatal("LDAP: Can't set deref option: %s",
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai /* If SASL binds are used, the protocol version needs to be
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai ret = ldap_set_option(conn->ld, LDAP_OPT_PROTOCOL_VERSION,
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai i_fatal("LDAP: Can't set protocol version %u: %s",
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai ret = ldap_start_tls_s(conn->ld, NULL, NULL);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai i_error("LDAP: ldap_start_tls_s() failed: %s",
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai i_error("LDAP: Your LDAP library doesn't support TLS");
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* There doesn't seem to be a way to do SASL binding
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng asynchronously.. */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ret = ldap_sasl_interactive_bind_s(conn->ld, NULL,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng i_fatal("LDAP: sasl_bind=yes but no SASL support compiled in");
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng conn->conn_state = LDAP_CONN_STATE_BOUND_DEFAULT;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng conn->io = io_add(conn->fd, IO_READ, ldap_input, conn);
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic void db_ldap_disconnect_timeout(struct ldap_connection *conn)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* no requests left, remove this timeout handler */
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic void db_ldap_conn_close(struct ldap_connection *conn)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng unsigned int i;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng request = requests[queue_idx(conn->request_queue, i)];
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer conn->to = timeout_add(DB_LDAP_REQUEST_DISCONNECT_TIMEOUT_SECS *
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyervoid db_ldap_set_attrs(struct ldap_connection *conn, const char *attrlist,
ae6aa22afeb444ae208c287e7227a4a7c877f17aVenugopal Iyer char ***attr_names_r, struct hash_table *attr_map,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng unsigned int i, j, size;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* @UNSAFE */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng *attr_names_r = p_new(conn->pool, char *, size + 1);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng for (i = j = 0; i < size; i++) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* allow spaces here so "foo=1, bar=2" works */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng else if (p != attr_data) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* =<static key>=<static value> */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng (skip_attr == NULL || strcmp(skip_attr, value) != 0)) {
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai p_strdup(conn->pool, str_c(static_data)));
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavaidb_ldap_value_get_var_expand_table(struct auth_request *auth_request)
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai const struct var_expand_table *auth_table;
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai auth_table = auth_request_get_var_expand_table(auth_request, NULL);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai for (count = 0; auth_table[count].key != '\0'; count++) ;
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai table = t_new(struct var_expand_table, count + 1);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng memcpy(table + 1, auth_table, sizeof(*table) * count);
4eaa471005973e11a6110b69fe990530b3b95a38Rishi Srivatsavai ((c) == '*' || (c) == '(' || (c) == ')' || (c) == '\\')
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng const struct auth_request *auth_request ATTR_UNUSED)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng const char *p;
61af1958c03f88647637805ecf6bdb99b9eef36bGarrett D'Amore if (*p == '\0')
61af1958c03f88647637805ecf6bdb99b9eef36bGarrett D'Amore for (; *p != '\0'; p++) {
61af1958c03f88647637805ecf6bdb99b9eef36bGarrett D'Amoredb_ldap_result_iterate_init(struct ldap_connection *conn, LDAPMessage *entry,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ctx = t_new(struct db_ldap_result_iterate_context, 1);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ctx->static_attrs = t_strsplit(static_data, ",");
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ctx->attr = ldap_first_attribute(conn->ld, entry, &ctx->ber);
fd0939ef389f48c901faf4bf0b60b82d4bc58b64David Edmondsondb_ldap_result_iterate_finish(struct db_ldap_result_iterate_context *ctx)
fd0939ef389f48c901faf4bf0b60b82d4bc58b64David Edmondson if (ctx->debug != NULL && str_len(ctx->debug) > 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng auth_request_log_debug(ctx->auth_request, "ldap",
da14cebe459d3275048785f25bd869cb09b5307fEric Chengdb_ldap_result_change_attr(struct db_ldap_result_iterate_context *ctx)
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy ctx->name = hash_lookup(ctx->attr_map, ctx->attr);
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy str_printfa(ctx->debug, " %s(%s)=", ctx->attr,
2b24ab6b3865caeede9eeb9db6b83e1d89dcd1eaSebastien Roy if (ctx->name == NULL || *ctx->name == '\0') {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng (ctx->template = strchr(ctx->name, '=')) != NULL) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /* we want to use variables */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ctx->name = t_strdup_until(ctx->name, ctx->template);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ctx->var_table = db_ldap_value_get_var_expand_table(
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng ctx->vals = ldap_get_values(ctx->conn->ld, ctx->entry,
da14cebe459d3275048785f25bd869cb09b5307fEric Chengdb_ldap_result_return_value(struct db_ldap_result_iterate_context *ctx)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng var_expand(ctx->var, ctx->template, ctx->var_table);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (ctx->auth_request->auth->verbose_debug_passwords ||
da14cebe459d3275048785f25bd869cb09b5307fEric Chengstatic bool db_ldap_result_int_next(struct db_ldap_result_iterate_context *ctx)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng const char *p;
1eee170a5f6cf875d905524fea524c7c5c870aa0Erik Nordmark /* a new attribute */
1eee170a5f6cf875d905524fea524c7c5c870aa0Erik Nordmark /* continuing existing attribute */
1eee170a5f6cf875d905524fea524c7c5c870aa0Erik Nordmark ctx->attr = ldap_next_attribute(ctx->conn->ld, ctx->entry,
1eee170a5f6cf875d905524fea524c7c5c870aa0Erik Nordmark if (ctx->static_attrs != NULL && *ctx->static_attrs != NULL) {
1eee170a5f6cf875d905524fea524c7c5c870aa0Erik Nordmark ctx->name = t_strdup_until(*ctx->static_attrs, p);
1eee170a5f6cf875d905524fea524c7c5c870aa0Erik Nordmarkbool db_ldap_result_iterate_next(struct db_ldap_result_iterate_context *ctx,
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyerbool db_ldap_result_iterate_next_all(struct db_ldap_result_iterate_context *ctx,
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer const char **name_r,
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer const char *const **values_r)
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer /* we can use only one value with templates */
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyerstatic const char *parse_setting(const char *key, const char *value,
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer return parse_setting_from_defs(conn->pool, setting_defs,
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyerstatic struct ldap_connection *ldap_conn_find(const char *config_path)
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer for (conn = ldap_connections; conn != NULL; conn = conn->next) {
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer if (strcmp(conn->config_path, config_path) == 0)
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyerstruct ldap_connection *db_ldap_init(const char *config_path)
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer /* see if it already exists */
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer i_fatal("LDAP: Configuration file path not given");
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer pool = pool_alloconly_create("ldap_connection", 1024);
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer conn = p_new(pool, struct ldap_connection, 1);
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer conn->conn_state = LDAP_CONN_STATE_DISCONNECTED;
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer conn->config_path = p_strdup(pool, config_path);
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer if (!settings_read(config_path, NULL, parse_setting,
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer if (conn->set.uris == NULL && conn->set.hosts == NULL)
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer i_fatal("LDAP: Dovecot compiled without support for LDAP uris "
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer "(ldap_initialize not found)");
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer conn->set.ldap_deref = deref2str(conn->set.deref);
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer conn->set.ldap_scope = scope2str(conn->set.scope);
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer i_array_init(&conn->request_array, DB_LDAP_MAX_QUEUE_SIZE);
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer conn->request_queue = queue_init(&conn->request_array.arr);
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyervoid db_ldap_unref(struct ldap_connection **_conn)
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer for (p = &ldap_connections; *p != NULL; p = &(*p)->next) {
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyer/* Building a plugin */
0dc2366f7b9f9f36e10909b1e95edbf2a261c2acVenugopal Iyerextern struct passdb_module_interface passdb_ldap;