Commit 352dc0f5 authored by Bradley Nicholes's avatar Bradley Nicholes
Browse files

Better detection and clean up of ldap connection that have been

terminated by the ldap server. PR#40878

Submitted by: Rob Baily <rbaily servicebench com>
Reviewed by: bnicholes



git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@472633 13f79535-47bb-0310-9956-ffa450edef68
parent f4a83408
Loading
Loading
Loading
Loading
+48 −35
Changes for modules/ldap/util_ldap.c: 48 added lines, 35 removed lines.
Original line number Diff line number Diff line
@@ -199,18 +199,10 @@ static apr_status_t uldap_connection_cleanup(void *param)
    return APR_SUCCESS;
}


/*
 * Connect to the LDAP server and binds. Does not connect if already
 * connected (i.e. ldc->ldap is non-NULL.) Does not bind if already bound.
 *
 * Returns LDAP_SUCCESS on success; and an error code on failure
 */
static int uldap_connection_open(request_rec *r,
static int uldap_connection_init(request_rec *r,
                                          util_ldap_connection_t *ldc )
{
    int rc = 0;
    int failures = 0;
    int version  = LDAP_VERSION3;
    apr_ldap_err_t *result = NULL;
    struct timeval timeOut = {10,0};    /* 10 second connection timeout */
@@ -218,23 +210,6 @@ static int uldap_connection_open(request_rec *r,
        (util_ldap_state_t *)ap_get_module_config(r->server->module_config,
        &ldap_module);

    /* sanity check for NULL */
    if (!ldc) {
        return -1;
    }

    /* If the connection is already bound, return
    */
    if (ldc->bound)
    {
        ldc->reason = "LDAP: connection open successful (already bound)";
        return LDAP_SUCCESS;
    }

    /* create the ldap session handle
    */
    if (NULL == ldc->ldap)
    {
    /* Since the host will include a port if the default port is not used,
     * always specify the default ports for the port parameter.  This will
     * allow a host string that contains multiple hosts the ability to mix
@@ -272,9 +247,7 @@ static int uldap_connection_open(request_rec *r,
        apr_ldap_set_option(ldc->pool, ldc->ldap, APR_LDAP_OPT_TLS_CERT,
                            ldc->client_certs, &(result));
        if (LDAP_SUCCESS != result->rc) {
                ldap_unbind_s(ldc->ldap);
                ldc->ldap = NULL;
                ldc->bound = 0;
            uldap_connection_unbind( ldc );
            ldc->reason = result->reason;
            return(result->rc);
        }
@@ -285,9 +258,7 @@ static int uldap_connection_open(request_rec *r,
        apr_ldap_set_option(ldc->pool, ldc->ldap,
                            APR_LDAP_OPT_TLS, &ldc->secure, &(result));
        if (LDAP_SUCCESS != result->rc) {
                ldap_unbind_s(ldc->ldap);
                ldc->ldap = NULL;
                ldc->bound = 0;
            uldap_connection_unbind( ldc );
            ldc->reason = result->reason;
            return(result->rc);
        }
@@ -337,7 +308,43 @@ static int uldap_connection_open(request_rec *r,
    }
#endif

    return(rc);
}

/*
 * Connect to the LDAP server and binds. Does not connect if already
 * connected (i.e. ldc->ldap is non-NULL.) Does not bind if already bound.
 *
 * Returns LDAP_SUCCESS on success; and an error code on failure
 */
static int uldap_connection_open(request_rec *r,
                                 util_ldap_connection_t *ldc)
{
    int rc = 0;
    int failures = 0;

    /* sanity check for NULL */
    if (!ldc) {
        return -1;
    }

    /* If the connection is already bound, return
    */
    if (ldc->bound)
    {
        ldc->reason = "LDAP: connection open successful (already bound)";
        return LDAP_SUCCESS;
    }

    /* create the ldap session handle
    */
    if (NULL == ldc->ldap)
    {
       rc = uldap_connection_init( r, ldc );
       if (LDAP_SUCCESS != rc)
       {
           return rc;
       }
    }


@@ -356,6 +363,14 @@ static int uldap_connection_open(request_rec *r,
                                (char *)ldc->bindpw);
        if (LDAP_SERVER_DOWN != rc) {
            break;
        } else if (failures == 5) {
           /* attempt to init the connection once again */
           uldap_connection_unbind( ldc );
           rc = uldap_connection_init( r, ldc );
           if (LDAP_SUCCESS != rc)
           {
               break;
           }
       }
    }

@@ -363,9 +378,7 @@ static int uldap_connection_open(request_rec *r,
    */
    if (LDAP_SUCCESS != rc)
    {
        ldap_unbind_s(ldc->ldap);
        ldc->ldap = NULL;
        ldc->bound = 0;
       uldap_connection_unbind(ldc);
        ldc->reason = "LDAP: ldap_simple_bind_s() failed";
    }
    else {