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 */

Reply via email to