/* Copyright (c) 2016-2018 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "array.h"
#include "aqueue.h"
#include "ioloop.h"
#include "ldap-private.h"
static
static
int ldap_connect_next_message(struct ldap_connection *conn, struct ldap_op_queue_entry *req, bool *finished_r);
static
static
static
static
{
for (unsigned int i = 0; i < n; i++) {
}
}
static
{
if (ret != LDAP_SUCCESS) {
return -1;
}
} else {
}
#ifdef LDAP_OPT_X_TLS_PROTOCOL_MIN
/* refuse to connect to SSLv2 as it's completely insecure */
#endif
/* default timeout */
/* timelimit */
opt = LDAP_VERSION3;
#ifdef LDAP_OPT_X_TLS_NEWCTX
opt = 0;
#endif
return 0;
}
const struct ldap_client_settings *set)
{
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return TRUE;
/* check SSL settings */
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return TRUE;
}
const struct ldap_client_settings *set,
{
if (set->require_ssl &&
"uri does not start with ldaps and ssl required without start TLS");
return -1;
}
/* deep copy relevant strings */
}
/* cannot use these */
/* keep in sync with ldap_connection_have_settings() */
}
return -1;
}
return 0;
}
{
for (unsigned int i = 0; i < n; i++) {
}
}
static void
struct ldap_op_queue_entry *req,
{
else
}
static
struct ldap_op_queue_entry *req)
{
}
static
{
unsigned int i = 0, n;
return;
}
return;
}
/* get next request */
for(i=0; i < n; i++) {
break;
}
i--;
/* nothing to actually send */
const char *error;
int ret;
/* did not succeed */
}
static
{
}
{
if (req->timeout_secs > 0)
}
static int
struct ldap_op_queue_entry *req,
{
*finished_r = TRUE;
case LDAP_STATE_TLS:
if (msgtype != LDAP_RES_EXTENDED) {
*finished_r = FALSE;
return LDAP_SUCCESS;
}
if (ret != 0) {
"ldap_start_tls(uri=%s) failed: %s",
return ret;
} else if (result_err != 0) {
"ldap_start_tls(uri=%s) failed: %s",
return LDAP_INVALID_CREDENTIALS; /* make sure it disconnects */
}
} else {
/* retoid can be NULL even if ret == 0 */
if (ret == 0) {
if (ret != 0) {
// if this fails we have to abort
"ldap_start_tls(uri=%s) failed: %s",
return LDAP_INVALID_CREDENTIALS;
}
}
if (ret != LDAP_SUCCESS) {
"ldap_start_tls(uri=%s) failed: %s",
return LDAP_UNAVAILABLE;
}
} else {
i_debug("Using TLS connection to remote LDAP server");
}
}
case LDAP_STATE_AUTH:
if (ret != LDAP_SUCCESS) {
"ldap_parse_result() failed for connect: %s",
ldap_err2string(ret)));
return ret;
}
if (result_err != LDAP_SUCCESS) {
"Connect failed: %s", error));
return result_err;
}
if (msgtype != LDAP_RES_BIND) return 0;
if (ret != LDAP_SUCCESS) {
return 1;
}
default:
i_unreached();
}
i_unreached();
}
static
{
/* too bad */
for (unsigned int i = 0; i < n; i++) {
return;
}
}
i_unreached();
}
static
{
for (unsigned int i = 0; i < n; i++) {
}
}
static int
{
int ret;
*finished_r = TRUE;
case LDAP_STATE_DISCONNECT:
/* if we should not disable SSL, and the URI is not ldaps:// */
if (ret != LDAP_SUCCESS) {
"ldap_start_tls(uri=%s) failed: %s",
return ret;
}
break;
}
/* fall through */
case LDAP_STATE_AUTH:
NULL,
NULL,
if (ret != LDAP_SUCCESS) {
"ldap_sasl_bind(uri=%s, dn=%s) failed: %s",
return ret;
}
break;
case LDAP_STATE_CONNECT:
return LDAP_SUCCESS; /* we are done here */
default:
i_unreached();
};
*finished_r = FALSE;
return LDAP_SUCCESS;
}
static
{
const char *error;
int fd;
bool finished;
/* try to reconnect after disconnection */
}
pool_unref(&pool);
return -1;
}
/* start timeout */
if (req->timeout_secs > 0)
return 0;
}
{
for (unsigned int i = 0; i < n; i++) {
}
}
}
}
{
/* it's not connected */
return 0;
}
static struct ldap_op_queue_entry *
unsigned int *idx_r)
{
for (i = 0; i < n; i++) {
*idx_r = i;
return *reqp;
}
}
return NULL;
}
static int
{
unsigned int i = 0;
/* we need to look at who it was for */
switch(err) {
case LDAP_SUCCESS:
break;
case LDAP_SERVER_DOWN:
#ifdef LDAP_CONNECT_ERROR
case LDAP_CONNECT_ERROR:
#endif
case LDAP_UNAVAILABLE:
case LDAP_OPERATIONS_ERROR:
case LDAP_BUSY:
/* requeue */
break;
case LDAP_INVALID_CREDENTIALS: {
/* fail everything */
return 0;
}
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:
break;
default:
/* ignore */
break;
}
if (finished) {
return 1;
}
return 0;
}
static
{
.tv_sec = 0,
.tv_usec = 0
};
int ret;
/* try get a message */
if (ret > 0)
if (ret == -1) {
i_unreached();
if (ret != LDAP_SERVER_DOWN)
else
i_error("Connection lost to LDAP server, reconnecting");
/* kill me */
} else if (ret != 0) {
}
/* reset timeout */
}
{
}
{
return result->error_string;
}