ldap-connection.c revision 4afd5b65670e52e1d513e707c96d626ab1856e03
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen/* Copyright (c) 2016-2017 Dovecot authors, see the included COPYING file */
cd94aeaa294f7cc507206b4b2075852f00e14d61Timo Sirainenvoid ldap_connection_read_more(struct ldap_connection *conn);
cd94aeaa294f7cc507206b4b2075852f00e14d61Timo Sirainenint ldap_connect_next_message(struct ldap_connection *conn, struct ldap_op_queue_entry *req, bool *finished_r);
cd94aeaa294f7cc507206b4b2075852f00e14d61Timo Sirainenvoid ldap_connection_abort_request(struct ldap_op_queue_entry *req);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenvoid ldap_connection_request_destroy(struct ldap_op_queue_entry **req);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenint ldap_connection_connect(struct ldap_connection *conn);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenvoid ldap_connection_send_next(struct ldap_connection *conn);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenvoid ldap_connection_deinit(struct ldap_connection **_conn)
00fa8dcbc66f56daa737487c9dec7166c37de79eTimo Sirainen unsigned int n = aqueue_count(conn->request_queue);
00fa8dcbc66f56daa737487c9dec7166c37de79eTimo Sirainen for (unsigned int i = 0; i < n; i++) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenint ldap_connection_setup(struct ldap_connection *conn, const char **error_r)
2598b2f36365b52d9754b9348a5be29569293e46Timo Sirainen ret = ldap_initialize(&(conn->conn), conn->set.uri);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen *error_r = t_strdup_printf("ldap_initialize(uri=%s) failed: %s",
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen ldap_set_option(conn->conn, LDAP_OPT_X_TLS, &opt);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen ldap_set_option(conn->conn, LDAP_OPT_X_TLS_REQUIRE_CERT, &opt);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* refuse to connect to SSLv2 as it's completely insecure */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen ldap_set_option(conn->conn, LDAP_OPT_X_TLS_PROTOCOL_MIN, &opt);
4c6ddf2491104f917d00e6900e833e80ea02c7b6Timo Sirainen /* default timeout */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen ldap_set_option(conn->conn, LDAP_OPT_TIMEOUT, &opt);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen ldap_set_option(conn->conn, LDAP_OPT_NETWORK_TIMEOUT, &opt);
00fa8dcbc66f56daa737487c9dec7166c37de79eTimo Sirainen /* timelimit */
00fa8dcbc66f56daa737487c9dec7166c37de79eTimo Sirainen ldap_set_option(conn->conn, LDAP_OPT_TIMELIMIT, &opt);
97db4761382024093f441e4bc78ba8b6a056504dTimo Sirainen ldap_set_option(conn->conn, LDAP_OPT_X_TLS_CACERTFILE, conn->ssl_set.ca_file);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen ldap_set_option(conn->conn, LDAP_OPT_X_TLS_CACERTDIR, conn->ssl_set.ca_dir);
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen ldap_set_option(conn->conn, LDAP_OPT_X_TLS_CERTFILE, conn->ssl_set.cert.cert);
c0a708fa3f7b8f4fbca32052da5faf7a0125189dTimo Sirainen ldap_set_option(conn->conn, LDAP_OPT_X_TLS_KEYFILE, conn->ssl_set.cert.key);
97db4761382024093f441e4bc78ba8b6a056504dTimo Sirainen ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, &opt);
cd94aeaa294f7cc507206b4b2075852f00e14d61Timo Sirainen ldap_set_option(conn->conn, LDAP_OPT_PROTOCOL_VERSION, &opt);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen ldap_set_option(conn->conn, LDAP_OPT_REFERRALS, 0);
bbba7d0fce1b6ce5baa2d7ef946eb1b63e2ab518Timo Sirainen ldap_set_option(conn->conn, LDAP_OPT_X_TLS_NEWCTX, &opt);
c49a19168dab6fda80aee16ad799a8a56d3bc18fTimo Sirainenbool ldap_connection_have_settings(struct ldap_connection *conn,
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen const struct ldap_client_settings *conn_set = &conn->set;
02ccba3d3be96444abd15b5254864c9151bbeb30Timo Sirainen if (null_strcmp(conn_set->bind_dn, set->bind_dn) != 0)
02ccba3d3be96444abd15b5254864c9151bbeb30Timo Sirainen if (null_strcmp(conn_set->password, set->password) != 0)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (conn_set->timeout_secs != set->timeout_secs ||
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen conn_set->max_idle_time_secs != set->max_idle_time_secs ||
02ccba3d3be96444abd15b5254864c9151bbeb30Timo Sirainen /* check SSL settings */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (null_strcmp(conn->ssl_set.min_protocol, set->ssl_set->min_protocol) != 0)
c0a708fa3f7b8f4fbca32052da5faf7a0125189dTimo Sirainen if (null_strcmp(conn->ssl_set.cipher_list, set->ssl_set->cipher_list) != 0)
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen if (null_strcmp(conn->ssl_set.ca_file, set->ssl_set->ca_file) != 0)
ad004e44be109684521494b5af2ad1da39b8bb27Timo Sirainen if (null_strcmp(conn->ssl_set.cert.cert, set->ssl_set->cert.cert) != 0)
97db4761382024093f441e4bc78ba8b6a056504dTimo Sirainen if (null_strcmp(conn->ssl_set.cert.key, set->ssl_set->cert.key) != 0)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenint ldap_connection_init(struct ldap_client *client,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct ldap_connection **conn_r, const char **error_r)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen *error_r = t_strdup_printf("ldap_connection_init(uri=%s) failed: %s", set->uri,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen "uri does not start with ldaps and ssl required without start TLS");
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen pool_t pool = pool_alloconly_create("ldap connection", 1024);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct ldap_connection *conn = p_new(pool, struct ldap_connection, 1);
00fa8dcbc66f56daa737487c9dec7166c37de79eTimo Sirainen /* deep copy relevant strings */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen conn->set.bind_dn = p_strdup(pool, set->bind_dn);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen conn->set.password = p_strdup(pool, set->password);
4c6ddf2491104f917d00e6900e833e80ea02c7b6Timo Sirainen ber_str2bv(conn->set.password, strlen(conn->set.password), 0, &(conn->cred));
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* cannot use these */
2a90d8a14b0e7cc1508814bc87d3dfa598ef46a8Timo Sirainen /* keep in sync with ldap_connection_have_settings() */
c0a708fa3f7b8f4fbca32052da5faf7a0125189dTimo Sirainen conn->ssl_set.min_protocol = p_strdup(pool, set->ssl_set->min_protocol);
c0a708fa3f7b8f4fbca32052da5faf7a0125189dTimo Sirainen conn->ssl_set.cipher_list = p_strdup(pool, set->ssl_set->cipher_list);
caea325346da6fb1cf503b35a619467a997acbfaTimo Sirainen conn->ssl_set.ca_file = p_strdup(pool, set->ssl_set->ca_file);
caea325346da6fb1cf503b35a619467a997acbfaTimo Sirainen conn->ssl_set.cert.cert = p_strdup(pool, set->ssl_set->cert.cert);
caea325346da6fb1cf503b35a619467a997acbfaTimo Sirainen conn->ssl_set.cert.key = p_strdup(pool, set->ssl_set->cert.key);
const char *error;
int ret;
case LDAP_STATE_TLS:
return LDAP_SUCCESS;
if (ret != 0) {
return ret;
} else if (result_err != 0) {
if (ret == 0) {
if (ret != 0) {
return LDAP_INVALID_CREDENTIALS;
return LDAP_UNAVAILABLE;
case LDAP_STATE_AUTH:
return ret;
return result_err;
i_unreached();
i_unreached();
i_unreached();
int ret;
case LDAP_STATE_DISCONNECT:
return ret;
case LDAP_STATE_AUTH:
NULL,
NULL,
return ret;
case LDAP_STATE_CONNECT:
i_unreached();
return LDAP_SUCCESS;
const char *error;
int fd;
bool finished;
static struct ldap_op_queue_entry *
unsigned int *idx_r)
*idx_r = i;
return *reqp;
return NULL;
switch(err) {
case LDAP_SUCCESS:
case LDAP_SERVER_DOWN:
#ifdef LDAP_CONNECT_ERROR
case LDAP_CONNECT_ERROR:
case LDAP_UNAVAILABLE:
case LDAP_OPERATIONS_ERROR:
case LDAP_BUSY:
case LDAP_INVALID_CREDENTIALS: {
case LDAP_SIZELIMIT_EXCEEDED:
case LDAP_TIMELIMIT_EXCEEDED:
case LDAP_NO_SUCH_ATTRIBUTE:
case LDAP_UNDEFINED_TYPE:
case LDAP_INVALID_SYNTAX:
case LDAP_NO_SUCH_OBJECT:
case LDAP_ALIAS_PROBLEM:
case LDAP_INVALID_DN_SYNTAX:
case LDAP_IS_LEAF:
case LDAP_ALIAS_DEREF_PROBLEM:
case LDAP_FILTER_ERROR:
case LDAP_LOCAL_ERROR:
if (finished) {
.tv_sec = 0,
.tv_usec = 0
int ret;
if (ret > 0)
i_unreached();
} else if (ret != 0) {