static int
ldap_connect_next_message(struct ldap_connection *conn,
			  struct ldap_op_queue_entry *req, bool *finished_r)
{
	int ret;

	*finished_r = TRUE;

	switch(conn->state) {
	case LDAP_STATE_DISCONNECT:
		/* if we should not disable SSL, and the URI is not ldaps:// */
		if (!conn->set.start_tls || strstr(conn->set.uri, "ldaps://") == NULL) {
			ret = ldap_start_tls(conn->conn, NULL, NULL, &(req->msgid));
			if (ret != LDAP_SUCCESS) {
				ldap_connection_result_failure(conn, req, ret, t_strdup_printf(
					"ldap_start_tls(uri=%s) failed: %s",
					conn->set.uri, ldap_err2string(ret)));
				return ret;
			}
			conn->state = LDAP_STATE_TLS;
			break;
		} else {
			conn->state = LDAP_STATE_AUTH;
			/* we let it slide intentionally to next case */
		}
	case LDAP_STATE_AUTH:
		ret = ldap_sasl_bind(conn->conn,
			conn->set.bind_dn,
			LDAP_SASL_SIMPLE,
			&(conn->cred),
			NULL,
			NULL,
			&(req->msgid));
		if (ret != LDAP_SUCCESS) {
			ldap_connection_result_failure(conn, req, ret, t_strdup_printf(
				"ldap_sasl_bind(uri=%s, dn=%s) failed: %s",
				conn->set.uri, conn->set.bind_dn, ldap_err2string(ret)));
			return ret;
		}
		break;
	case LDAP_STATE_CONNECT:
		ldap_connection_result_success(conn, req);
		return LDAP_SUCCESS; /* we are done here */
	default:
		i_unreached();
	};

	req->conn = conn;
	*finished_r = FALSE;
	return LDAP_SUCCESS;
}
Exemple #2
0
/*
 * Opes connection to an LDAP server
 * uri must be one URI
 */
