From f239bbd3c65c4b6b424924eba82ed38da50f796c Mon Sep 17 00:00:00 2001 From: Nadezhda Ivanova Date: Thu, 7 Feb 2019 18:36:17 +0200 Subject: [PATCH] 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. --- doc/man/man3/ldap_get_option.3 | 6 ++++++ include/ldap.h | 1 + libraries/libldap/ldap-int.h | 1 + libraries/libldap/options.c | 13 +++++++++++++ libraries/libldap/result.c | 10 +++++++--- 5 files changed, 28 insertions(+), 3 deletions(-) diff --git a/doc/man/man3/ldap_get_option.3 b/doc/man/man3/ldap_get_option.3 index e1ef69754f..a7a2c0777e 100644 --- a/doc/man/man3/ldap_get_option.3 +++ b/doc/man/man3/ldap_get_option.3 @@ -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 diff --git a/include/ldap.h b/include/ldap.h index 9f3351025b..3e37e03397 100644 --- a/include/ldap.h +++ b/include/ldap.h @@ -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 diff --git a/libraries/libldap/ldap-int.h b/libraries/libldap/ldap-int.h index 0037eeb0e4..a311c7adf3 100644 --- a/libraries/libldap/ldap-int.h +++ b/libraries/libldap/ldap-int.h @@ -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)) diff --git a/libraries/libldap/options.c b/libraries/libldap/options.c index 4e157ed988..6039600251 100644 --- a/libraries/libldap/options.c +++ b/libraries/libldap/options.c @@ -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 = diff --git a/libraries/libldap/result.c b/libraries/libldap/result.c index 3a5969be46..b42febaa35 100644 --- a/libraries/libldap/result.c +++ b/libraries/libldap/result.c @@ -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; }