Add LDAP_OPT_KEEPCONN option

This option instructs try_read1msg to not free the connection on read error
or on Notice of disconnections, but leave it to the caller. It is needed,
for example, by back-asyncmeta, who expects to have control on when
its target connections are freed. Must be used with caution.
This commit is contained in:
Nadezhda Ivanova 2019-02-07 18:36:17 +02:00 committed by Quanah Gibson-Mount
parent e9fa4af4d8
commit f239bbd3c6
5 changed files with 28 additions and 3 deletions

View file

@ -426,6 +426,12 @@ and the
.BR port
fields.
This option is OpenLDAP specific.
.TP
.B LDAP_OPT_KEEPCONN
Instructs
.BR ldap_result (3)
to keep the connection open on read error or if Notice of Disconnection is received. In these cases, the connection should be closed by the caller.
This option is OpenLDAP specific.
.SH SASL OPTIONS
The SASL options are OpenLDAP specific.
.TP

View file

@ -138,6 +138,7 @@ LDAP_BEGIN_DECL
#define LDAP_OPT_CONNECT_ASYNC 0x5010 /* create connections asynchronously */
#define LDAP_OPT_CONNECT_CB 0x5011 /* connection callbacks */
#define LDAP_OPT_SESSION_REFCNT 0x5012 /* session reference count */
#define LDAP_OPT_KEEPCONN 0x5013 /* keep the connection on read error or NoD */
/* OpenLDAP TLS options */
#define LDAP_OPT_X_TLS 0x6000

View file

@ -146,6 +146,7 @@ LDAP_BEGIN_DECL
#define LDAP_BOOL_TLS 3
#define LDAP_BOOL_CONNECT_ASYNC 4
#define LDAP_BOOL_SASL_NOCANON 5
#define LDAP_BOOL_KEEPCONN 6
#define LDAP_BOOLEANS unsigned long
#define LDAP_BOOL(n) ((LDAP_BOOLEANS)1 << (n))

View file

@ -379,6 +379,11 @@ ldap_get_option(
rc = LDAP_OPT_SUCCESS;
break;
case LDAP_OPT_KEEPCONN:
* (int *) outvalue = (int) LDAP_BOOL_GET(lo, LDAP_BOOL_KEEPCONN);
rc = LDAP_OPT_SUCCESS;
break;
case LDAP_OPT_X_KEEPALIVE_IDLE:
* (int *) outvalue = lo->ldo_keepalive_idle;
rc = LDAP_OPT_SUCCESS;
@ -494,6 +499,14 @@ ldap_set_option(
rc = LDAP_OPT_SUCCESS;
break;
case LDAP_OPT_KEEPCONN:
if(invalue == LDAP_OPT_OFF) {
LDAP_BOOL_CLR(lo, LDAP_BOOL_KEEPCONN);
} else {
LDAP_BOOL_SET(lo, LDAP_BOOL_KEEPCONN);
}
rc = LDAP_OPT_SUCCESS;
break;
/* options which can withstand invalue == NULL */
case LDAP_OPT_SERVER_CONTROLS: {
LDAPControl *const *controls =

View file

@ -510,7 +510,9 @@ nextresp3:
if ( err == EWOULDBLOCK ) return LDAP_MSG_X_KEEP_LOOKING;
if ( err == EAGAIN ) return LDAP_MSG_X_KEEP_LOOKING;
ld->ld_errno = LDAP_SERVER_DOWN;
--lc->lconn_refcnt;
if ( !LDAP_BOOL_GET( &ld->ld_options, LDAP_BOOL_KEEPCONN )) {
--lc->lconn_refcnt;
}
lc->lconn_status = 0;
return -1;
@ -892,7 +894,8 @@ nextresp2:
* RFC 4511 unsolicited (id == 0) responses
* shouldn't necessarily end the connection
*/
if ( lc != NULL && id != 0 ) {
if ( lc != NULL && id != 0 &&
!LDAP_BOOL_GET( &ld->ld_options, LDAP_BOOL_KEEPCONN )) {
--lc->lconn_refcnt;
lc = NULL;
}
@ -959,7 +962,8 @@ nextresp2:
}
/* get rid of the connection... */
if ( lc != NULL ) {
if ( lc != NULL &&
!LDAP_BOOL_GET( &ld->ld_options, LDAP_BOOL_KEEPCONN )) {
--lc->lconn_refcnt;
}