static int do_open (LDAP **ld, const char* uri, int defport, ldap_ssl_options_t ssl_on_local)
{

#if defined(LDAP_OPT_NETWORK_TIMEOUT) || defined(HAVE_LDAP_START_TLS)
	struct timeval tv;
#endif
#ifdef HAVE_LDAP_START_TLS
	struct timeval *tvp;
	LDAPMessage *res = NULL;
	int msgid;
#endif
	int rc;

	rc = do_init (ld, uri, defport);

	if (rc != LDAP_SUCCESS)
	{
		DBG("do_open(): do_init failed");
		return rc;
    }

	if( ! *ld)
	{
		DBG("do_open(): internal error - assert (*ld != NULL)");
		return(-2);
	}

#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_PROTOCOL_VERSION)
	ldap_set_option (*ld, LDAP_OPT_PROTOCOL_VERSION, &ldapVersion);
#endif /* LDAP_OPT_PROTOCOL_VERSION */

#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_NETWORK_TIMEOUT)
/*	ldap_set_option (*ld, LDAP_OPT_NETWORK_TIMEOUT, &timeout); */

	rc = ldap_set_option(*ld, LDAP_OPT_NETWORK_TIMEOUT, &timeout);
	if ( rc != LDAP_SUCCESS ) {
		DBG2("Warning: failed to set connection timeout to %d: %s", timeout, ldap_err2string(rc));
	} else
		DBG1("Set connection timeout to %d", timeout);
#endif /* LDAP_OPT_NETWORK_TIMEOUT */

#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_NETWORK_TIMEOUT)
	tv.tv_sec = bind_timelimit;
	tv.tv_usec = 0;
	ldap_set_option (*ld, LDAP_OPT_NETWORK_TIMEOUT, &tv);
#endif /* LDAP_OPT_NETWORK_TIMEOUT */


#if defined(HAVE_LDAP_START_TLS_S) || defined(HAVE_LDAP_START_TLS)
	if (ssl_on_local == SSL_START_TLS)
    {
		int version;

		/* we need V3 at least */
		if (ldap_get_option(*ld, LDAP_OPT_PROTOCOL_VERSION,
							&version) == LDAP_OPT_SUCCESS)
		{
			if (ldapVersion < LDAP_VERSION3)
			{
				ldapVersion = LDAP_VERSION3;
				ldap_set_option (*ld, LDAP_OPT_PROTOCOL_VERSION,
			    			&ldapVersion);
	    	}
		}

		/* set up SSL context */
		if (do_ssl_options (*ld) != LDAP_SUCCESS)
		{
			ldap_unbind (*ld);
			DBG("do_open(): SSL setup failed");
			return LDAP_UNAVAILABLE;
		}

#ifdef HAVE_LDAP_START_TLS

  		DBG("do_open(): do_start_tls");
		rc = ldap_start_tls (*ld, NULL, NULL, &msgid);
		if (rc != LDAP_SUCCESS)
		{
		  DBG1("do_open(): ldap_start_tls failed: %s", ldap_err2string (rc));
		  return rc;
		}

		if (bind_timelimit == LDAP_NO_LIMIT)
		{
			tvp = NULL;
    	}
  		else
    	{
      		tv.tv_sec = bind_timelimit;
      		tv.tv_usec = 0;
      		tvp = &tv;
    	}

		rc = ldap_result (*ld, msgid, 1, tvp, &res);
		if (rc == -1)
		{
#if defined(HAVE_LDAP_GET_OPTION) && defined(LDAP_OPT_ERROR_NUMBER)
			if (ldap_get_option (*ld, LDAP_OPT_ERROR_NUMBER, &rc) != LDAP_SUCCESS)
			{
				rc = LDAP_UNAVAILABLE;
			}
#else
			rc = ld->ld_errno;
#endif /* LDAP_OPT_ERROR_NUMBER */

			DBG1("do_open(): ldap_start_tls failed: %s", ldap_err2string (rc));
			return rc;
		}

		rc = ldap_result2error (*ld, res, 1);
		if (rc != LDAP_SUCCESS)
		{
			DBG1("do_open(): ldap_result2error failed: %s)", ldap_err2string (rc));
			return rc;
		}

		rc = ldap_install_tls (*ld);
#else
		rc = ldap_start_tls_s (*ld, NULL, NULL);
#endif /* HAVE_LDAP_START_TLS */

  		if (rc == LDAP_SUCCESS)
		{
  			DBG("do_open(): TLS startup succeeded");
		}
		else
		{
			ldap_unbind (*ld);
			DBG2("do_open(): TLS startup failed for LDAP server %s: %s",
			     uri, ldap_err2string (rc));
		    return rc;
		}
	}
  	else
#endif /* HAVE_LDAP_START_TLS_S || HAVE_LDAP_START_TLS */

	/*
	 * If SSL is desired, then enable it.
	 */
	if (ssl_on_local == SSL_LDAPS)
    {
#if defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_X_TLS)
		int tls = LDAP_OPT_X_TLS_HARD;
		if (ldap_set_option (*ld, LDAP_OPT_X_TLS, &tls) !=
			LDAP_SUCCESS)
		{
			ldap_unbind (*ld);
			DBG("do_open(): TLS setup failed");
			return LDAP_UNAVAILABLE;
		}

		/* set up SSL context */
		if (do_ssl_options (*ld) != LDAP_SUCCESS)
		{
			ldap_unbind (*ld);
			DBG("do_open(): SSL setup failed");
			return LDAP_UNAVAILABLE;
		}
#endif
    }

	rc = do_bind (*ld, bind_timelimit);
	if (rc != LDAP_SUCCESS)
	{
		DBG2("do_open(): failed to bind to LDAP server %s: %s",
			 uri, ldap_err2string (rc));
		ldap_unbind (*ld);
	}
	return rc;
}