As promised, here's the patch I threw together for the rlm_ldap module to solve the problem of failed auth when the LDAP server disconnects the idle connection.
Basically, I took the ldap_connect code out of the perform_search function into it's own "search_connect" function. Then, if ldap_search_st returns LDAP_SERVER_DOWN, it sets inst->bound to 0, does search_connect to try to reconnect to the server, and tries the ldap_search_st one more time. Again, my understanding of all this stuff is very limited. For all I know I created a vast memory leak that will rot your hard drive and cause your business to go bankrupt. - Dan -- - Dan Perik Computer Services Department Lapilo Center New Tribes Mission - PNG
157a158,160 > /* By Dan Perik */ > static int search_connect( void *instance, int res ); > 313a317 > int search_result = 0; 317,323c321 < DEBUG2("rlm_ldap: attempting LDAP reconnection"); < if (inst->ld){ < DEBUG2("rlm_ldap: closing existing LDAP connection"); < ldap_unbind_s(inst->ld); < } < if ((inst->ld = ldap_connect(instance, inst->login, inst->password, 0, &res)) == NULL) { < radlog(L_ERR, "rlm_ldap: (re)connection attempt failed"); --- > if( !search_connect( inst, res ) ) { 326d323 < inst->bound = 1; 329c326,341 < switch (ldap_search_st(inst->ld, search_basedn, scope, filter, attrs, 0, &(inst->timeout), result)) { --- > /* Do LDAP search */ > search_result = ldap_search_st(inst->ld, search_basedn, scope, filter, attrs, >0, &(inst->timeout), result); > /* If server is down, it may have disconnected */ > if ( search_result == LDAP_SERVER_DOWN ) { > DEBUG("rlm_ldap: ldap server connection down, attempting >reconnection"); > /* So unbind it, and try to reconnect */ > inst->bound = 0; > if( !search_connect( inst, res ) ) { > return (RLM_MODULE_FAIL); > } > > /* Now do our search again, if it fails again, then don't try anymore >*/ > search_result = ldap_search_st(inst->ld, search_basedn, scope, filter, >attrs, 0, &(inst->timeout), result); > } > > switch ( search_result ) { 335c347 < radlog(L_ERR, "rlm_ldap: ldap_search() failed: %s", ldap_err2string(ldap_errno)); --- > radlog(L_ERR, "rlm_ldap: ldap_search() failed: %i, %s", ldap_errno, >ldap_err2string(ldap_errno)); 346a359,377 > } > > /* > * search_connect(). Connect to the LDAP server for searches > * returns true if successful, false if not. > */ > static int search_connect( void *instance, int res ) { > ldap_instance *inst = instance; > DEBUG2("rlm_ldap: attempting LDAP reconnection"); > if (inst->ld){ > DEBUG2("rlm_ldap: closing existing LDAP connection"); > ldap_unbind_s(inst->ld); > } > if ((inst->ld = ldap_connect(instance, inst->login, inst->password, 0, &res)) >== NULL) { > radlog(L_ERR, "rlm_ldap: (re)connection attempt failed"); > return 0; /* false = error */ > } > inst->bound = 1; > return -1; /* true = error */