mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
added timeouts and retries to ldap operations
(This used to be commit 4f004eb54d
)
This commit is contained in:
parent
addea9645d
commit
5d41807f4d
@ -11,9 +11,16 @@ typedef struct {
|
||||
char *kdc_server;
|
||||
int ldap_port;
|
||||
char *bind_path;
|
||||
time_t last_attempt;
|
||||
} ADS_STRUCT;
|
||||
|
||||
|
||||
/* time between reconnect attempts */
|
||||
#define ADS_RECONNECT_TIME 5
|
||||
|
||||
/* timeout on searches */
|
||||
#define ADS_SEARCH_TIMEOUT 10
|
||||
|
||||
#define UF_DONT_EXPIRE_PASSWD 0x10000
|
||||
#define UF_MNS_LOGON_ACCOUNT 0x20000
|
||||
#define UF_SMARTCARD_REQUIRED 0x40000
|
||||
|
@ -62,6 +62,8 @@ int ads_connect(ADS_STRUCT *ads)
|
||||
int version = LDAP_VERSION3;
|
||||
int rc;
|
||||
|
||||
ads->last_attempt = time(NULL);
|
||||
|
||||
ads->ld = ldap_open(ads->ldap_server, ads->ldap_port);
|
||||
if (!ads->ld) {
|
||||
return errno;
|
||||
@ -75,6 +77,50 @@ int ads_connect(ADS_STRUCT *ads)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
a wrapper around ldap_search_s that retries depending on the error code
|
||||
this is supposed to catch dropped connections and auto-reconnect
|
||||
*/
|
||||
int ads_search_retry(ADS_STRUCT *ads, const char *bind_path, int scope, const char *exp,
|
||||
const char **attrs, void **res)
|
||||
{
|
||||
struct timeval timeout;
|
||||
int rc = -1, rc2;
|
||||
int count = 3;
|
||||
|
||||
if (!ads->ld &&
|
||||
time(NULL) - ads->last_attempt < ADS_RECONNECT_TIME) {
|
||||
return LDAP_SERVER_DOWN;
|
||||
}
|
||||
|
||||
while (count--) {
|
||||
*res = NULL;
|
||||
timeout.tv_sec = ADS_SEARCH_TIMEOUT;
|
||||
timeout.tv_usec = 0;
|
||||
if (ads->ld) {
|
||||
rc = ldap_search_ext_s(ads->ld, bind_path, scope, exp, attrs, 0, NULL, NULL,
|
||||
&timeout, LDAP_NO_LIMIT, (LDAPMessage **)res);
|
||||
if (rc == 0) return rc;
|
||||
}
|
||||
|
||||
if (*res) ads_msgfree(ads, *res);
|
||||
*res = NULL;
|
||||
DEBUG(1,("Reopening ads connection after error %s\n", ads_errstr(rc)));
|
||||
if (ads->ld) {
|
||||
/* we should unbind here, but that seems to trigger openldap bugs :(
|
||||
ldap_unbind(ads->ld);
|
||||
*/
|
||||
}
|
||||
ads->ld = NULL;
|
||||
rc2 = ads_connect(ads);
|
||||
if (rc2) {
|
||||
DEBUG(1,("ads_search_retry: failed to reconnect (%s)\n", ads_errstr(rc)));
|
||||
return rc2;
|
||||
}
|
||||
}
|
||||
DEBUG(1,("ads reopen failed after error %s\n", ads_errstr(rc)));
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
do a general ADS search
|
||||
@ -83,9 +129,7 @@ int ads_search(ADS_STRUCT *ads, void **res,
|
||||
const char *exp,
|
||||
const char **attrs)
|
||||
{
|
||||
*res = NULL;
|
||||
return ldap_search_s(ads->ld, ads->bind_path,
|
||||
LDAP_SCOPE_SUBTREE, exp, (char **)attrs, 0, (LDAPMessage **)res);
|
||||
return ads_search_retry(ads, ads->bind_path, LDAP_SCOPE_SUBTREE, exp, attrs, res);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -95,9 +139,7 @@ int ads_search_dn(ADS_STRUCT *ads, void **res,
|
||||
const char *dn,
|
||||
const char **attrs)
|
||||
{
|
||||
*res = NULL;
|
||||
return ldap_search_s(ads->ld, dn,
|
||||
LDAP_SCOPE_BASE, "(objectclass=*)", (char **)attrs, 0, (LDAPMessage **)res);
|
||||
return ads_search_retry(ads, dn, LDAP_SCOPE_BASE, "(objectclass=*)", attrs, res);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -535,11 +577,13 @@ BOOL ads_USN(ADS_STRUCT *ads, uint32 *usn)
|
||||
const char *attrs[] = {"highestCommittedUSN", NULL};
|
||||
int rc;
|
||||
void *res;
|
||||
BOOL ret;
|
||||
|
||||
rc = ldap_search_s(ads->ld, "",
|
||||
LDAP_SCOPE_BASE, "(objectclass=*)", attrs, 0, (LDAPMessage **)&res);
|
||||
rc = ads_search_retry(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res);
|
||||
if (rc || ads_count_replies(ads, res) != 1) return False;
|
||||
return ads_pull_uint32(ads, res, "highestCommittedUSN", usn);
|
||||
ret = ads_pull_uint32(ads, res, "highestCommittedUSN", usn);
|
||||
ads_msgfree(ads, res);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user