diff --git a/servers/lloadd/bind.c b/servers/lloadd/bind.c index 2d0e5e7b63..1f699fd2b1 100644 --- a/servers/lloadd/bind.c +++ b/servers/lloadd/bind.c @@ -312,6 +312,7 @@ client_bind( Connection *client, Operation *op ) op->o_client_refcnt++; tavl_delete( &client->c_ops, op, operation_client_cmp ); client->c_state = SLAP_C_BINDING; + client->c_type = SLAP_C_OPEN; client_reset( client ); CONNECTION_UNLOCK_INCREF(client); diff --git a/servers/lloadd/config.c b/servers/lloadd/config.c index a11d758b2f..9189410897 100644 --- a/servers/lloadd/config.c +++ b/servers/lloadd/config.c @@ -118,6 +118,7 @@ ldap_pvt_thread_mutex_t backend_mutex; Backend *current_backend = NULL; struct slap_bindconf bindconf = {}; +struct berval lloadd_identity = BER_BVNULL; enum { CFG_ACL = 1, @@ -621,6 +622,21 @@ config_bindconf( ConfigArgs *c ) #endif } + if ( !BER_BVISNULL( &bindconf.sb_authzId ) ) { + ber_dupbv( &lloadd_identity, &bindconf.sb_authzId ); + } else if ( !BER_BVISNULL( &bindconf.sb_authcId ) ) { + ber_dupbv( &lloadd_identity, &bindconf.sb_authcId ); + } else if ( !BER_BVISNULL( &bindconf.sb_binddn ) ) { + char *ptr; + + lloadd_identity.bv_len = STRLENOF("dn:") + bindconf.sb_binddn.bv_len; + lloadd_identity.bv_val = ch_malloc( lloadd_identity.bv_len + 1 ); + + ptr = lutil_strcopy( lloadd_identity.bv_val, "dn:" ); + ptr = lutil_strncopy( + ptr, bindconf.sb_binddn.bv_val, bindconf.sb_binddn.bv_len ); + *ptr = '\0'; + } return 0; } diff --git a/servers/lloadd/operation.c b/servers/lloadd/operation.c index 939c623b25..441d869518 100644 --- a/servers/lloadd/operation.c +++ b/servers/lloadd/operation.c @@ -685,7 +685,8 @@ request_process( Connection *client, Operation *op ) op->o_client_msgid, op->o_upstream_connid, op->o_upstream_msgid ); assert( rc == LDAP_SUCCESS ); - if ( lload_features & LLOAD_FEATURE_PROXYAUTHZ ) { + if ( (lload_features & LLOAD_FEATURE_PROXYAUTHZ) && + client->c_type != SLAP_C_PRIVILEGED ) { CONNECTION_LOCK_DECREF(client); Debug( LDAP_DEBUG_TRACE, "request_process: " "proxying identity %s to upstream\n", diff --git a/servers/lloadd/slap.h b/servers/lloadd/slap.h index 6d7153a48f..06a7647e1d 100644 --- a/servers/lloadd/slap.h +++ b/servers/lloadd/slap.h @@ -129,6 +129,7 @@ LDAP_SLAPD_V (slap_c_head) clients; LDAP_SLAPD_V (ldap_pvt_thread_mutex_t) backend_mutex; LDAP_SLAPD_V (Backend *) current_backend; LDAP_SLAPD_V (struct slap_bindconf) bindconf; +LDAP_SLAPD_V (struct berval) lloadd_identity; LDAP_SLAPD_V (int) slapMode; #define SLAP_UNDEFINED_MODE 0x0000 @@ -281,6 +282,7 @@ enum sc_state { enum sc_type { SLAP_C_OPEN = 0, /* regular connection */ SLAP_C_BIND, /* connection used to handle bind client requests if VC not enabled */ + SLAP_C_PRIVILEGED, /* connection can override proxyauthz control */ }; /* * represents a connection from an ldap client/to ldap server diff --git a/servers/lloadd/upstream.c b/servers/lloadd/upstream.c index 9a42d15485..54d6944256 100644 --- a/servers/lloadd/upstream.c +++ b/servers/lloadd/upstream.c @@ -116,9 +116,12 @@ handle_bind_response( Operation *op, BerElement *ber ) case LDAP_SUCCESS: default: { c->c_state = SLAP_C_READY; + c->c_type = SLAP_C_OPEN; if ( result != LDAP_SUCCESS ) { ber_memfree( c->c_auth.bv_val ); BER_BVZERO( &c->c_auth ); + } else if ( !ber_bvstrcasecmp( &c->c_auth, &lloadd_identity ) ) { + c->c_type = SLAP_C_PRIVILEGED; } if ( !BER_BVISNULL( &c->c_sasl_bind_mech ) ) { ber_memfree( c->c_sasl_bind_mech.bv_val ); @@ -215,9 +218,12 @@ handle_vc_bind_response( Operation *op, BerElement *ber ) case LDAP_SUCCESS: default: { c->c_state = SLAP_C_READY; + c->c_type = SLAP_C_OPEN; if ( result != LDAP_SUCCESS ) { ber_memfree( c->c_auth.bv_val ); BER_BVZERO( &c->c_auth ); + } else if ( !ber_bvstrcasecmp( &c->c_auth, &lloadd_identity ) ) { + c->c_type = SLAP_C_PRIVILEGED; } if ( !BER_BVISNULL( &c->c_vc_cookie ) ) { ber_memfree( c->c_vc_cookie.bv_val );